使用Tkinter的Python GUI项目(包括代码)

386 阅读6分钟

一个登录页面

一个简单的登录表格,它接受一个用户名和密码,并使用一个密码和用户名的文件来验证它是否正确。为了使这个程序工作,你应该在同一目录下设置一个名为Accounts.txt 的文件。

密码

from tkinter import *
from tkinter import messagebox

class Window:
    def __init__(self, master):
        self.master = master

        self.Main = Frame(self.master)
        
        self.L1 = Label(self.Main, text = "Welcome to our Login")
        self.L1.grid(row = 0, column = 1, padx = 5, pady = 5, columnspan = 2)
        
        # Username
        self.L2 = Label(self.Main, text = "Username: ")
        self.L2.grid(row = 1, column = 0, padx = 5, pady = 5)

        self.E1 = Entry(self.Main, width = 30)
        self.E1.grid(row = 1, column = 1, padx = 5, pady = 5, columnspan = 3)

        # Password
        self.L3 = Label(self.Main, text = "Password: ")
        self.L3.grid(row = 2, column = 0, padx = 5, pady = 5)

        self.E2 = Entry(self.Main, show = "*", width = 30)
        self.E2.grid(row = 2, column = 1, padx = 5, pady = 5, columnspan = 3)

        # Buttons
        self.B1 = Button(self.Main, text = "Submit", command = self.verify)
        self.B1.grid(row = 3, column = 2, padx = 5, pady = 5, sticky = "e")

        self.B2 = Button(self.Main, text = "Clear", command = self.clear)
        self.B2.grid(row = 3, column = 3, padx = 5, pady = 5)

        self.Main.pack(padx = 5, pady = 5)

    def clear(self):
        self.E1.delete(0, 'end')
        self.E2.delete(0, 'end')

    def verify(self):
        user = self.E1.get()
        password = self.E2.get()

        file = open("Accounts.txt", "r")

        for line in file:
            temp = line.strip("\n").split(",")

            if user == temp[0] and password == temp[1]:
                print("Your Login Credentials have been Verified")
                return 1

        prompt = messagebox.showerror(title = "Error!", message = "Incorrect Login Details")
        return 0


root = Tk()
window = Window(root)
root.mainloop()

用户名和密码样本。

CodersLegacy,12345
John Hubbard,2020
Random,0000
Sarah,9009

注册

表格 一个注册表格,使用包布局管理器将各种小部件放置在一个相当有趣的布局中,接受用户的输入。然后,这些数据可以被保存到MySQL数据库作为永久存储。对于这个程序,你需要安装一个MySQL数据库来使用数据存储功能。

代码

from tkinter import *
import mysql.connector


