【问题标题】:Create a GUI with multiple pages (2-3) in tkinter using python 3使用 python 3 在 tkinter 中创建具有多个页面 (2-3) 的 GUI
【发布时间】:2018-07-29 23:37:00
【问题描述】:

我正在开发一个 GUI,它将与控制器对话并指示它更新通过 LAN 电缆连接到同一控制器的模块的固件。我正在使用 python 3 和 tkinter 编写代码和 GUI。该程序使用 Telnet 和 FTP 协议与之对话。我正在做这个项目的工程师要求我添加一个主页,允许我使用按钮导航到不同的页面。我很难找到兼容的示例代码来做到这一点。目前,我的 GUI 只有一个包含所有功能的母版页。 (见下面的代码)任何人都可以在正确的方向激起我吗?不知道如何使用正确的语法来解决这个问题。非常感谢。

旁注: 此代码不包含 Telnet 或 FTP 脚本,仅包含激活它们的 GUI。

主脚本位于最底部。

“类窗口”用于初始化和构建框架/窗口。

import FirmwareUpdate2
import ftpFirmwareDrop
import os
import threading
from tkinter import *
from tkinter import ttk
from tkinter import messagebox

# from FirmwareUpdate2 import Output
# from FirmwareUpdate2 import guiFlag


# self is common practice as an object variable representation when being passed #in a class or function, but in reality we can use any name.
class Window(Frame):  # Frame is an object imported from tkinter, used to define window frame
    fileName='wookie'
    stationNum='nothing'
    flag=False
    stationFlag=False
    flagExit=False
    flagnoAction=True

    var_1=1
    upFiles=[]
    def __init__(self, master=None):
        Frame.__init__(self, master,bd=1,relief=SUNKEN,background="SkyBlue4")
        self.master = master
        self.grid()
        self.init_window()  

    def init_window(self):  # used to define the window within the frame

        self.master.title("FIRM-UP")  # Window title

        self.pack(fill=BOTH, expand=1)  
        addLabel=Label(self,text="IP Address",background="gray75",fg="green",height=1, width=9,borderwidth=3)
        addLabel.place(x=45,y=17)
        self.ipAddress = StringVar(self)
        self.stationss = StringVar(self)
        self.scroll = Scrollbar(self, orient=VERTICAL, borderwidth=2, background="gray78" )
        self.tBox = Text(self, height=22, width=84, borderwidth=2, relief=SUNKEN, background="gray92")
        self.tBox.configure(yscrollcommand=self.scroll.set,wrap=WORD)
        self.scroll.config(command=self.tBox.yview)
        self.scroll.place(in_=self.tBox, relx=1.0, relheight=1.0, bordermode="outside")
        self.tBox.place(x=15, y=240)
        ipBox=Entry(self,textvariable=self.ipAddress, borderwidth=2, relief=SUNKEN, background="gray92")
        ipBox.place(x=15,y=55)
        quitButton = Button( self, text="Quit",height=1, width=8, borderwidth=2, command=self.client_exit,background="gray78") #button function part of tkinter , REVIEW tcl wrapping for FYI of system.
        quitButton.place(x=700, y=650)  # starts at top left corner, starting to end pixel
        updateFirm=Button(self, text="Update",height=1, width=8, borderwidth=2, command=self.enable_update_demon,background="gray78")
        updateFirm.place(x=785, y=650)  # starts at top left corner, starting to end pixel
        putFile = Button(self, text="Drop File",height=1, width=8, borderwidth=2, command=self.enable_dropFile_demon,background="gray78")
        putFile.place(x=278, y=14)  # starts at top left corner, starting to end pixel
        clearScreen = Button(self, text="Clear", height=1, width=8, borderwidth=2, command=self.clearScreen,background="gray78")
        clearScreen.place(x=810, y=200)
        # client_exit defined in script
        comboBox=ttk.Combobox(self,text="Upgrade Files",textvariable=varSymbol,background="gray92")
        comboBox['values']=updateFile
        comboBox.set(updateFile[0])
        comboBox.bind("<<ComboboxSelected>>", self.assignName)
        #comboBox.grid(row=0, column=1,sticky=W)
        comboBox.place(x=225,y=55)
        deviceLabel = Label(self, text="Devices", background="gray75", fg="green", height=1, width=9, borderwidth=3)
        deviceLabel.place(x=503, y=17)
        self.stationBox = ttk.Combobox(self, text="Available Stations", textvariable=self.stationss, background="gray92")
        self.stationBox.bind("<<ComboboxSelected>>", self.assignStation)
        self.stationBox.place(x=455, y=55)
        #self.stationBox.set(updateFile[0])
        updatedLabel = Label(self, text="Updated Devices", background="gray75", fg="green", height=1, width=16, borderwidth=3)
        updatedLabel.place(x=720, y=17)
        self.updatedBox = Text(self, height=6, width=18, borderwidth=2, relief=SUNKEN, background="gray92")
        self.updatedBox.configure(wrap=WORD)
        self.updatedBox.place(x=692, y=55)
        self.updatedBox.insert(END,"No Devices updated")
        self.updatedBox.update()
    def enable_update_demon(self):
        self.flagExit = True
        self.flagnoAction=False
        #quitButton_Lock=threading.Lock()
        self.up_th=threading.Thread(target=self.runUpdate)
        self.up_th.daemon=True
        self.up_th.start()

    def enable_dropFile_demon(self):
        self.flagnoAction = False
        self.dr_th=threading.Thread(target=self.dropFile)
        self.dr_th.daemon = True
        self.dr_th.start()

    def client_exit(self):
        self.destroy()
        Frame.destroy(self)
        if not self.flagnoAction:
            if self.flagExit==False:
                self.dr_th.join(0)
            else:
                self.up_th.join(0)
        sys.exit()

    def getIPaddress(self):

        temp=str(self.ipAddress.get())

        if temp=="" or temp[3]!='.' or temp[7]!='.' or temp[9]!='.' or len(temp)!=10 :
            self.tBox.insert(END, "Please type a valid IP Address")
            self.tBox.update()
            return False
        else:
            return True

    def runUpdate(self):
        tempFlag = self.getIPaddress()
        if not tempFlag:
            pass
        else:
            assert isinstance(END, object)
            #fileName=varSymbol. get()
            self.tBox.config(state=NORMAL)
            self.tBox.insert(END,'\n' + " Starting update script")
            self.tBox.update()

            if not self.flag:
                self.fileName=updateFile[0]
            self.stationBox.set("")
            FirmwareUpdate2.Main(self.fileName,self.tBox,self.ipAddress,self.stationBox,self.updatedBox)

    def dropFile(self):
        tempFlag= self.getIPaddress()

        if not tempFlag:
            pass
        else:
            self.tBox.config(state=NORMAL)
            self.tBox.insert(END, '\n' + " Starting drop file script")
            self.tBox.update()
            if not self.flag: #selecting default file name
                self.fileName = updateFile[0]

            ftpFirmwareDrop.Main(self.fileName,self.tBox,self.ipAddress)# running file drop script

    def assignName(self,event):
        self.fileName=varSymbol.get()
        self.flag=True

    def assignStation(self,event):
        self.stationFlag=True
        #self.updateObject.updateStationFlag()
        #print("Selected!")


    def getIPaddress(self):

        temp=str(self.ipAddress.get())

        if temp=="":
            self.tBox.insert(END, "Please type a valid IP Address \n")
            self.tBox.update()
            return False
        counter=0
        for i in range(1,len(temp)):
            if temp[i]==".":
                if not i==len(temp)-1:
                    if temp[i+1]==".":
                        self.tBox.insert(END, "Please type a valid IP Address \n")
                        self.tBox.update()
                        return False
                counter=counter + 1

            if temp[i]!="." and not temp[i].isdigit():
                self.tBox.insert(END, "Please type a valid IP Address \n")
                self.tBox.update()
                return False

        if not temp[0].isdigit() or not temp[len(temp)-1].isdigit():
            self.tBox.insert(END, "Please type a valid IP Address \n")
            self.tBox.update()
            return False
        if counter!=3:
            self.tBox.insert(END, "Please type a valid IP Address \n")
            self.tBox.update()
            return False

        if len(temp)>15:
            self.tBox.insert(END, "Please type a valid IP Address \n")
            self.tBox.update()
            return False

        else:
            return True

    def clearScreen(self):
        self.tBox.delete("1.0",END)


