【问题标题】:AttributeError: object has no attribute 'listbox'?AttributeError:对象没有属性“列表框”?
【发布时间】:2017-02-08 22:57:11
【问题描述】:

在这个简单的脚本中,在Page1 上的listbox 中选择的项目被保存并从Page2 打印。 listbox 中的值保存在 app_data 中。代码运行,但app_data 中没有记录任何值(打印的值为空白)。出现以下异常:

Exception in Tkinter callback Traceback (most recent call last):
  File "/usr/lib/python3.4/tkinter/__init__.py", line 1536, in __call__
    return self.func(*args)   File "filepath/file.py", line 35, in <lambda>
    button1 = ttk.Button(self,text="Next Page",command=lambda: controller.show_frame(Page2)
                         or self.controller.app_data["listbox"]
                         .set(self.listbox.get(self.listbox.curselection())))
AttributeError: 'Page1' object has no attribute 'listbox'

据我所知,控制器无法识别列表框。我使用super() 研究了可能的解决方案,如Understanding Python super() with init() methods 所示,但没有成功。

问题: 什么能使列表框值正确保存到app_data

button1 = ttk.Button(self,text="Next Page"
                     ,command=lambda: controller.show_frame(Page2)
                     or self.controller.app_data["listbox"]
                     .set(self.listbox.get(self.listbox.curselection()))

完整代码:

from tkinter import *
from tkinter import ttk

class MyApp(Tk):
    def __init__(self):
        Tk.__init__(self)

        # App data in controller
        self.app_data = {"listbox":    StringVar()}

        container = ttk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        self.frames = {}

        for F in (Page1, Page2):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky = NSEW)
        self.show_frame(Page1)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

class Page1(ttk.Frame):
    def __init__(self, parent, controller):
        ttk.Frame.__init__(self, parent)
        self.controller = controller

        listbox = Listbox(self,exportselection=0)
        listbox.grid()
        for item in [0,1,2,3,4,5]:
            listbox.insert(END, item)

        button1 = ttk.Button(self,text="Next Page"
                             ,command=lambda: controller.show_frame(Page2)
                             or self.controller.app_data["listbox"]
                             .set(self.listbox.get(self.listbox.curselection())))
        button1.grid()

class Page2(ttk.Frame):
    def __init__(self, parent, controller):
        ttk.Frame.__init__(self, parent)
        self.controller = controller
        ttk.Label(self, text='Next Page').grid(padx=(20,20), pady=(20,20))
        button1 = ttk.Button(self, text='Select Page',
                             command=lambda: controller.show_frame(Page1))
        button1.grid()
        button2 = ttk.Button(self, text='print value', command=self.print_value)
        button2.grid()
    def print_value(self):
        value = self.controller.app_data["listbox"].get()
        print ('The value stored in StartPage some_entry = ' + str(value))

app = MyApp()
app.mainloop()

【问题讨论】:

    标签: python python-3.x tkinter listbox


    【解决方案1】:

    你的问题很简单:在button1定义中你使用了self.listbox的一些方法,但是当你定义你的列表框时,你还没有将它定义为Page1的属性:listbox = Listbox(self,exportselection=0)(没有@987654325 @在它前面)。这就是您收到错误 AttributeError: 'Page1' object has no attribute 'listbox' 的原因。

    有两种方法可以避免这种情况:

    • 如果您需要在Page1__init__ 方法之外的某个位置使用列表框,请将其设为属性:self.listbox = Listbox(self,exportselection=0) 并将所有listbox 替换为self.listbox

    • 如果您在其他任何地方都不需要它,只需更改 listbox 中的 self.listbox button1 定义:

      button1 = ttk.Button(self,text="Next Page"
                           ,command=lambda: controller.show_frame(Page2)
                           or self.controller.app_data["listbox"]
                           .set(listbox.get(listbox.curselection())))
      

    【讨论】:

      猜你喜欢
      • 2017-09-03
      • 2021-07-05
      • 2018-01-16
      • 2016-05-14
      • 2016-12-21
      • 2022-01-23
      • 2022-01-23
      • 2019-11-01
      • 2021-08-23
      相关资源
      最近更新 更多