class Window():
    def __init__(self, master):
        self.master = master

        self.Main = Frame(self.master)


        # ----- Section 1

        self.section1 = Frame(self.Main)

        self.L1 = Label(self.section1, text = "First Name")
        self.L1.pack(padx = 5, pady = 5, side = LEFT)

        self.E1 = Entry(self.section1)
        self.E1.pack(padx = 5, pady = 5, side = LEFT)

        self.L2 = Label(self.section1, text = "Last Name")
        self.L2.pack(padx = 5, pady = 5, side = LEFT)

        self.E2 = Entry(self.section1)
        self.E2.pack(padx = 5, pady = 5, side = LEFT)
        
        self.section1.pack(padx = 5, pady = 5, expand = True, fill = X)

        # ----- Section 1


        # ----- Section 2

        self.section2 = Frame(self.Main)

        self.L3 = Label(self.section2, text = "Address")
        self.L3.pack(padx = 5, pady = 5, side = LEFT)

        self.E3 = Entry(self.section2, width = 30)
        self.E3.pack(padx = 5, pady = 5, side = LEFT, expand = True, fill = X)

        self.L4 = Label(self.section2, text = "Postal Code")
        self.L4.pack(padx = 5, pady = 5, side = LEFT)

        self.E4 = Entry(self.section2, width = 6)
        self.E4.pack(padx = 5, pady = 5, side = LEFT)

        
        self.section2.pack(padx = 5, pady = 5, expand = True, fill = X)

        # ----- Section 2



        # ----- Section 3
        self.section3 = Frame(self.Main)
        ## ---- Section 3 sub-frame 1
        
        self.section3_1 = Frame(self.section3)        

        self.L5 = Label(self.section3_1, text = "Pick your Gender")
        self.L5.pack(padx = 5, pady = 5)

        self.Rvar1 = IntVar()

        self.R1 = Radiobutton(self.section3_1, text = "Male", variable = self.Rvar1, value = 1)
        self.R1.pack(padx = 5, pady = 5)
        self.R2 = Radiobutton(self.section3_1, text = "Female", variable = self.Rvar1, value = 2)
        self.R2.pack(padx = 5, pady = 5)
        self.R3 = Radiobutton(self.section3_1, text = "Other", variable = self.Rvar1, value = 3)
        self.R3.pack(padx = 5, pady = 5)

        self.section3_1.pack(padx = 50, pady = 5, side = LEFT)

        ## ---- Section 3 sub-frame 1


        ## ---- Section 3 sub-frame 2
        
        self.section3_2 = Frame(self.section3)        

        self.L5 = Label(self.section3_2, text = "Pick an Option")
        self.L5.pack(padx = 5, pady = 5)

        self.Cvar1 = IntVar()
        self.Cvar2 = IntVar()
        self.Cvar3 = IntVar()

        self.C1 = Checkbutton(self.section3_2, text = "Option1", variable = self.Cvar1)
        self.C1.pack(padx = 5, pady = 5)
        self.C2 = Checkbutton(self.section3_2, text = "Option2", variable = self.Cvar2)
        self.C2.pack(padx = 5, pady = 5)
        self.C3 = Checkbutton(self.section3_2, text = "Option3", variable = self.Cvar3)
        self.C3.pack(padx = 5, pady = 5)

        self.section3_2.pack(padx = 50, pady = 5, side = RIGHT)
        
        ## ---- Section 3 sub-frame 2
        

        self.section3.pack(padx = 5, pady = 5, expand = True, fill = X)
        # ----- Section 3


        # ----- Section 4

        self.section4 = Frame(self.Main)

        self.L6 = Label(self.section4, text = "About yourself: ")
        self.L6.pack(padx = 5, pady = 5)

        self.T1 = Text(self.section4, height = 5, width = 30)
        self.T1.pack(padx =5, pady = 5, expand = True, fill = X)

        self.section4.pack(padx = 5, pady = 5, expand = True, fill = X)
        

        # ----- Section 4

        self.B0 = Button(self.Main, text = "Connect", command = self.connect)
        self.B0.pack(padx = 5, pady = 5, side = LEFT)

        self.B1 = Button(self.Main, text = "Create Table", command = self.create_table)
        self.B1.pack(padx = 5, pady = 5, side = LEFT)

        self.B2 = Button(self.Main, text = "Submit", command = self.submit)
        self.B2.pack(padx = 5, pady = 5, side = RIGHT)

        self.Main.pack(padx = 5, pady = 5, expand = True, fill = X)


    def connect(self):
        try:
            self.db = mysql.connector.connect(
                        host = "localhost",
                        user = "root",
                        password = "shadow1963",
                        database = "data")

            self.cursor = self.db.cursor()
            print("Connection Succeeded")
        except:
            print("Connection Failed")


    def create_table(self):
        try:
            self.cursor.execute("""CREATE TABLE regis_data
                                (firstname VARCHAR(30),
                                 lastname VARCHAR(30),
                                 address VARCHAR(100),
                                 postal_code INT,
                                 gender INT,
                                 choice INT,
                                 comments TEXT)""")
        except:
            print("Table already created")


    def submit(self):
        sql = """INSERT INTO regis_data (firstname, lastname, address, postal_code, gender, choice, comments)
                    VALUES (%s, %s, %s, %s, %s, %s, %s)"""
        values = (self.E1.get(), self.E2.get(), self.E3.get(), self.E4.get(), str(self.Rvar1.get()),
                  str(self.Cvar1.get()) + str(self.Cvar2.get()) + str(self.Cvar3.get()), self.T1.get("1.0", "end"))

        self.cursor.execute(sql, values)
        self.db.commit()
        


