2016-08-02 47 views
1

我有一個主要文件,主要包含GUI(Tkinter代碼)。一個窗口,其中有LabelText區域,其中文本在用戶操作上更新並且ButtonPython:如何從模塊訪問類的屬性

# ~/main.py 
import Tkinter 
import buttonevent 
from itertools import cycle 

msglist = ['main_msg1\n', 'main_msg2\n', 'main_msg3\n', 'main_msg4\n'] 


class Root(object): 

    def __init__(self, master): 
     self.msglist = cycle(msglist) 
     self.master = master 
     self.frame1 = Tkinter.Frame(master) 
     self.frame1.pack() 
     Root.status = Tkinter.StringVar() 
     self.status_info = Tkinter.Label(self.frame1, textvariable=Root.status) 
     self.status_info.pack() 
     Root.status.set("Set by constructor") 

     self.frame2 = Tkinter.Frame(master) 
     self.frame2.pack() 
     Root.textinfo = Tkinter.Text(self.frame2, width=20, height=10) 
     Root.textinfo.insert(Tkinter.END, 'message 1') 
     Root.textinfo.config(font='Arial') 
     Root.textinfo.pack() 
     Root.textinfo.config(bg=master.cget('bg'), relief=Tkinter.SUNKEN) 
     Root.textinfo.configure(state='disabled') 

     self.frame3 = Tkinter.Frame(master) 
     self.frame3.pack() 
     self.button = Tkinter.Button(self.frame3, text='Ok', command=self.ok) 
     self.button.pack() 

    def ok(self): 
     text_info(self.msglist.next()) 
     buttonevent.do_event() 
     buttonevent.do_stuff() 


def text_info(msg): 
    Root.textinfo.configure(state='normal') 
    Root.textinfo.insert(Tkinter.END, msg) 
    Root.textinfo.see(Tkinter.END) 
    Root.textinfo.configure(state='disabled') 


if __name__ == '__main__': 
    root = Tkinter.Tk() 
    main_window = Root(root) 
    root.mainloop() 

用戶操作在不同的文件上定義。

# ~/buttonevent.py 

from itertools import cycle 
import main 

do_msg = ['do_msg1\n', 'do_msg2\n', 'do_msg3\n', 'do_msg4\n'] 
msg = cycle(do_msg) 


def do_event(): 
    # do something 
    main.text_info(msg.next()) 


def do_stuff(): 
    # do something 
    print 'doing stuff' 

以前的代碼是在一個單一的文件,現在我試圖把它寫成一個多文件的基礎上它的功能。基本上,當用戶做一些事情時,一條消息將顯示在Text區域。由於Text字段顯示消息並且在每次顯示/活動/更新時都具有一些共同性,因此我在主文件中爲它創建了一個函數text_info

說如果我想在Text字段上發送不同的消息以更新不同的文件,例如從buttonevent.py文件中,我該如何實現它。

當我運行它,我得到錯誤的

$ python main.py 
do_msg1 

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "/home/miniconda2/lib/python2.7/lib-tk/Tkinter.py", line 1537, in __call__ 
    return self.func(*args) 
    File "main.py", line 38, in ok 
    buttonevent.do_event() 
    File "/home/buttonevent.py", line 14, in do_event 
    main.text_info(xx) 
    File "/home/main.py", line 51, in text_info 
    Root.textinfo.configure(state='normal') 
AttributeError: type object 'Root' has no attribute 'textinfo' 
  1. 我如何可以調用主PY-文件的功能從不同的PY-文件。
  2. 什麼是最好的方式,我應該做的main.py文件
  3. 使用classfunctiontext_info如果這不是代碼的正確方法,請大家指正。
+0

'textinfo'是沒有設置直到你初始化的根類的至少一個實例。你需要你之前在原始文件創建根類的實例類屬性可以使用text_info函數。除非至少有一個對象被實例化,否則'__init__'方法中的代碼永遠不會執行。啊哈。問題是你有'if __name__ =='__main __':'這意味着當你導入主體時,所有的東西都不會被執行... –

回答

1

你可以達到你想要的東西通過給根實例的引用作爲參數傳遞給函數:

而不是分配到根類:

Root.status = Tkinter.StringVar() 

把它分配給根實例:

