如何从Python的功能外部更改标签文本



我是编程的新手,我正在尝试使某些内容与显示温度一样简单。在关闭窗口之前,我无法显示温度,它进入了loop get_outside_temp((,但是直到我打破循环后才显示任何内容,然后将绘制窗口。请参阅下面的代码。

 #Import needed files
import tkinter as tk
import sys
import time

#define some variables
green = '#2BF720'
blue='#0CCAF0'
#blue = '#427BED'
font10 = "-family Newspaper -size 18 -weight bold -slant roman -underline 0 -overstrike 0"
font2 = "-family Newspaper -size 36 -weight bold -slant roman -underline 0 -overstrike 0"
#get outside temp and display it
def get_outside_temp():
     while True:
        tfile = open("/sys/bus/w1/devices/28-0416b113e1ff/w1_slave") 
        text = tfile.read() 
        tfile.close() 
        secondline = text.split("n")[1] 
        temperaturedata = secondline.split(" ")[9] 
        outside_temp = float(temperaturedata[2:]) 
        outside_temp = round(outside_temp / 1000 ,1)
        print(outside_temp) #so I can see it's working
        #this is wherre I'm trying to display the temperature in the window.
        outside_temp_label.config(text = outside_temp)
        '''
        outside_temp_label = tk.Label(outside_frame, text=outside_temp, bg="Black", fg='White', font=font2)
        outside_temp_label.grid(padx=140, pady=75)
        '''
        time.sleep(5)

#create main window
root = tk.Tk()
root.geometry("800x480")
root.configure(bg="black")
root.title("Go Nad Go IV")
#create the frame for the outside
outside_frame = tk.Frame(root, height=230, width = 390, bg="black", 
relief="groove", highlightcolor = blue, highlightbackground=blue, highlightthickness = 2)
outside_frame.grid(row=0, column=1, padx=5, pady=5)
outside_frame.grid_propagate(False)
outside_label = tk.Label(outside_frame, text="Outside Temperature", bg="Black", fg=blue, font=font10)
outside_label.grid(column=0,row=0)
#get the outside temp
tfile = open("/sys/bus/w1/devices/28-0416b113e1ff/w1_slave") 
text = tfile.read()
tfile.close() 
secondline = text.split("n")[1] 
temperaturedata = secondline.split(" ")[9] 
outside_temp = float(temperaturedata[2:]) 
outside_temp = round(outside_temp / 1000 ,1)
#display the temp
outside_temp_label = tk.Label(outside_frame, text=outside_temp, bg="Black", fg='White', font=font2)
outside_temp_label.grid(padx=140, pady=75)
get_outside_temp()
root.mainloop()

您的问题不是访问标签,这是您的整个程序在该time.sleep(5)期间无反应次数。因此,您已经更新了内存中的标签,但是它没有在屏幕上重新绘制,因为什么都没有重新绘制。

您无法在GUI计划中睡觉。如果您希望每5秒运行一次,则有三个选择:使用背景线程,手动驱动事件循环,或要求GUI在5秒内再次运行您的代码。

最后一个是迄今为止最简单的。在TKINTER中,它是拼写的after,您会这样使用它:

def get_outside_temp():
    # No while True loop here!
    tfile = open("/sys/bus/w1/devices/28-0416b113e1ff/w1_slave") 
    text = tfile.read() 
    tfile.close() 
    # all your other existing code, except the sleep
    root.after(5000, callback=get_outside_temp)

换句话说,我们的功能不是一个永远运行的函数,一次睡觉5秒,我们的功能非常快,要求在5秒内再次运行,然后返回事件循环,以便其他东西可以运行(例如重新绘制屏幕,响应鼠标等(。

谢谢,我确实设法使它工作。
代替: root.fter(5000,回调= get_outside_temp(我必须使用: root.fter(5000,get_outside_temp(

fix:

import tkinter as tk
import sys
import time

green = '#2BF720'
blue = '#0CCAF0'
font10 = "-family Newspaper -size 18 -weight bold -slant roman -underline 0 -overstrike 0"
font2 = "-family Newspaper -size 36 -weight bold -slant roman -underline 0 -overstrike 0"

def get_outside_temp():
   tfile = open("/sys/bus/w1/devices/28-0416b113e1ff/w1_slave") 
   text = tfile.read() 
   tfile.close() 
   secondline = text.split("n")[1] 
   temperaturedata = secondline.split(" ")[9] 
   outside_temp = float(temperaturedata[2:]) 
   outside_temp = round(outside_temp / 1000 ,1)
   outside_temp_label.config(text = outside_temp)
   
   
   root.after(5000, get_outside_temp)
root = tk.Tk()
root.geometry("800x480")
root.configure(bg="black")
root.title("Go Nad Go IV")
outside_frame = tk.Frame(root, height=230, width=390, bg="black", 
                        relief="groove", highlightcolor=blue, 
                        highlightbackground=blue, highlightthickness=2)
outside_frame.grid(row=0, column=1, padx=5, pady=5)
outside_frame.grid_propagate(False)
outside_label = tk.Label(outside_frame, text="Outside Temperature", bg="Black", fg=blue, font=font10)
outside_label.grid(column=0, row=0)
tfile = open("/sys/bus/w1/devices/28-0416b113e1ff/w1_slave") 
text = tfile.read() 
tfile.close() 
secondline = text.split("n")[1] 
temperaturedata = secondline.split(" ")[9] 
outside_temp = float(temperaturedata[2:]) 
outside_temp = round(outside_temp / 1000 ,1)
outside_temp_label = tk.Label(outside_frame, text=outside_temp, bg="Black", fg='White', font=font2)
outside_temp_label.grid(padx=140, pady=75)
get_outside_temp()
root.mainloop()

问题是因为get_outside_temp() 函数连续循环。结果,tkinter mainloop无法操作和刷新窗口,代码不断提高温度。

之前:

#get outside temp and display it
def get_outside_temp():
   while True:
      tfile = open("/sys/bus/w1/devices/28-0416b113e1ff/w1_slave") 
      text = tfile.read() 
      tfile.close() 
      secondline = text.split("n")[1] 
      temperaturedata = secondline.split(" ")[9] 
      outside_temp = float(temperaturedata[2:]) 
      outside_temp = round(outside_temp / 1000 ,1)
      print(outside_temp) #so I can see it's working
      #this is wherre I'm trying to display the temperature in the window.
      outside_temp_label.config(text = outside_temp)
      '''
      outside_temp_label = tk.Label(outside_frame, text=outside_temp, bg="Black", fg='White', font=font2)
      outside_temp_label.grid(padx=140, pady=75)
      '''
      time.sleep(5)

之后:

def get_outside_temp():
   tfile = open("/sys/bus/w1/devices/28-0416b113e1ff/w1_slave") 
   text = tfile.read() 
   tfile.close() 
   secondline = text.split("n")[1] 
   temperaturedata = secondline.split(" ")[9] 
   outside_temp = float(temperaturedata[2:]) 
   outside_temp = round(outside_temp / 1000 ,1)
   print(outside_temp) #so I can see it's working
   outside_temp_label.config(text = outside_temp)
   
   # run again in 5 seconds
   root.after(5000, get_outside_temp)

替代变体如何做到这一点:

螺纹 -

import tkinter as tk
import threading
import time
def long_running_task():
    time.sleep(5)  # simulating a long task
    root.after(0, update_gui)
def update_gui():
    label.config(text="Task Completed using a Thread!")
root = tk.Tk()
label = tk.Label(root, text="Starting Task...")
label.pack()
thread = threading.Thread(target=long_running_task)
thread.start()
root.mainloop()

事件循环 -

import tkinter as tk
import time
root = tk.Tk()
label = tk.Label(root, text="Starting Task...")
label.pack()
for _ in range(5):
    time.sleep(1)  # simulating work being done over time
    root.update()  # manually driving the event loop
label.config(text="Task Completed by driving the event loop manually!")
root.mainloop()

周期性触发 -

import tkinter as tk
def periodic_task(counter):
    if counter <= 0:
        label.config(text="Task Completed using after!")
    else:
        label.config(text=f"Task running... {counter} seconds left")
        root.after(1000, periodic_task, counter-1)
root = tk.Tk()
label = tk.Label(root, text="Starting Task...")
label.pack()
root.after(1000, periodic_task, 5)  # starting the periodic task
root.mainloop()

最新更新