if __name__== "__main__":


    stationFlag=False
    counter=0
    dirListing=os.listdir('./FirmwareUpdates/')
    updateFile=[]
    updateStation=[]
    # os.chdir('./FirmwareUpdates/')
    for item in dirListing:  #gathering update files in Firmware directory
        if ".zip" in item:
            updateFile.append(item)

    root = Tk()  # Tk is imported from tkinter; creates root window.
    root.geometry("1000x750")
    varSymbol=StringVar(root,value=updateFile)
    app=Window(root)

    root.mainloop()  # initializes and generates window

【问题讨论】:

  • 你见过这个吗? stackoverflow.com/questions/7546050
  • 我有。这使用 tk.Tk 参数。我正在使用 Tk() 创建一个 Frame 对象,它使用不同的语法。所以我一直在寻找一个例子,其中有人使用 Tk() 和一个类来初始化所有小部件和窗口参数。
  • 您对术语的使用很难理解。您不能创建“使用 Tk() 的 Frame 对象”。 Tk() 创建一个根窗口,而不是一个框架。并且无论您使用Tk() 还是tk.Tk() 都与问题无关。如果你喜欢不同的风格,没有什么能阻止你。我向您指出的示例几乎完全符合您的要求:它使用类来创建所有窗口。但是,重要的是不是复制代码,而是复制概念
  • 抱歉,我需要更准确地了解这些条款。你是对的,它是一个根窗口而不是一个框架。只要它与我到目前为止所写的内容兼容,我使用不同的语法就没有问题。我再看看它,并尝试将它集成到现有代码中。

