AttributeError: у объекта '_tkinter.tkapp' нет атрибута 'titleBar' - PullRequest
0 голосов
/ 10 июня 2018

Я написал графический интерфейс с tkinter.На заднем плане я должен выполнить некоторые интенсивные вычисления.Время от времени я хочу записывать некоторую информацию из потока вычислений в окно графического интерфейса.

Сначала я подумал, что было бы неплохо добавить код вычисления в "mainloop".Но это не работает, потому что mainloop ответственен за поддержание GUI реактивным.Кажется, это не очень хорошая идея для его внедрения.

Ниже я создал фиктивное приложение, которое соответствует моей новой идее.В примере приложения есть контейнер.Внутри этого контейнера есть TitleBar.Класс TitleBar определен ниже.Он содержит только одну метку.

Далее я определю простой поток.Он имитирует трудоемкие вычисления, при которых требуется записать некоторую информацию в графический интерфейс.

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'

Как мне получить доступ и изменить свойства объекта метки?

Спасибо

Бернд

Ответы [ 3 ]

0 голосов
/ 10 июня 2018

С помощью eyllanesc и Mark_Bassem мне удалось решить проблему.Кажется, что проблема действительно была очень простой.

На всякий случай, если люди зайдут в этот пост в будущем, я оставлю правильный код здесь:

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)
        self.titleBar = TitleBar(container, controller=self) 
        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
        self.titleLabel = tk.Label(self, text="This is the initial text")
        self.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'] = "status: " + str(a)


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

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

    t = MyTestThread()
    t.start()

    app.mainloop()
0 голосов
/ 11 июня 2018

Вы забыли поставить себя перед атрибутом titleBar

0 голосов
/ 10 июня 2018

Вы забыли поставить self перед атрибутом titleBar

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...