![](/img/trans.png)
[英]How to access a caller method's __class__ attribute from a callee function in Python?
[英]Python: how to access a class's attribute from a module
我有一個主文件,主要包含GUI(Tkinter代碼)。 一個帶有Label
的窗口,一個Text
區域和一個Button
,在該區域中,用戶操作會更新文本。
# ~/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_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'
class
或function
的text_info
在main.py
文件 您可以通過提供Root實例的引用作為函數的參數來實現所需的功能:
而不是分配給Root類:
Root.status = Tkinter.StringVar()
將其分配給Root實例:
self.status = Tkinter.StringVar()
沒有理由將其分配給Root類而不是實例本身,因為它的所有權也是Root實例的一部分:觸發事件進行更新的是Root實例的組件(Tkinter部件)。 然后,您可以將self作為按鈕事件的參數:
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())
全部是“根”。 改成“自我”。 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'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.