从单独的python模块(tk.Frames)中的类调用变量

时间:2019-07-31 21:16:13

标签: python-3.x tkinter

我正在编写一个tkinter应用,该应用在三个不同的.py文件中有3个页面。

我重新编写了代码,使我可以通过运行一个主要的总体应用程序来创建每个框架,该应用程序在随后的所有页面中均为self.controller(这要感谢该站点上的一些优秀用户)。我这样做的原因是,我希望能够将用户名(tk.StringVar())从第一个框架传递到第二个框架中的tk.Label

如上所述,我已经重写了几次该代码,但是当我尝试从其他页面之一实际调用变量或函数时,仍然出现以下错误。

另一个页面称为FrontPage,它存储在front_page.py中,当我通过主tk.Tk运行该页面时,它可以完美运行,因此我知道我已经正确定义了self.name_entry

我为GamePage使用的(最低)代码是

import tkinter as tk
from tkinter import SUNKEN
import front_page
from front_page import FrontPage
from character import Character
from dice_roll import Die


class GamePage(tk.Frame):
    """The overall class for the app"""

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is the start page")
        label.pack(side="top", fill="x", pady=10)
        self.features = {}

        #This is where I try to call the text from the other page
        self.character_name = front_page.FrontPage.name_entry.get()

        self.name_label = tk.Label(
            self.mainframe,
            text= self.character_name,
            font=("Courier", 20),
            bd = 1,
            relief = SUNKEN
        )
        self.name_label.pack()

当我尝试从FrontPage上的tk.Entry实际调用文本时,它不起作用。我其他类中的所有函数(都从顶部导入)都可以正常工作。

Traceback (most recent call last):
  File "/Users/kevinomalley/Desktop/python_work/rapid_rpg/app_GUI.py",       
line 47, in <module>
    app = GUI()
  File "/Users/kevinomalley/Desktop/python_work/rapid_rpg/app_GUI.py", 
line 20, in __init__
    frame = F(parent=container, controller=self)
  File "/Users/kevinomalley/Desktop/python_work/rapid_rpg/main_page.py", 
line 23, in __init__
    self.character_name = front_page.FrontPage.name_entry.get()
AttributeError: type object 'FrontPage' has no attribute 'name_entry'

现在我90%的确定这是因为我没有正确使用self.controller 我看到了很多参考它的答案,但是没有清楚地解释如何使用它或有效地调用它。

如果有人能使我免于头撞墙的5天之苦,那将使我可怜的小新手心跳起来。

谢谢

1 个答案:

答案 0 :(得分:1)

控制器是控制页面之间访问的一种方式。您尚未显示所有代码,但是如果您希望页面能够访问其他页面,则首先需要做的就是创建一个函数,该函数可以返回对另一个页面的引用。

例如:

class YourApp(...):
    ...
    def get_page(self, page_class):
        return self.frames[page_class]

现在,您可以从任何页面调用此函数以获取对任何其他页面的引用:

game_page = self.controller.get_page(GamePage)

有了该参考,您现在可以使用其任何属性:。例如:

self.character_name = game_page.name_entry.get()

注意:这些示例可能不是100%正确的。我不知道您是如何实现其余代码的。但是,这个概念很重要:

  • 向控制器添加方法以返回页面
  • 调用该方法以获取对页面的引用
  • 使用该引用获取该页面的属性

在此答案中将对所有这些内容进行更详细的说明:https://stackoverflow.com/a/33650527/7432