标签: python-3.x user-interface tkinter


【解决方案1】:

我采取了不同的方式。将在我的下一个项目中尝试链接中的方法。在这种方法中,我基本上为每个窗口类定义了根窗口。不知道为什么不需要初始化主脚本上的根窗口(我假设它可能在后台进行并使用了默认值),但它仍然有效。 (Window).deiconify() 和 (Window).destroy() 属性允许我在导航到不同页面时隐藏和显示窗口。这是我的代码:

    import FirmwareUpdate2
    import ftpFirmwareDrop
    import os
    import threading
    from tkinter import *
    from tkinter import ttk
    import time
    from tkinter import messagebox


    # self is common practice as an object variable representation when being passed in a class or function, but in reality we can use any name.
    class Window(Frame):  # Frame is an object imported from tkinter, used to define window frame

        fileName = 'wookie'
        stationNum = 'nothing'
        flag = False
        stationFlag = False
        flagExit = False
        flagnoAction = True
        var_1 = 1
        upFiles = []

        def __init__(self, master=None, *args):
            Frame.__init__(self, master, bd=1, relief=SUNKEN, background="SkyBlue4")
            self.master = master
            self.grid()
            self.init_window()  # init_window is defined in this script.  Not from tkinter.

        def init_window(self):  # used to define the window within the frame

            self.master.title("FIRM-UP")  # Window title
            self.pack(fill=BOTH, expand=1)  # enabling usage (filling) of whole window and expanding window size

            addLabel = Label(self, text="IP Address", background="gray75", fg="green", height=1, width=9, borderwidth=3)
            addLabel.place(x=55, y=17)
            self.ipAddress = StringVar(self)
            self.stationss = StringVar(self)
            self.scroll = Scrollbar(self, orient=VERTICAL, borderwidth=2, background="gray78")
            self.tBox = Text(self, height=22, width=84, borderwidth=2, relief=SUNKEN, background="gray92")
            self.tBox.configure(yscrollcommand=self.scroll.set, wrap=WORD)
            self.scroll.config(command=self.tBox.yview)
            self.scroll.place(in_=self.tBox, relx=1.0, relheight=1.0, bordermode="outside")
            self.tBox.place(x=35, y=240)
            ipBox = Entry(self, textvariable=self.ipAddress, borderwidth=2, relief=SUNKEN, background="gray92")
            ipBox.place(x=15, y=55)
            quitButton = Button(self, text="Quit", height=1, width=8,borderwidth=2, command=self.client_exit,background="gray78")  # button function part of tkinter , REVIEW tcl wrapping for FYI of system.
            quitButton.place(x=720, y=650)  # starts at top left corner, starting to end pixel
            mainButton = Button(self, text="Main Menu", height=1, width=14, borderwidth=2, command=self.mainReturn,background="gray78")  # button function part of tkinter , REVIEW tcl wrapping for FYI of system.
            mainButton.place(x=758, y=200)  # starts at top left corner, starting to end pixel
            updateFirm = Button(self, text="Update", height=1, width=8, borderwidth=2, command=self.enable_update_demon,background="gray78")
            updateFirm.place(x=65, y=105)  # starts at top left corner, starting to end pixel
            # putFile = Button(self, text="Drop File",height=1, width=8, borderwidth=2, command=self.enable_dropFile_demon,background="gray78")
            # putFile.place(x=278, y=14)  # starts at top left corner, starting to end pixel
            clearScreen = Button(self, text="Clear", height=1, width=8, borderwidth=2, command=self.clearScreen,background="gray78")
            clearScreen.place(x=805,y=650)
            # client_exit defined in script
            updateFiles = Label(self, text="Available Files", background="gray75", fg="green", height=1, width=16,borderwidth=3)
            updateFiles.place(x=250, y=17)
            comboBox = ttk.Combobox(self, text="Upgrade Files", textvariable=varSymbol, background="gray92")
            comboBox['values'] = updateFile
            comboBox.set(updateFile[0])
            comboBox.bind("<<ComboboxSelected>>", self.assignName)
            comboBox.place(x=225, y=55)
            deviceLabel = Label(self, text="Devices", background="gray75", fg="green", height=1, width=9, borderwidth=3)
            deviceLabel.place(x=503, y=17)
            self.stationBox = ttk.Combobox(self, text="Available Stations",textvariable=self.stationss,
                                           background="gray92")
            self.stationBox.bind("<<ComboboxSelected>>", self.assignStation)
            self.stationBox.place(x=455, y=55)
            # self.stationBox.set(updateFile[0])
            updatedLabel = Label(self, text="Updated Devices", background="gray75", fg="green", height=1, width=16,borderwidth=3)
            updatedLabel.place(x=720, y=17)
            self.updatedBox = Text(self, height=6, width=18, borderwidth=2, relief=SUNKEN, background="gray92")
            self.updatedBox.configure(wrap=WORD)
            self.updatedBox.place(x=692, y=55)
            self.updatedBox.insert(END, "No Devices updated")
            self.updatedBox.update()

        def enable_update_demon(self):
            self.flagExit = True
            self.flagnoAction = False
            self.up_th = threading.Thread(target=self.runUpdate)
            self.up_th.daemon = True
            self.up_th.start()

        def mainReturn(self):

            self.master.destroy()
            root1.deiconify()

        def client_exit(self):
            self.destroy()
            Frame.destroy(self)
            if not self.flagnoAction:
                if self.flagExit == False:
                    self.dr_th.join(0)
                else:
                    self.up_th.join(0)
            sys.exit()

        def getIPaddress(self):

            temp = str(self.ipAddress.get())

            if temp == "" or temp[3] != '.' or temp[7] != '.' or temp[9] != '.' or len(temp) != 10:
                self.tBox.insert(END, "Please type a valid IP Address")
                self.tBox.update()
                return False
            else:
                return True

        def runUpdate(self):
            tempFlag = self.getIPaddress()
            if not tempFlag:
                pass
            else:
                assert isinstance(END, object)
                # fileName=varSymbol. get()
                self.tBox.config(state=NORMAL)
                self.tBox.insert(END, '\n' + " Starting update script")
                self.tBox.update()

                if not self.flag:
                    self.fileName = updateFile[0]
                self.stationBox.set("")
                FirmwareUpdate2.Main(self.fileName, self.tBox, self.ipAddress, self.stationBox, self.updatedBox)
