Home > Software design >  How to seperate Tkinter Gui app source code into multiple files
How to seperate Tkinter Gui app source code into multiple files

Time:09-21

i'm working on downloading manager python gui app using Tkinter and halfway there my code started to look very messy so i decided to seperate functions on different file and then import it: my main code:

from tkinter import *
from functions import add_download

root = Tk()
root.title("The Pownloader!")
canvas = Canvas(root, width=700, height=500).pack()

# Buttons:

ADD_BUTTON = Button(root, text="ADD", bd=4, height=2, width=5, command=add_download)
SETTINGS_BUTTON = Button(root, text="SETTINGS", bd=4, height=2, width=5)
ABOUT_BUTTON = Button(root, text="ABOUT", bd=4, height=2, width=5)
EXIT_BUTTON = Button(root, text="EXIT", bd=4, height=2, width=5, command=quit)

# Mini-Buttons:

PAUSE_MINI_BUTTON = Button(root, text="PAUSE", font=(None, "8"), height=2, width=3)
RESUME_MINI_BUTTON = Button(root, text="RESUME", font=(None, "8"), height=2, width=3)
REMOVE_MINI_BUTTON = Button(root, text="REMOVE", font=(None, "8"), height=2, width=3)

# Side_Mini_Buttons:

DOWNLOAD_WINDOW = Button(root, text="Downloads", font=(None, "8"), height=3, width=6)
ERRORS_WINDOW = Button(root, text="Failed", font=(None, "8"), height=3, width=6)
COMPLETED_WINDOW = Button(root, text="Completed", font=(None, "8"), height=3, width=6)

# Positionning Buttons:

ADD_BUTTON.place(x=70, y=20)
SETTINGS_BUTTON.place(x=145, y=20)
ABOUT_BUTTON.place(x=220, y=20)
EXIT_BUTTON.place(x=295, y=20)
PAUSE_MINI_BUTTON.place(x=290, y=455)
RESUME_MINI_BUTTON.place(x=340, y=455)
REMOVE_MINI_BUTTON.place(x=390, y=455)
DOWNLOAD_WINDOW.place(x=1, y=100)
ERRORS_WINDOW.place(x=1, y=160)
COMPLETED_WINDOW.place(x=1, y=220)

# Download Frame:

DOWNLOAD_LIST_LABEL = Label(root, text="Download List:")
DOWNLOAD_LIST_LABEL.place(x=70, y=80)
DOWNLOAD_ENTRIES = Listbox(root, width=70, height=19)
DOWNLOAD_ENTRIES.place(x=70, y=100)


# Main Loop:

root.mainloop()

However my functions.py code looks like this:

def add_download():
    # Defining The Pop-up frame:
    
    top = Toplevel(root, width = 420, height = 150)
    top.title("New Download")

    # Putting on widgets:
    link = StringVar()
    LINK_LABEL = Label(top, text = "Paste Link:")
    FIELD_ENTRY = Entry(top, width = 40, textvariable=link)

    def on_click():
        link_to_verify = (link.get()).strip()
        if len(link_to_verify)>15:
            if link_to_verify[0:11]=="http://www.":
                DOWNLOAD_ENTRIES.insert(0, link_to_verify)
            else:
                print("Stupid")
        else:
            print("not a valid link")

    BUTTONS_WIDGET = Frame(top)
    ADD_BUTTON = Button(BUTTONS_WIDGET, text = "Add", width=10, command=on_click)
    CANCEL_BUTTON = Button(BUTTONS_WIDGET, text = "Cancel", width=10, command=top.destroy)

    # Positionning everythig:
    LINK_LABEL.grid(column=0,row=0)
    FIELD_ENTRY.grid(column=1,row=0)
    BUTTONS_WIDGET.grid(column=1,row=2)
    ADD_BUTTON.grid(column=0,row=0)
    CANCEL_BUTTON.grid(column=1,row=0)

basically i wanted the function to call and show a pop-up window, i'm sure this could done in a million times better but i'm just learning, however i receive an error says: Toplevel is not defined

CodePudding user response:

You will need to build a class to manage it.

Inside run.py:

import tkinter as tk
from interface import GUI

root = tk.Tk()
GUI(root)

Then inside your interface.py script you can call in additional modules:

import tkinter as tk
from aux import AuxGUI
from menu import MenuGUI 

class GUI:
    def __init__(self, master):
        self.master = master
        self.GUI_list = []
        self.AuxGUI = AuxGUI(self.master, self.GUI_list)  # Additional module
        self.MenuGUI = MenuGUI (self.master, self.GUI_list)  # Additional module

Then you can use OOP to access functions or objects to dynamically interact with each other.

 self.GUI_list.append(self.AuxGUI)
 self.GUI_list.append(self.MenuGUI)

Inside menu.py identify the correct index from the GUI_list:

 import tkinter as tk

 class MenuGUI:
     def __init__(self, master, GUI_list):
         self.master = master
         self.AuxGUI = GUI_list[0]

CodePudding user response:

Every file needs to import tkinter.

In addition, any variables in the main file which are needed by the imported functions need to be passed into the functions. For example, you should define add_download to accept the root window as a parameter.

def add_download(root):
    ...

Then, in the main program, pass root as that parameter:

ADD_BUTTON = Button(root, ..., command=lambda: add_download(root))
  • Related