如何实时更新PySimpleGUI中的文本?

3

我想编写一个程序,读取我的Arduino的串行信息,并实时在GUI中显示。问题是我不知道如何使数据实现实时更新。

这是我当前的代码:

import re
import serial
import PySimpleGUI as sg

class InterfaceGrafica:
    def __init__(self):
        layout = [[sg.Text('Interface gráfica para o controle do secador.')],
                  [sg.Text('Valor do controle PWM:'), sg.Text(Dados().pwm, key = 'pwm')],
                  [sg.Text('Valor da temperatura: '), sg.Text(Dados().temp, key = 'temp')],
                  [sg.Text('Peso: '), sg.Text(Dados().peso, key = 'peso')],
                  [sg.Text('Valor da umidade: '), sg.Text(Dados().um, key = 'um')],
                  [sg.Text('Temperatura setpoint: '), sg.Text(Dados().set, key = 'set')],
                  [sg.Button('Exit')]]

        self.janela = sg.Window('Versão final', layout=layout, size=(600, 600))

    def Iniciar(self):
        while True:
            self.event, self.values = self.janela.Read()
            if self.event == sg.WIN_CLOSED or self.event == 'Exit':
                break
            conecao = serial.Serial("COM3", 9600)

            for i in range(20):
                leitura = conecao.readline()
                leiturad = leitura.decode()
                var = re.split(',', leiturad)
                print(leiturad)
                self.janela.Element('pwm').Update(values=var[0])
                janela.Refresh
                self.janela.Element('temp').Update(values=var[1])
                self.janela.Element('peso').Update(values=var[2])
                self.janela.Element('um').Update(values=var[3])
                self.janela.Element('set').Update(values=var[4])

tela = InterfaceGrafica()
tela.Iniciar()

使用多线程从串口读取和获取数据,然后调用 window.write_event_value 生成带有值的事件。在事件循环中处理该事件并更新 sg.Text,例如 self.janela['pwm'].update(value=value) - Jason Yang
2个回答

2
你需要为self.janela.read(timeout = 250)设置超时时间。 我创建了一个虚假的Dados来测试,(你不需要使用),并且它会更新。 https://pysimplegui.readthedocs.io/en/latest/
#! /usr/bin/env python3
##  pip3 install serial pysimplegui
##  Python -m pip install serial pysimplegui

import re
import serial
import random
import PySimpleGUI as sg

class Singleton( object ):
    def __new__( cls ):
        if not hasattr( cls, 'instance' ):
            cls .instance = super( Singleton, cls ) .__new__( cls )
        return cls .instance

Dados = Singleton()

def update():
    print( 'update' )
    Dados .pwm = random .random()
    Dados .temp = f'{ random .randint( 50, 100 ) } *F'
    Dados .peso = f'$ { random .randint( 1, 30 ) }'
    Dados .um = random .randint( 1, 100 )
    Dados .set = random .randint( 1, 100 )


class InterfaceGrafica:
    def __init__(self):
        layout = [ [ sg .Text('Interface gráfica para o controle do secador.') ],
                   [ sg .Text('Valor do controle PWM:'),  sg .Text( Dados .pwm,  key='pwm' ) ],
                   [ sg .Text('Valor da temperatura: '),  sg .Text( Dados .temp,  key='temp' ) ],
                   [ sg .Text('Peso: '),  sg .Text( Dados .peso,  key='peso' ) ],
                   [ sg .Text('Valor da umidade: '),  sg .Text( Dados .um,  key='um' ) ],
                   [ sg .Text('Temperatura setpoint: '),  sg .Text( Dados .set,  key='set' ) ],
                   [ sg .Button('Exit') ] ]

        self.janela = sg.Window( 'Versão final', layout=layout, size=(400, 300) )

        while True:
            self.event, self.values = self.janela.read( timeout=250 )
            if self.event == sg.WIN_CLOSED or self.event == 'Exit':
                break
            '''
            conecao = serial.Serial("COM3", 9600)
            for i in range(20):  leitura = conecao.readline()  ##  read 20 lines from serial

            leiturad = leitura.decode()  ##  decode those 20 lines
            var = re.split(',', leiturad)  ##  split CSV into list
            print(var)
            '''

            self.janela['pwm']( Dados .pwm )  ##  var[ 0 ]
            self.janela['temp']( Dados .temp )  ##  var[ 1 ]
            self.janela['peso']( Dados .peso )  ##  var[ 2 ]
            self.janela['um']( Dados .um )  ##  var[ 3 ]
            self.janela['set']( Dados .set )  ##  var[ 4 ]
            self.janela.Refresh()
            update()

update()
InterfaceGrafica()

0

使用多线程,否则当您的代码在读取串口时被阻塞时,您的GUI将无响应。

以下代码未经过无串口输入测试,因此可能存在拼写错误或其他问题。

import serial   # pip install PySerial
import threading
import PySimpleGUI as sg

class GUI:
    def __init__(self):
        sg.theme('DarkBlue3')
        sg.set_options(font=("Courier New", 16))
        layout = [
            [self.center([[sg.Text('Controller of Dryer', font=("Courier New", 20, 'bold'))]])],
            [sg.Text("")],
            [sg.Text('PWM        '), self.Text('PWM'     )],
            [sg.Text('TEMPERATURE'), self.Text('TEMP'    )],
            [sg.Text('WEIGHT     '), self.Text('WEIGHT'  )],
            [sg.Text('MOISTURE   '), self.Text('MOISTURE')],
            [sg.Text('SETPOINT   '), self.Text('SETPOINT')],
            [sg.Text("")],
            [self.center([[sg.Button('Exit')]])],
        ]
        self.window = sg.Window('Final version', layout=layout, finalize=True)
        self.running = True
        self.com = serial.Serial("COM3", 9600)
        threading.Thread(target=self.get_data, args=(window,), daemon=True).start()
        self.start()

    def center(self, layout):
        return sg.Column(layout, element_justification='center', expand_x=True)

    def Text(self, key):
        return sg.Text('', size=(20, 1), text_color='white', background_color='blue', key=key)

    def get_data(self):
        while self.running:
            data = com.readline().decode().split(",")
            self.window.write_event_value("DATA", data)

    def start(self):
        while True:
            event, values = self.window.read()
            if event in (sg.WIN_CLOSED, 'Exit'):
                break
            elif event == 'DATA':
                data = values[event]
                self.update(data)
        self.running = False
        self.window.close()

    def update(self, data):
        for i, key in enumerate(('PWM', 'TEMP', 'WEIGHT', 'MOISTURE', 'SETPOINT')):
            self.window[key].update(value=data[i])

GUI()

感谢Jason Yang和Doyousketch2的帮助。我已经完成了超时解决方案,它起作用了。 - Pedro Augusto Boller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接