# running file drop script

        def assignName(self, event):
            self.fileName = varSymbol.get()
            self.flag = True

        def assignStation(self, event):
            self.stationFlag = True
            # self.updateObject.updateStationFlag()
            # print("Selected!")

        def getIPaddress(self):

            temp = str(self.ipAddress.get())

            if temp == "":
                self.tBox.insert(END, "Please type a valid IP Address \n")
                self.tBox.update()
                return False
            counter = 0
            for i in range(1, len(temp)):
                if temp[i] == ".":
                    if not i == len(temp) - 1:
                        if temp[i + 1] == ".":
                            self.tBox.insert(END, "Please type a valid IP Address \n")
                            self.tBox.update()
                            return False
                    counter = counter + 1

                if temp[i] != "." and not temp[i].isdigit():
                    self.tBox.insert(END, "Please type a valid IP Address \n")
                    self.tBox.update()
                    return False

            if not temp[0].isdigit() or not temp[len(temp) - 1].isdigit():
                self.tBox.insert(END, "Please type a valid IP Address \n")
                self.tBox.update()
                return False
            if counter != 3:
                self.tBox.insert(END, "Please type a valid IP Address \n")
                self.tBox.update()
                return False

            if len(temp) > 15:
                self.tBox.insert(END, "Please type a valid IP Address \n")
                self.tBox.update()
                return False
            # if len(temp)==15:
            #     if temp == "" or temp[3] != '.' or temp[7] != '.' or temp[11]!= '.':
            else:
                return True

        def clearScreen(self):
            self.tBox.delete("1.0", END)
