Передача переменных в окно класса tkinter - PullRequest
0 голосов
/ 30 сентября 2018

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

Я действительно покопался и попробовалчтобы найти некоторую информацию о передаче сообщений, и я нашел отличную информацию о модуле pickle, используя многопроцессорную обработку и встроенные в нее инструменты, а также многопоточность и организацию очередей.Я даже копался в уроке Дэвида Бизли о параллелизме, расположенном здесь . Я просто не могу понять синтаксис ни для одного из этих методов.

Я разбил свой код на небольшой функциональный блок, который должен запускать небольшое окно tkinter, например:

Окно tkinter

Код нижеимеет функцию «launchGUI», которая запускает мой графический интерфейс tkinter, функцию «myLoop», которая запускает потоки, а также выполняет цикл для управления моей более крупной программой позже, сейчас она просто вращает переменную blink.У меня также есть метод blinkCheck в моем классе, который проверяет состояние переменной blink в классе.

Я даже не знаю, отправляю ли я получателя сообщений в нужное место.В следующем примере кода я просто пытаюсь передать глобальную переменную в класс.Я знаю, что он попадает в класс, потому что метод blinkCheck () работает, даже если раскомментирование этого метода приводит к сбою окна.Однако при отключенном методе метка в графическом интерфейсе никогда не меняется.Я думаю, что сбой окна - наименьшее из моих беспокойств, должно быть, потому что у меня есть еще один цикл выполнения.

Как правильно изменить это число в Label для изменения?

Вот мой пример кода:

import tkinter as tk
from tkinter import Frame, Label
import time
import threading

blink = 0

class MyClass(tk.Frame):
    def __init__(self, master):
        self.master = master
        super().__init__(self.master)

        global blink  

        self.label = Label(master, text=blink)
        self.label.pack()
        #self.blinkCheck()

    def blinkCheck(self):
        global blink
        while True:
            print("blink in blinkCheck method is = {}".format(blink))
            time.sleep(2.5)

def launchGUI():
    root = tk.Tk()
    root.title("My Blinker")
    app1 = MyClass(root)
    app1.mainloop()

def myLoop():
    global blink
    t1=threading.Thread(target=launchGUI)
    t1.daemon = True
    t1.start()
    print("blink in blinker function is {}".format(blink))
    while True:
        if blink == 0:
            blink = 1
        else:
            if blink == 1:
                blink = 0
        time.sleep(2.5)


if __name__=="__main__":
    myLoop()

Ответы [ 2 ]

0 голосов
/ 30 сентября 2018

Во-первых, графический интерфейс должен работать в основном потоке и не должен блокироваться бесконечным циклом.Вместо этого используйте after.Для общения используйте какой-нибудь подходящий объект из потоков, например Event:

import tkinter as tk
import time
import threading

class MyClass(tk.Frame):
    def __init__(self, master, event):
        super().__init__(master)
        self.master = master
        self.event = event

        self.label = tk.Label(master, text='')
        self.label.pack()
        self.after(100, self.blink_check)

    def blink_check(self):
        self.label['text'] = self.event.is_set()
        self.after(100, self.blink_check)

def blink(event):
    while True:
        event.set()
        time.sleep(2.5)
        event.clear()
        time.sleep(2.5)

def main():
    root = tk.Tk()
    root.title("My Blinker")
    event = threading.Event()
    t = threading.Thread(target=blink, args=(event,))
    t.daemon = True
    t.start()
    frame = MyClass(root, event)
    root.mainloop()

if __name__=="__main__":
    main()
0 голосов
/ 30 сентября 2018

В своем описании вы упомянули что-то о задействовании кнопок.Я не вижу этого в предоставленном вами фрагменте.Но с помощью кнопок можно настроить метку, например:

from tkinter import Label, Button
blink = 0

class MyClass(tk.Frame):
    def __init__(self, master):
        self.master = master
        super().__init__(self.master)

        global blink  

        self.label = Label(master, text=blink)
        self.button = Button(master, text="Button", command=lambda: foo(self.label))
        self.label.pack()
        self.button.pack()
        #self.blinkCheck()

    def blinkCheck(self):
        global blink
        while True:
            print("blink in blinkCheck method is = {}".format(blink))
            time.sleep(2.5)

    def foo(self, label):
        label.config(text=blink)

Условно это самый простой способ настройки метки в активном потоке.

Если кто-то захочетэтот ответ может быть не совсем правильным, пожалуйста, отредактируйте его, потому что я новичок в переполнении стека!

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