root = Tk()
root.resizable(False, False)
window = Window(root)
root.mainloop()


电子表格程序

这是一个简单的电子表格,它有一些你可能期望在电子表格软件中看到的基本功能。你还可以将电子表格中的所有数据保存到一个文件中,以后再将其加载到电子表格中。

代码

from tkinter import *


class Window:
    def __init__(self, master):
        self.master = master

        self.Main = Frame(self.master)


        # TOP SECTION
        self.top = Frame(self.Main)

        self.title = Label(self.top, text = "Welcome to our SpreadSheet")
        self.title.pack(padx = 5, pady = 5)
    
        self.top.pack(padx = 5, pady = 5)
        # TOP SECTION
        

        # MIDDLE SECTION
        self.middle = Frame(self.Main)

        self.row = 10
        self.col = 12

        self.cells = [[None for i in range(self.col)] for j in range(self.row)]

        for i in range(self.row):
            for j in range(self.col):
                self.cells[i][j] = Entry(self.middle, width = 5)
                self.cells[i][j].grid(row = i, column = j)

        
        self.middle.pack(padx = 5, pady = 5)
        # MIDDLE SECTION


        # BOTTOM SECTION
        self.bottom = Frame(self.Main)

        self.saveButton = Button(self.bottom, text = "Save", command = self.save)
        self.saveButton.pack(padx = 5, pady = 5, side = RIGHT)

        self.loadButton = Button(self.bottom, text = "Load", command = self.load)
        self.loadButton.pack(padx = 5, pady = 5, side = RIGHT)

        self.clearButton = Button(self.bottom, text = "Clear", command = self.clear)
        self.clearButton.pack(padx = 5, pady = 5, side = LEFT)
        
        self.bottom.pack(padx = 5, pady = 5, expand = True, fill = X)
        # BOTTOM SECTION
        
        self.Main.pack(padx = 5, pady = 5, expand = True, fill = X)


    def save(self):
        file = open("data.txt", "w")

        for i in range(self.row):
            for j in range(self.col):
                file.write(self.cells[i][j].get() + ",")
            file.write("\n")

        file.close()

    def load(self):
        file = open("data.txt", "r")

        self.clear()

        for i in range(self.row):
            temp = file.readline()
            temp = temp.split(",")
            for j in range(self.col):
                self.cells[i][j].insert(0, temp[j].strip())
                
    def clear(self):

        for i in range(self.row):
            for j in range(self.col):
                self.cells[i][j].delete(0, 'end')

        
root = Tk()
window = Window(root)
root.mainloop()


记事本应用

一个简单的记事本应用,具有文本编辑器中的基本功能,以及撤销/恢复操作的能力。

代码

from tkinter import *
from collections import deque


class Window:
    def __init__(self, master):
        self.master = master

        self.Main = Frame(self.master)

        self.stack = deque(maxlen = 10)
        self.stackcursor = 0

        self.L1 = Label(self.Main, text = "This is my NotePad")
        self.L1.pack(padx = 5, pady = 5)

        self.T1 = Text(self.Main, width = 80, height = 20)
        self.T1.pack(padx = 5, pady = 5)

        self.menu = Menu(self.Main)
        self.menu.add_command(label = "Print", command = self.print_stack)
        self.menu.add_command(label = "Undo", command = self.undo)
        self.menu.add_command(label = "Redo", command = self.redo)
        self.master.config(menu = self.menu)

        self.B1 = Button(self.Main, text = "Print", width = 8, command = self.display)
        self.B1.pack(padx = 5, pady = 5, side = LEFT)

        self.B2 = Button(self.Main, text = "Clear", width = 8, command = self.clear)
        self.B2.pack(padx = 5, pady = 5, side = LEFT)

        self.B3 = Button(self.Main, text = "Undo", width = 8, command = self.undo)
        self.B3.pack(padx = 5, pady = 5, side = LEFT)

        self.B4 = Button(self.Main, text = "Redo", width = 8, command = self.redo)
        self.B4.pack(padx = 5, pady = 5, side = LEFT)

        self.Main.pack(padx = 5, pady = 5)

    def display(self):
        print(self.T1.get("1.0", "end"))     

    def clear(self):
        self.T1.delete("1.0", "end")

    def stackify(self):
        self.stack.append(self.T1.get("1.0", "end - 1c"))
        if self.stackcursor < 9: self.stackcursor += 1

    def undo(self):
        if self.stackcursor != 0:
            self.clear()
            if self.stackcursor > 0: self.stackcursor -= 1
            self.T1.insert("0.0", self.stack[self.stackcursor])

    def redo(self):
        if len(self.stack) > self.stackcursor + 1:
            self.clear()
            if self.stackcursor < 9: self.stackcursor += 1
            self.T1.insert("0.0", self.stack[self.stackcursor])

    def print_stack(self):
        i = 0
        for stack in self.stack:
            print(str(i) + " " + stack)
            i += 1

                         

