调用位于另一个类(Tkinter)的方法中的变量

时间:2020-07-23 08:52:04

标签: python-3.x oop tkinter

我是一个初学者,因此,感谢您对我遇到的问题的耐心和理解。

背景

我使用的是:macOS,Python3,ATOM

我正在尝试建立一个图书馆,以存储有关可用书籍(标题,作者,年份,ISBN)的信息。我的计划是分别为后端和前端创建一个脚本。最终,通过导入后端脚本并使用在那里设计的功能,将它们全部连接到前端脚本上。是的,我之前使用过OOP,但仅用于构建二十一点游戏。 tkinter对班级的使用对我来说有点古怪,我迷路了。

当前情况

我的UI看起来像我想要的样子,并且当前正在创建用于附加到按钮的命令的函数。问题是,我在两个不同的类中分别具有入口小部件和ScrolledText小部件,分别代表两个不同的框架(顶部和底部),并在调用变量时

title.val = tk.StringVar() 

弹出错误:

  Traceback (most recent call last):
  /LIBfront.py", line 105, in <module>
    class main():
  /LIBfront.py", line 111, in main bottomleft = BottomFrame(win)
  /LIBfront.py", line 52, in __init__ self.search_cmd()
  /LIBfront.py", line 64, in search_cmd for row in LIBback.search_entry(TopFrame.title_val.get(), self.author_val.get(), year_val.get(), isbn_val.get()):
AttributeError: type object 'TopFrame' has no attribute 'title_val'

这是该代码的简化版本,仅包含部分内容。 编辑:根据反馈进行的更改

    import tkinter as tk
import tkinter.scrolledtext as tkst
import LIBback # This is just the backend script

# Creating top frame for user input
class TopFrame():

    def __init__(self, win):
        self.win = win
        self.frame = tk.Frame(win, relief = 'groove')
        self.frame.pack(fill = 'x', expand = False)
        self.topwidgets()

    def topwidgets(self):
        self.title_val = tk.StringVar()
        self.lbl1 = tk.Label(self.frame, text = 'Title:')
        self.e1 = tk.Entry(self.frame, width = 25, textvariable = self.title_val)
        self.lbl1.grid(row = 0, column = 0, ipadx = 10, ipady = 10)
        self.e1.grid(row = 0, column = 1, sticky = 'e')

# Creating bottom frame for user interaction and results display
class BottomFrame():

    def __init__(self, win):
        self.win = win
        self.frame1 = tk.Frame(win)
        self.frame1.pack(fill = 'both', side = "left", expand = False)
        self.frame2 = tk.Frame(win)
        self.frame2.pack(fill = 'both', side = "left", expand = True)
        self.widgets()
        self.search_cmd()

    def search_cmd(self):
        self.txtbox.delete('1.0',tk.END) # Below this line is where the issue began
        for row in LIBback.search_entry(self.title_val.get()):
            self.txtbox.insert(tk.END, row)

    def widgets(self):
        self.button2 = tk.Button(self.frame1, text = 'Search Entry', height = 2 , width = 10, command = self.search_cmd)
        self.button2.pack(side = 'top', fill = 'y', pady = 5, padx = 5)

def main():
    win = tk.Tk()
    win.title('Book Shop')
    win.geometry("630x370")
    top = TopFrame(win)
    bottom = BottomFrame(top)
    win.mainloop()

if __name__ == '__main__':
    main()

我尝试或试图理解的内容

  1. 即使已声明方法并使用该变量,也不会将目标变量声明为属性。
  2. 通过TopFrame.topwidgets.title_val.get()以[CLASS.FUNCTION.VAR.get()]的形式访问它对我不起作用。
  3. 使用tkinter模仿OOP的其他示例,其中有一个“主”?类,并在其中声明self.var = tk.StringVar()并使用“控制器”来引用它。失败,原因是我缺乏这种理解。

我的问题

在这种情况下,如何调用该变量?可能的话,您能否带我逐步了解为什么它未能将其声明为类的属性,或者我如何使它们彼此无法连接?

非常感谢您的提前帮助!真的很感激!

1 个答案:

答案 0 :(得分:1)

您应该将top作为参数传递给BottomFrame,以便可以在title_val内部访问TopFrame中的BottomFrame

class BottomFrame():
    def __init__(self, win, top):
        self.win = win
        self.top = top
        ...

    def search_cmd(self):
        self.txtbox.delete('1.0',tk.END)
        for row in LIBback.search_entry(self.top.title_val.get()):
            self.txtbox.insert(tk.END, row)

...

def main():
    win = tk.Tk()
    win.title('Book Shop')
    win.geometry("630x370")
    top = TopFrame(win)
    bottom = BottomFrame(win, top) # pass top to BottomFrame
    win.mainloop()
相关问题