2016-07-15 76 views
0

我想製作一個GUI程序,其中包含幾個頁面的按鈕和標籤。我需要該程序能夠通過按下按鈕 來動態更改標籤,以便與當前未處理的頁面上的標籤進行交互。我製作了一個可以運行的示例程序,但在嘗試更改未顯示頁面中的標籤時出現錯誤。AttributeError:type object'class'has no attribute'stringVar'

import tkinter as tk 
from tkinter import ttk 

LARGE_FONT = ("Verdana", 12) 


class ManyPagesApp(tk.Tk): 

    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 
     container = tk.Frame(self) 
     container.pack(side="top", fill="both", expand=True) 
     container.grid_rowconfigure(0, weight=1) 
     container.grid_columnconfigure(0, weight=1) 
     self.frames = {} 

     # This loop adds the pages into the frame 
     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) 

    # This function raises the page to the "top" level of the frame 
    def show_frame(self, cont): 
     frame = self.frames[cont] 
     frame.tkraise() 


# Creates what shows in start page 
class Page1(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 

     button1 = ttk.Button(self, text="Go to Page 2", command=lambda: controller.show_frame(Page2)) 
     button1.pack() 

     button2 = ttk.Button(self, text="THIS BUTTON CHANGES LABEL ON PAGE 1", 
         command=lambda: self.labelChanger('This label was changed by using button 2')) 
     button2.pack() 

     label = ttk.Label(self, text='This is Page 1', font=LARGE_FONT) 
     label.pack(pady=10, padx=10) 

     self.labelVariable1 = tk.StringVar() 
     self.labelVariable1.set('This label will be changed') 
     label = tk.Label(self, textvariable= self.labelVariable1) 
     label.pack() 

    def labelChanger(self, text): 
     self.labelVariable1.set(text) 

class Page2(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     objectofpage1 = Page1 

     button1 = ttk.Button(self, text="Goes to page 1", command=lambda: controller.show_frame(Page1)) 
     button1.pack() 

     button2 = ttk.Button(self, text="Changes Label 2 in page 1", 
         command=lambda: objectofpage1.labelChanger(objectofpage1, 'You have changed the label in page 1')) 
     button2.pack() 

     label = ttk.Label(self, text='This is page 2', font=LARGE_FONT) 
     label.pack(pady=10, padx=10) 



# Runs everything 
if __name__ == "__main__": 
    app = ManyPagesApp() 
    app.mainloop() 

我的應用程序由於有更多的頁面得到更大的,但我做了這個示例程序,讓我同樣的錯誤。

OBS:錯誤只發生在頁面2上並嘗試更改第一頁上的標籤時。

這是彈出的錯誤:

Exception in Tkinter callback 
Traceback (most recent call last): 
File "***\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__ 
return self.func(*args) 
    File "***/TestApp.py", line 63, in <lambda> 
command=lambda: objectofpage1.labelChanger(objectofpage1, 'You have changed the label in page 1')) 
    File "***/TestApp.py", line 51, in labelChanger 
self.labelVariable1.set(text) 
AttributeError: type object 'Page1' has no attribute 'labelVariable1' 

PS:第一次發帖,我不知道這是不是已經回答了,但我找不到任何解決這個問題,所以我只是爲了發佈這個帳戶。

我很欣賞幫助,並提前致謝!

+2

'objectofpage1 = Page1'。你需要創建一個'Page1'的實例。 'Page1'類在創建之前沒有'labelVariable1',因爲它是在'__init__'中創建的。請注意,這可能不會做你認爲它的作用。 –

+0

複製代碼時我有一個縮進錯誤... for循環應該縮進。它應該是ManyPagesApp類中__init__的一部分...如何編輯我在那裏編寫的代碼? – theBoringProgrammer

+0

那我該怎麼做?我如何使變量labelVariable1「全局」?我知道錯誤在那裏,但我不知道解決方案是什麼... – theBoringProgrammer

回答

1

錯誤與這樣的說法:

objectofpage1 = Page1 

要設置objectofpage1類,而不是一個實例類的。你的程序已經有一個實例,你只需要獲取由控制器管理的實例。

如果每個頁面都需要訪問其他頁面,您只需要向控制器添加一個方法來返回實例。事情是這樣的:

class ManyPagesApp(tk.Tk): 
    ... 
    def get_page(self, page_class): 
     return self.frames[page_class] 

class Page2(tk.Frame): 

    def __init__(self, parent, controller): 
     ... 
     objectofpage1 = controller.get_page(Page1) 

注意:你也有這種說法的錯誤:

command=lambda: objectofpage1.labelChanger(objectofpage1, 'You have changed the label in page 1')) 

它應該是:

command=lambda: objectofpage1.labelChanger('You have changed the label in page 1')) 

對於頁面之間共享信息的更深入的討論,請參閱How to get variable data from a class

+0

謝謝sooo多!這正是我需要知道的! – theBoringProgrammer

相關問題