#---------------------Window2 Class Starts------------------------------
class Window2(Frame):  # Frame is an object imported from tkinter, used to define window frame

    fileName = 'wookie'
    stationNum = 'nothing'
    flag = False
    stationFlag = False
    flagExit = False
    flagnoAction = True

    # flag2=False
    var_1 = 1
    upFiles = []

    def __init__(self, master=None):
        Frame.__init__(self, master, bd=1, relief=SUNKEN, background="SkyBlue4")
        self.master = master
        self.grid()
        self.init_window()  # init_window is defined in this script.  Not from tkinter.

    def init_window(self):  # used to define the window within the frame

        self.master.title("FIRM-UP")  # Window title
        self.pack(fill=BOTH, expand=1)
        self.ipAddress = StringVar(self)
        self.stationss = StringVar(self)
        self.scroll = Scrollbar(self, orient=VERTICAL, borderwidth=2, background="gray78")
        self.tBox = Text(self, height=24, width=84, borderwidth=2, relief=SUNKEN, background="gray92")
        self.tBox.configure(yscrollcommand=self.scroll.set, wrap=WORD)
        self.scroll.config(command=self.tBox.yview)
        self.scroll.place(in_=self.tBox, relx=1.0, relheight=1.0, bordermode="outside")
        self.tBox.place(x=60, y=200)
        ipBox = Entry(self, textvariable=self.ipAddress, borderwidth=2, relief=SUNKEN, background="gray92")
        ipBox.place(x=370, y=150)
        updateFiles = Label(self, text="Drop Files", background="gray75", fg="green", height=1, width=16,borderwidth=3)
        updateFiles.place(x=250, y=17)
        quitButton = Button(self, text="Quit", height=1, width=8, borderwidth=2, command=self.client_exit,background="gray78")  # button function part of tkinter , REVIEW tcl wrapping for FYI of system.
        quitButton.place(x=750, y=650)  # starts at top left corner, starting to end pixel
        mainButton = Button(self, text="Main Menu", height=1, width=14, borderwidth=2, command=self.mainReturn,background="gray78")  # button function part of tkinter , REVIEW tcl wrapping for FYI of system.
        mainButton.place(x=805, y=145)
        putFile = Button(self, text="Drop File", height=1, width=8, borderwidth=2, command=self.enable_dropFile_demon,background="gray78")
        putFile.place(x=550, y=145)  # starts at top left corner, starting to end pixel
        clearScreen = Button(self, text="Clear", height=1, width=8, borderwidth=2, command=self.clearScreen,background="gray78")
        clearScreen.place(x=830, y=650)
        addLabel = Label(self, text="IP Address", background="gray75", fg="green", height=1, width=9, borderwidth=3)
        addLabel.place(x=420, y=103)

    def enable_dropFile_demon(self):
        self.flagnoAction = False
        self.dr_th = threading.Thread(target=self.dropFile)
        self.dr_th.daemon = True
        self.dr_th.start()

    def getIPaddress(self):

        temp = str(self.ipAddress.get())

        if temp == "":
            self.tBox.insert(END, "Please type a valid IP Address \n")
            self.tBox.update()
            return False
        counter = 0
        for i in range(1, len(temp)):
            if temp[i] == ".":
                if not i == len(temp) - 1:
                    if temp[i + 1] == ".":
                        self.tBox.insert(END, "Please type a valid IP Address \n")
                        self.tBox.update()
                        return False
                counter = counter + 1

            if temp[i] != "." and not temp[i].isdigit():
                self.tBox.insert(END, "Please type a valid IP Address \n")
                self.tBox.update()
                return False

        if not temp[0].isdigit() or not temp[len(temp) - 1].isdigit():
            self.tBox.insert(END, "Please type a valid IP Address \n")
            self.tBox.update()
            return False
        if counter != 3:
            self.tBox.insert(END, "Please type a valid IP Address \n")
            self.tBox.update()
            return False

        if len(temp) > 15:
            self.tBox.insert(END, "Please type a valid IP Address \n")
            self.tBox.update()
            return False
        else:
            return True

    def client_exit(self):
        self.destroy()
        Frame.destroy(self)
        if not self.flagnoAction:
            if self.flagExit == False:
                self.dr_th.join(0)
            else:
                self.up_th.join(0)
        sys.exit()

    def dropFile(self):
        # assert isinstance(END, object)
        tempFlag = self.getIPaddress()

        if not tempFlag:
            pass
        else:
            self.tBox.config(state=NORMAL)
            self.tBox.insert(END, '\n' + " Starting drop file script")
            self.tBox.update()
            if not self.flag:  # selecting default file name
                self.fileName = updateFile[0]

            ftpFirmwareDrop.Main(self.fileName, self.tBox, self.ipAddress)  # running file drop script
    # ---------------------------------------------------------Window2 Class Ends -------------------------------------------------------------

