AttributeError:'_ tkinter.tkapp'对象没有属性'titleBar'

时间:2018-06-10 18:46:06

标签: python multithreading tkinter

我用tkinter编写了一个GUI。在后台我必须进行一些密集的计算。我不时想从计算线程中将一些信息写入GUI窗口。

首先,我认为将计算代码添加到“mainloop”中是个好主意。但这不起作用,因为mainloop是保持GUI反应的责任。它接缝并不是一个好主意来构建它。

下面我创建了一个虚拟应用程序来分散我的新想法。 Sample app有一个容器。在该容器内,有一个TitleBar。 TitleBar类定义如下。它只包含一个标签。

接下来我定义一个简单的线程。它模拟了一个耗时的计算,希望将一些信息写入GUI。

import tkinter as tk
import threading
import time


class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        # initialize the main window
        tk.Tk.__init__(self, *args, **kwargs)

        # add a container which will take all the widgets
        container = tk.Frame(self, bg="green")
        container.pack(side="top", fill="both", expand=True)

        # Add a titlebar object (defined below)
        titleBar = TitleBar(container, controller=self) 
        titleBar.grid(row=0, column=0, columnspan=2, sticky=tk.N+tk.W+tk.E)


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

        # the title bar contains only one label element
        titleLabel = tk.Label(self, text="This is the initial text")
        titleLabel.pack(side=tk.LEFT)


# Define a thread that runs in the background to perform intensive calculations
class MyTestThread(threading.Thread):
    def run(self):
        for i in range(10):
            time.sleep(1)
            a = i+100        # intensive calculation

            # from time to time: inform use about status
            print(a)      # printing to console works fine
            app.titleBar.titleLabel['text'] = "test 1"   # --- FAILS ---


if __name__ == "__main__":
    app = SampleApp()

    app.titleBar.titleLabel['text'] = "test 2"   # --- FAILS ---

    t = MyTestThread()
    t.start()

    app.mainloop()

问题是我无法访问标签以向其写入信息。写作在线程内部和应用程序本身都失败了。在这两种情况下都失败并出现以下错误:

AttributeError: '_tkinter.tkapp' object has no attribute 'titleBar'

如何访问和更改label-object的属性?

谢谢

贝恩德

3 个答案:

答案 0 :(得分:0)

您忘记将self放在titleBar属性

之前

答案 1 :(得分:0)

在eyllanesc和Mark_Bassem的帮助下,我能够解决问题。似乎问题确实非常简单。

以防万一人们将来会发表这篇文章,我会在这里保留正确的代码:

executor.diskIO().execute(new Runnable() {...});

答案 2 :(得分:0)

您忘记将自己置于titleBar属性

之前