Python - Обновление текста метки внутри класса окна извне функции - PullRequest
0 голосов
/ 31 августа 2018

Добрый день всем,

Я пытаюсь написать приложение, которое запускает мой HVAC и ряд других систем, работающих на Raspberry PI. Я буду первым, кто признает, что Python и я не хорошие друзья. Однако библиотека драйверов для датчиков, которые я использую, кажется, не совместима с Java или чем-то еще, в чем я лучше подготовлен. Я потратил несколько дней на поиск ответа на этот вопрос, но не смог найти тот, который имеет работал на меня.

По сути, я пытаюсь получить функцию getcurrentTH () для обновления currenttempLabel в графическом интерфейсе. Я получаю сообщение об ошибке.

Ошибка имени: имя currenttempLabel не определено

Я предполагаю, что это как-то связано с тем, как я пытаюсь вызвать метку внутри класса из функции извне. Любые указатели будут оценены.

Код ниже.

import mysql.connector
import time
import Adafruit_DHT as dht
from tkinter import *
import random
import _thread
import threading

started = 0
currentTemp = 0
currentHumidity = 0

def getcurrentTH():
    while started > 0:
        global currentTemp
        global currentHumidity
        h,t = dht.read_retry(dht.DHT22, 4)
        currentTemp = ((t *1.8) + 32)
        currentHumidity = h
        currenttempLabel['text'] = currentTemp
        time.sleep(5)

def start():
    global started
    started = 1
    print("started")
    print(started)
    t3 = threading.Thread(target=getcurrentTH)
    t3.start()


def stop():
    global started
    started = 0

def quitapp():
    exit()

class Window(Frame):

    def __init__(self, master = None):
        Frame.__init__(self, master)

        self.master = master

        self.init_window()

    def init_window(self):
        global currentTemp
        global currentHumidty

        self.pack(fill=BOTH, expand=1)

        startButton = Button(self, height = 3, width = 5, bg = "light green", text= "Start", command=start)

        startButton.place(x=625, y=50)

        stopButton = Button(self, height =3, width =5, bg = "red",  text = "Stop", command=stop)

        stopButton.place(x=625, y=150)

        statusLabel = Label(self,  text = "Current Status: N/A")

        statusLabel.place(x=600, y=125)

        quitButton = Button(self, height =3, width = 5, text = "Quit", command=quitapp)

        quitButton.place(x=625, y=500)

        currenttempLabel = Label(self, font = ("Courier",26), text = "No Current Reading" )
        currenttempLabel.place(x=50, y=50)

root = Tk()
root.geometry("800x600")
app = Window(root)
root.mainloop()

1 Ответ

0 голосов
/ 31 августа 2018

Ваш currenttempLabel является локальной переменной в Window.init_window. Как только эта функция завершается, переменная исчезает, и больше нет доступа к ее значению.

Если вы хотите сохранить эти виджеты в переменных, к которым можно будет получить доступ позже, самое простое, что вам нужно сделать, это поместить их в атрибуты объекта:

self.currenttempLabel = Label(self, font = ("Courier",26), text = "No Current Reading" )
self.currenttempLabel.place(x=50, y=50)

Теперь вы можете получить к ним доступ через глобальную переменную app. (Может быть, лучше передать объект Window или переместить эти функции верхнего уровня в методы Window, которые могут обращаться к нему как self, вместо того, чтобы хранить его как глобальный. Но так как у вас уже есть глобальный в своем текущем дизайне вы можете просто использовать это.)

app.currenttempLabel['text'] = currentTemp

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

t3 = threading.Thread(target=getcurrentTH)

Код, который не выполняется в главном потоке, не может касаться каких-либо виджетов tkinter. В зависимости от вашей платформы это может привести к возникновению исключения, зависанию графического интерфейса, падению или, что хуже всего, работе около 90% времени, но иногда что-то не так.

Есть несколько способов обойти эту проблему. Основной из них описан в этой статье в книге Tkinter : создайте queue.Queue, выполните опрос основного потока q.get_nowait() и вызовите все найденные там функции, а фоновый поток просто q.put функции, а не вызывать их напрямую.

Есть библиотека с именем mttkinter, которая завершает эту технику, но она была для Python 2.3; порт для Python 2.7 выглядит довольно солидно, но для 3.x я знаю только в основном непроверенные и не поддерживаемые вилки, такие как , который я собрал несколько лет назад, потому что ни один из остальных не работал . Поэтому, если вы хотите пойти по этому пути, вам все равно придется понимать, как все работает под одеялом, чтобы вы могли проверить и поддерживать его самостоятельно.

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