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

How do I update the text in PySimpleGUI in real time?

我正在尝试制作一个程序来读取我的 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()

您需要为 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()

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

以下代码未针对无 com 端口输入进行测试,因此某处可能出现拼写错误或其他错误。

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()