【问题标题】:Separating Tkinter GUI into Separate Modules (Python 3.4)将 Tkinter GUI 分成单独的模块(Python 3.4)
【发布时间】:2017-07-12 20:08:39
【问题描述】:

我在 Tkinter 中有一个越来越复杂的 GUI。我想把它分成一些模块,以便于管理。 如果我不使用面向对象的方法,有没有办法将我的 GUI 分成模块?

这是我想移至单独模块的一些代码的简单示例:

def create_main_nav_buttons(strat_folder_list):
    global dynamic_info_nav_items
    temp_count = 0
    for item in strat_folder_list:
        main_nav = tk.Canvas(Nav_Frame_Top, width=175, height=grid_box_size/1.5, highlightthickness=1, bg='slategray1')
        main_nav.grid(row = temp_count, column = 1)
        main_nav.bind("<Button-1>", lambda event, x=item: create_navigation2(x)) 
        temp_count += 1
    dynamic_info_nav_items.append(main_nav)

-旁注:

我之前使用object oriented approach 编写了一个 GUI,但这次决定不使用它,因为我没有完全理解其中的某些部分,例如:

def __init__(self, parent, *args, **kwargs):
    tk.Frame.__init__(self, parent, *args, **kwargs)
    self.parent = parent

因此,当出现问题时,修复是一场噩梦,我找不到太多支持。

【问题讨论】:

  • (使用这种方法,全局变量和导入也将成为一场噩梦)。即在示例代码中,您也需要导入create_navigation2Nav_Frame_Top
  • 我使用函数和变量用 tkinter 编写了一个 600 行的 GUI,它工作得很好,但是我最终将它移到了一个类中,这样我就可以避免使用全局变量。您可能只想对类使用 OOP 方法,这样您就可以使用类属性来避免全局变量。
  • __init__ 语句你看不懂怎么办?如果您阅读了上面的文档,这并不难弄清楚。
  • 不仅如此。它如何访问不同的功能。例如,我有一个按钮,我希望它在单击时激活一个功能。它不起作用,因为: AttributeError: object has no attribute 'parent' 我不知道 WTF 是错误的。通过反复试验,有时会使用 self.parent.main 让它工作。或 self.main 或 self.. 但后来又遇到了另一个对我来说没有意义的问题。当我想发布一个问题的简化版本时,我不知道要删除什么以及包含什么。太糟糕了,我真的很想使用课程,但不知道当事情变糟时如何获得帮助。

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


【解决方案1】:

使用 OO 技术是将代码划分为模块的正确方法,但这不是唯一的方法。我认为不上课会做更多的工作,但是没有什么可以阻止您在不上课的情况下做自己想做的事。

您需要改变编码方式的主要内容是停止依赖全局变量。这意味着您需要将信息从主程序传递给函数,而函数需要将信息返回给主程序。

示例

尽管我做了一些小的更改,但我已尝试使此示例中的代码尽可能接近您的原始代码。

首先,创建一个名为“widgets.py”的文件,内容如下:

import tkinter as tk

def create_main_nav_buttons(parent, grid_box_size, items):
    temp_count = 0
    widgets = []
    for item in items:
        main_nav = tk.Canvas(parent, width=175, height=grid_box_size/1.5, highlightthickness=1, bg='slategray1')
        main_nav.grid(row = temp_count, column = 1)
        main_nav.bind("<Button-1>", lambda event, x=item: create_navigation2(x)) 
        temp_count += 1
        widgets.append(main_nav)

    return widgets

def create_navigation2(x):
    print("create_navigation2...", x)

接下来,在名为“main.py”的文件中创建您的主程序:

import tkinter as tk
from widgets import create_main_nav_buttons

root = tk.Tk()
Nav_Frame_Top = tk.Frame(root)
Nav_Frame_Top.pack(side="top", fill="x")

dynamic_info_nav_items = []
strat_folder_list = ["one", "two", "three"]
grid_box_size=10

widgets = create_main_nav_buttons(Nav_Frame_Top, grid_box_size, strat_folder_list)
dynamic_info_nav_items += widgets

root.mainloop()

请注意,您希望在全局命名空间中的父项和其他项被传递给函数,然后函数返回主程序可以使用的值。

本质上,您是在函数和主程序之间创建契约。合同是“您告诉我构建小部件所需的信息,我将创建小部件并将它们以列表的形式返回给您”。

【讨论】:

  • 抱歉无法在这里私信你,也找不到你的联系方式。不得不感谢您对 tkinter 的所有帮助。你所有的帖子都是无价的。一年多前我学会了编程,在你的帮助下,我做了一个非常有用的应用程序。我知道我有很多东西要学,你所有的帖子都在慢慢地让我朝着正确的方向前进。谢谢!
猜你喜欢
  • 2016-03-17
  • 1970-01-01
  • 2019-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多