2017-06-22 95 views
0

我需要更改标签,我Tkinter的GUI下面的代码:正确改变Tkinter的标签

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列表。但是,set_result功能无法正常工作。当数据到达set_result时,temp_label中的文本不会更改。我究竟做错了什么?

+0

在你的例子中,没有调用'set_result'函数,因此没有人知道'read'是什么。 – CommonSense

+0

我忘了添加处理那个......我的坏的功能。问题被编辑为包含该函数'main_reader'。 – GreenSaber

+0

你有没有做过任何调试?你是否证实'read'是你认为的? –

回答

0

至少部分问题是您正在创建一个不可见的Page1。所以即使你改变了价值,你也不会看到它。

您必须调用,方法是使p1全球,使得p1main一个实例变量,或者将它传递给需要它的功能。

即使这样,这是行不通的。您不能从创建窗口小部件的进程或线程调用tkinter方法。您必须将数据放在其他线程/进程的队列中,然后在GUI线程中轮询队列。

+0

首先,我认为你已经回答了我所有的Tkinter问题,我想感谢你的帮助和耐心!其次,如果我对代码采取了不同的方式,例如在一个应用程序类下拥有所有进程,线程和函数,这是否可行? – GreenSaber