root = Tk()
window = Window(root)
root.bind("<Key>", lambda event: window.stackify())
root.mainloop()


语法高亮器+代码编辑器

用Python Tkinter制作的一个比较复杂的图形用户界面项目。我们在这里制作的语法高亮器是相当粗糙的,但它有许多你在今天的简单代码编辑器(如Notepad++)中可以找到的功能。它可以给某些关键词、字符串和重要的单词着色,同时也有一定程度的自动缩进功能。

代码

from tkinter import *
from collections import deque


class Window:
    def __init__(self, master):
        self.master = master
        self.master.option_add("*Font", "Verdana 12")

        self.Main = Frame(self.master)

        self.stack = deque(maxlen = 10)
        self.stackcursor = 0

        self.L1 = Label(self.Main, text = "This is my Code Editor")
        self.L1.pack(padx = 5, pady = 5)


        #---------

        self.T1 = Text(self.Main, width = 90, height = 25)

        self.T1.tag_configure("orange", foreground = "orange", font = "Verdana 12")
        self.T1.tag_configure("blue", foreground = "blue", font = "Verdana 12")
        self.T1.tag_configure("purple", foreground = "purple", font = "Verdana 12")
        self.T1.tag_configure("green", foreground = "green", font = "Verdana 12")
        self.T1.tag_configure("red", foreground = "red", font = "Verdana 12")

        self.tags = ["orange", "blue", "purple", "green", "red"]

        self.wordlist = [ ["class", "def", "for", "if", "else", "elif", "import", "from", "as", "break", "while"],
                          ["int", "string", "float", "bool", "__init__"],
                          ["pygame", "tkinter", "sys", "os", "mysql"],
                          ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] ]

        self.T1.bind("<Return>", lambda event: self.indent(event.widget))
        
        self.T1.pack(padx = 5, pady = 5)

        #---------

        self.menu = Menu(self.Main)
        self.menu.add_command(label = "Print", command = self.print_stack)
        self.menu.add_command(label = "Undo", command = self.undo)
        self.menu.add_command(label = "Redo", command = self.redo)

        self.master.config(menu = self.menu)

        self.B1 = Button(self.Main, text = "Print", width = 8, command = self.display)
        self.B1.pack(padx = 5, pady = 5, side = LEFT)

        self.B2 = Button(self.Main, text = "Clear", width = 8, command = self.clear)
        self.B2.pack(padx = 5, pady = 5, side = LEFT)

        self.B3 = Button(self.Main, text = "Undo", width = 8, command = self.undo)
        self.B3.pack(padx = 5, pady = 5, side = LEFT)

        self.B4 = Button(self.Main, text = "Redo", width = 8, command = self.redo)
        self.B4.pack(padx = 5, pady = 5, side = LEFT)

        self.Main.pack(padx = 5, pady = 5)


    def tagHighlight(self):
        start = "1.0"
        end = "end"
        
        for mylist in self.wordlist:
            num = int(self.wordlist.index(mylist))

            for word in mylist:
                self.T1.mark_set("matchStart", start)
                self.T1.mark_set("matchEnd", start)
                self.T1.mark_set("SearchLimit", end)

                mycount = IntVar()
                
                while True:
                    index= self.T1.search(word,"matchEnd","SearchLimit", count=mycount, regexp = False)

                    if index == "": break
                    if mycount.get() == 0: break

                    self.T1.mark_set("matchStart", index)
                    self.T1.mark_set("matchEnd", "%s+%sc" % (index, mycount.get()))

                    preIndex = "%s-%sc" % (index, 1)
                    postIndex = "%s+%sc" % (index, mycount.get())
                    
                    if self.check(index, preIndex, postIndex):
                        self.T1.tag_add(self.tags[num], "matchStart", "matchEnd")
                        

    def check(self, index, pre, post):
        letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
                   "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

        if self.T1.get(pre) == self.T1.get(index):
            pre = index
        else:
            if self.T1.get(pre) in letters:
                return 0

        if self.T1.get(post) in letters:
            return 0

        return 1


    def scan(self):
        start = "1.0"
        end = "end"
        mycount = IntVar()

        regex_patterns = [r'".*"', r'#.*']

        for pattern in regex_patterns:
            self.T1.mark_set("start", start)
            self.T1.mark_set("end", end)

            num = int(regex_patterns.index(pattern))

            while True:
                index = self.T1.search(pattern, "start", "end", count=mycount, regexp = True)

                if index == "": break

                if (num == 1):
                    self.T1.tag_add(self.tags[4], index, index + " lineend")
                elif (num == 0):
                    self.T1.tag_add(self.tags[3], index, "%s+%sc" % (index, mycount.get()))

                self.T1.mark_set("start", "%s+%sc" % (index, mycount.get()))


    def indent(self, widget):

        index1 = widget.index("insert")
        index2 = "%s-%sc" % (index1, 1)
        prevIndex = widget.get(index2, index1)

        prevIndentLine = widget.index(index1 + "linestart")
        print("prevIndentLine ",prevIndentLine)
        prevIndent = self.getIndex(prevIndentLine)
        print("prevIndent ", prevIndent)


        if prevIndex == ":":
            widget.insert("insert", "\n" + "     ")
            widget.mark_set("insert", "insert + 1 line + 5char")

            while widget.compare(prevIndent, ">", prevIndentLine):
                widget.insert("insert", "     ")
                widget.mark_set("insert", "insert + 5 chars")
                prevIndentLine += "+5c"
            return "break"
        
        elif prevIndent != prevIndentLine:
            widget.insert("insert", "\n")
            widget.mark_set("insert", "insert + 1 line")

            while widget.compare(prevIndent, ">", prevIndentLine):
                widget.insert("insert", "     ")
                widget.mark_set("insert", "insert + 5 chars")
                prevIndentLine += "+5c"
            return "break"


    def getIndex(self, index):
        while True:
            if self.T1.get(index) == " ":
                index = "%s+%sc" % (index, 1)
            else:
                return self.T1.index(index)
           
                   
    def update(self):
        self.stackify()
        self.tagHighlight()
        self.scan()

    def display(self):
        print(self.T1.get("1.0", "end"))     

    def clear(self):
        self.T1.delete("1.0", "end")

    def stackify(self):
        self.stack.append(self.T1.get("1.0", "end - 1c"))
        if self.stackcursor < 9: self.stackcursor += 1

    def undo(self):
        if self.stackcursor != 0:
            self.clear()
            if self.stackcursor > 0: self.stackcursor -= 1
            self.T1.insert("0.0", self.stack[self.stackcursor])

    def redo(self):
        if len(self.stack) > self.stackcursor + 1:
            self.clear()
            if self.stackcursor < 9: self.stackcursor += 1
            self.T1.insert("0.0", self.stack[self.stackcursor])

    def print_stack(self):
        i = 0
        for stack in self.stack:
            print(str(i) + " " + stack)
            i += 1

                     
root = Tk()
window = Window(root)
root.bind("<Key>", lambda event: window.update())
root.mainloop()