0

I'm working on a GUI that will talk to a controller and instruct it to update the Firmware of modules connected via LAN cable to the same controller. I'm using python 3 and tkinter to write the code and GUI. The program uses Telnet and FTP protocol to talk to it. The engineer I'm doing this project for asked that I add a main page that would allow me to navigate to different pages using buttons. I'm having a hard time finding compatible sample codes that do this. Currently, my GUI only had one master page that includes all features. (See code below) Can anyone stir me in the right direction? Not sure how to approach this with the right syntax. Many thanks.

Side notes: This code does not include the Telnet or FTP scripts, just the GUI that activates them.

Main Script is at the very bottom.

"Class Window" is used to initialize and build the frame/window.

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
GabeJC
  • 1
  • 1
  • 3
  • Have you seen this? http://stackoverflow.com/questions/7546050 – Bryan Oakley Jul 25 '18 at 03:43
  • I have. This uses the tk.Tk argument. I'm creating a Frame object using Tk() which uses a different syntax. So I was looking for an example where someone did this using Tk() and a Class to initialize all the widgets and window parameters. – GabeJC Jul 25 '18 at 14:07
  • Your use of terminology is hard to understand. You can't create "a Frame object using Tk()". `Tk()` creates a root window, not a frame. And whether you use `Tk()` or `tk.Tk()` is irrelevant to the problem. If you prefer a different style, there's nothing stopping you. The example I pointed you to does pretty much exactly what you want: it uses a classes to create all of the windows. However, the important thing is to _not_ copy the code, but rather to copy the _concept_. – Bryan Oakley Jul 25 '18 at 15:22
  • Sorry, I need to be more accurate with the terms. You're right, it's a root window and not a Frame. I have no issues using the different syntax as long as it's compatible with what I've written so far. I'll give it a second look and try to just integrate it to the existing code. – GabeJC Jul 26 '18 at 15:45

1 Answers1

0

I went about it a different way. Will try the method from the link on my next project. In this method I basically defined root windows for each window class. Not sure why the root window on the main script does not need to be initialized (I'm assuming it probably did in the background and used default values), but it worked nonetheless. The (Window).deiconify() and (Window).destroy() attributes allowed me to hide and show the windows whenever I navigated to a different page. Here is my code:

    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`
GabeJC
  • 1
  • 1
  • 3