正确更改Tkinter标签

时间:2017-06-22 14:11:35

标签: python tkinter

我需要使用以下代码更改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中的文字不会更改。我做错了什么?

1 个答案:

答案 0 :(得分:0)

至少部分问题是您正在创建一个不可见的 Page1。因此,即使您确实更改了值,也不会看到它。

您需要调用p1.set_result,方法是将p1设为全局,将p1设为main的实例变量,或将其传递给需要它的函数。

即便如此,这也行不通。您不能从创建窗口小部件之外的进程或线程调用tkinter方法。您必须将数据放在其他线程/进程中的队列中,并在GUI线程中轮询队列。