def clearScreen(self):
    self.tBox.delete("1.0", END)

def mainReturn(self):

    self.master.destroy()
    root1.deiconify()
    def startUpdatePage():
    root1.withdraw()
    window = Toplevel(root1)
    window.geometry("1000x750")
    upd = True
    app = Window(window)
    app.mainloop()
    def startFilePage():
    root1.withdraw()
    window = Tk()
    window.geometry("1000x750")
    app = Window2(window)
    app.mainloop()


if __name__ == "__main__":

    stationFlag = False
    counter = 0
    dirListing = os.listdir('./FirmwareUpdates/')
    updateFile = []
    updateStation = []
    for item in dirListing:  # gathering update files in Firmware directory
        if ".zip" in item:
            updateFile.append(item)

    root1 = Tk()  # Tk is imported from tkinter; creates root window.
    root1.geometry("500x450")
    varSymbol = StringVar(root1, value=updateFile)
    root1.configure(background="SkyBlue4")
    root1.title("FirmUp")
    updateButton = Button(root1, text="Update Firmware", height=1, width=16, borderwidth=2, command=startUpdatePage,background="gray78")
    updateButton.place(x=80, y=200)
    quitButton = Button( root1, text="Quit", height=1, width=8, borderwidth=2, command=root1.destroy,background="gray78")
    quitButton.place(x=420, y=410)
    fileButton = Button(root1, text="Add File", height=1, width=16, borderwidth=2, command=startFilePage,background="gray78")
    fileButton.place(x=270, y=200)
    root1.mainloop()  # initializes and generates window`enter code here`

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 2018-09-02
    相关资源
    最近更新 更多