是否有办法将tkinter GUI封装在一个类中,以便可以从另一个对象创建和交互?(*不*在mainloop中挂起)

0 投票
1 回答
1157 浏览
提问于 2025-04-16 15:06

有没有办法把一个tkinter的图形界面放在一个类里面,这样可以从其他对象创建和互动?为了让这个方法真正有用,这个类必须能够工作,不会让主循环(mainloop)或者类似的东西阻碍整个应用程序。如果可以的话,有人能给我一个有效的例子吗?

背景:我想做一个SimpleUI类,这样我就可以在任何应用程序中使用它,来显示信息或者注册一些在按钮点击或按键时执行的功能。所以我希望所有的线程、队列等都能隐藏在SimpleUI类里面。

根据我阅读的内容,答案是“不可以”,除非重新实现主循环。实际上,图形界面应该是主要的应用程序,通过某种方法来分配工作。不过,这样会让任何使用tkinter的应用程序(可能其他图形界面也是)感觉像是“尾巴摇狗”,希望我误解了我所阅读的内容。

我知道这可能看起来像是对这个和其他类似问题的重复提问,但我无法在那些问题下评论,而且答案似乎和我想做的正好相反。除了那个问题,我在很多地方找到了相关代码的片段,但我还没能把它们组合起来。如果有办法的话,我会学习Python的线程或者其他东西来让它工作。

我使用的是Python 3.1,如果这有什么影响的话。

这是我希望它工作的一个例子。

ui = SimpleUI()
ui.hide()
ui.show()
ui.add_frame...
ui.add_button...
ui.register_function(button, function)

1 个回答

1

这就是你想要的东西吗?

#The threading module allows you to subclass it's thread class to create
#and run a thread, in this case we will be starting SimpleUI in a seperate thread

import threading
from Tkinter import *

def printfunction():
    print "ButtonPress"

class NewClass:
    def __init__(self):
        self.ui = SimpleUI()
        self.ui.add_frame("frame1")
        self.ui.add_button("button1","frame1")
        self.ui.register_function("button1",printfunction)
        self.ui.start()
        #self.ui = Threader().start()
    def PrintSuccess(self):
        print "Success!"

class SimpleUI:
    def __init__(self):
        self.root = Tk()
        self.frames = {}
        self.buttons = {}
    def start(gui):
        class Threader(threading.Thread):
            def run(self):
                gui.root.mainloop()
        Threader().start()
    def hide(self):
        self.root.withdraw()
        if(raw_input("press enter to show GUI: ")==""):self.show()
    def show(self):
        self.root.update()
        self.root.deiconify()
    def add_frame(self,name):
        tmp = Frame(self.root)
        tmp.pack()
        self.frames[name] = tmp
    def add_button(self,name,frame):
        tmp = Button(self.frames[frame])
        tmp.pack()
        self.buttons[name] = tmp
    def register_function(self,button,function):
        self.buttons[button].config(command=function)


NC = NewClass()
NC.PrintSuccess()

撰写回答