簡體   English   中英

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'
  1. 如何從其他py文件中調用主py文件中的函數。
  2. 什么是最好的方式,我應該讓使用的classfunctiontext_infomain.py文件
  3. 如果這不是正確的編碼方式,請糾正我。

您可以通過提供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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM