我需要使用以下代码更改Tkinter GUI中的标签:
import os
import multiprocessing
from multiprocessing import Process, Pool
import threading
import queue
import tkinter as tk
from tkinter import *
from tkinter import ttk
from time import time
import minimalmodbus
import serial
minimalmodbus.CLOSE_PORT_AFTER_EACH_CALL = True
THREAD_LOCK = threading.Lock()
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.temp_label = tk.Label(self, text='temp', width=10)
self.temp_label.pack(side="top")
self.connect_button = tk.Button(self, text='Connect', command=self.run_code)
self.connect_button.pack(side="top")
def run_code(self):
all_thread()
def set_result(self, read):
self.temp_label.config(text=read[2])
def all_thread(): #not in class Page1()
thread = threading.Thread(target=all_process)
thread.start()
def all_process():
gas = minimalmodbus.Instrument("COM3", 1)
gas.serial.baudrate = 9600
gas.serial.bytesize = 8
gas.serial.parity = serial.PARITY_NONE
gas.serial.stopbits = 1
gas.serial.timeout = 0.25
gas.mode = minimalmodbus.MODE_RTU
gas_list = [gas]
processes = []
while len(gas_list) > 0:
val = 1
with THREAD_LOCK:
for sen in gas_list:
proc = Process(target=main_reader, args=(sen, val))
processes.append(proc)
proc.start()
val += 1
for sen in processes:
sen.join()
time.sleep(1)
def main_reader(sen, val):
try:
read = sen.read_registers(0,42)
except OSError:
read = "Communication Error"
except ValueError:
read = "RTU Error"
if val == 1:
Page1().set_result(read)
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
p1 = Page1(self)
buttonframe = tk.Frame(self)
container = tk.Frame(self)
buttonframe.pack(side="top", fill="x", expand=False)
container.pack(side="top", fill="both", expand=True)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
b1 = tk.Button(buttonframe, text="Page 1", command=p1.lift)
b1.pack(side="left")
p1.show()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("1000x600")
root.mainloop()
我想将temp_label
的文字更改为read
列表中的第3项。但是,set_result
功能无法正常工作。当数据到达set_result
时,temp_label
中的文字不会更改。我做错了什么?
答案 0 :(得分:0)
至少部分问题是您正在创建一个不可见的新 Page1
。因此,即使您确实更改了值,也不会看到它。
您需要调用p1.set_result
,方法是将p1
设为全局,将p1
设为main
的实例变量,或将其传递给需要它的函数。
即便如此,这也行不通。您不能从创建窗口小部件之外的进程或线程调用tkinter方法。您必须将数据放在其他线程/进程中的队列中,并在GUI线程中轮询队列。