self.status = Tkinter.StringVar() 

沒有理由將它分配給Root類而不是實例self,因爲它的所有權也是Root實例的一部分:它是啓動事件進行更新的Root實例(Tkinter部分)的組件。 然後,您可以給自己作爲參數傳遞給您的buttonevent:

def ok(self): 
    text_info(self.msglist.next()) 
    buttonevent.do_event(self) 
    buttonevent.do_stuff(self) 

然後你就可以讓你的類的text_info部分:

class Root(object): 

    ... 

    def text_info(self, msg): 
     self.textinfo.configure(state='normal') 
     self.textinfo.insert(Tkinter.END, msg) 
     self.textinfo.see(Tkinter.END) 

並更改buttonevent這樣:

def do_event(root_instance): 
    # do something 
    root_instance.text_info(msg.next()) 
1

全部「根」。改爲「自我」。 main.py

# ~/main.py 
import Tkinter 
import buttonevent 
from itertools import cycle 
curwin=None 
msglist = ['main_msg1\n', 'main_msg2\n', 'main_msg3\n', 'main_msg4\n'] 
class Root(object): 

    def __init__(self, master): 
     self.msglist = cycle(msglist) 
     self.master = master 
     self.frame1 = Tkinter.Frame(master) 
     self.frame1.pack() 
     self.status = Tkinter.StringVar() 
     self.status_info = Tkinter.Label(self.frame1, textvariable=self.status) 
     self.status_info.pack() 
     self.status.set("Set by constructor") 
     self.curmsg='message 1\n' 
     self.frame2 = Tkinter.Frame(master) 
     self.frame2.pack() 
     self.textinfo = Tkinter.Text(self.frame2, width=20, height=10) 
     self.textinfo.insert(Tkinter.END, 'message 1\n') 
     self.textinfo.config(font='Arial') 
     self.textinfo.pack() 
     self.textinfo.config(bg=master.cget('bg'), relief=Tkinter.SUNKEN) 
     self.textinfo.configure(state='disabled') 

     self.frame3 = Tkinter.Frame(master) 
     self.frame3.pack() 
     self.button = Tkinter.Button(self.frame3, text='Ok', command=self.ok) # "Ok" function defined for click event 
     self.button.pack() 

    def ok(self): 
     #self.text_info(buttonevent.curmsg) 
     self.textinfo.configure(state='normal') 
     self.textinfo.insert(Tkinter.END, buttonevent.curmsg) # get message from buttonevent.py and set for window. Fisrst clicking will get initalized curmsg value. if you want get value after click write buttonevent.do_event() above this codes. 
     self.textinfo.see(Tkinter.END) 
     self.textinfo.configure(state='disabled') 
     buttonevent.do_event() # calling buttonevent's do_event function so it means global message will be changed. next click you will see new value for message. 
     buttonevent.do_stuff() 

if __name__ == '__main__': 
    root = Tkinter.Tk() 
    curwin=Root(root) 
    root.mainloop() 

buttonevent。PY

# ~/buttonevent.py 

from itertools import cycle 
import main 

do_msg = ['do_msg1\n', 'do_msg2\n', 'do_msg3\n', 'do_msg4\n'] 
msg = cycle(do_msg) 
curmsg=msg.next() # Add this variable to call main.py to first click event 

def do_event(): 
    # do something 
    global curmsg #to edit variable value you must call it as global 
    curmsg=msg.next() #Changing variable value for each click 
    #Removed text_info function from main.py it is not necessary. 
def do_stuff(): 
    # do something 
    print 'doing stuff' 
+0

如果你解釋了你改變了什麼,你的答案會更好,更好。否則,我們不得不逐行讀取您的代碼,並將每行與原始代碼進行比較。 –

+0

text_info函數不是必須的,你可以刪除這個函數。 – redratear

+0

您的問題是變量傳輸。我在buttonevent.py腳本中添加了「curmsg」變量。並在Root類的「ok」函數中將其稱爲「buttonevent.curmsg」。並刪除buttonevent.py腳本中do_event函數的任何函數調用,因爲您在初始化Root類中將單擊事件定義爲「確定」。所以當點擊按鈕「ok」時,從buttonevent腳本調用currentmsg。 – redratear