【问题标题】:How to seperate Tkinter Gui app source code into multiple files如何将 Tkinter Gui 应用程序源代码分成多个文件
【发布时间】:2021-11-12 14:13:58
【问题描述】:

我正在使用 Tkinter 下载管理器 python gui 应用程序,到了一半,我的代码开始看起来很乱,所以我决定在不同的文件上分离函数,然后导入它: 我的主要代码:

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()

但是我的 functions.py 代码看起来像这样:

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)

基本上我希望该函数调用并显示一个弹出窗口,我相信这可以做得更好一百万倍,但我只是在学习,但是我收到一个错误说: 顶层未定义

【问题讨论】:

  • 每个文件都需要导入tkinter
  • 当我在另一个文件上导入 tkinter 时,它说 root 没有定义
  • 这是一个单独的问题。

标签: python function tkinter import toplevel


【解决方案1】:

你需要建立一个类来管理它。

run.py 内部:

import tkinter as tk
from interface import GUI

root = tk.Tk()
GUI(root)

然后在你的 interface.py 脚本中你可以调用额外的模块:

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

然后你就可以使用OOP来访问函数或对象以动态地相互交互了。

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

在 menu.py 中从 GUI_list 中识别正确的索引:

 import tkinter as tk

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

【讨论】:

  • 我认为说他们需要一个类来管理它有点强。不用类当然可以解决这个问题。
  • 用你的技术。您是否能够从不同导入模块中的函数编辑导入模块中的对象?还是您的技术仅适用于主要脚本?
  • 您的问题太模糊,无法回答。是的,可以修改从其他模块传入的对象。是的,使用类来定义应用程序会使这更容易,但这并不是绝对必要的。
【解决方案2】:

每个文件都需要导入 tkinter。

此外,主文件中任何被导入函数需要的变量都需要传入函数中。例如,您应该定义add_download 以接受根窗口作为参数。

def add_download(root):
    ...

然后,在主程序中,将root 作为参数传递:

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

【讨论】:

    猜你喜欢
    • 2019-11-05
    • 2011-01-06
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多