Foros Python

Versión completa: Modificar variables desde un hilo(thread) diferente
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Hola amigos, necesito ayuda, estoy aprendiendo a trabajar con visual python, en este momento estoy usando pyQT, pero mi pregunta radica en el uso de hilos.

Mi aplicación recibe datos de un dispositivo todo el tiempo a través del protocolo Modbus, y esto se hace en un hilo diferente al programa principal de la aplicación visual, es decir, el problema está que desde ese hilo no puedo modificar ninguna variable del programa principal o variable global.

Resumiendo, necesito desde el hilo Rx_Thread (), recibir un dato y mostrarlo en un textEdit del programa principal.

Código:
from PyQt5 import QtWidgets
from Test_ui import Ui_MainWindow
import sys
from pyModbusTCP.client import ModbusClient
import time, threading

c=ModbusClient(host="127.0.0.1", port=502, auto_open=True)
text = "Hola"

class Main (QtWidgets.QMainWindow):
     def __init__(self):
         super (Main, self).__init__()
         self.ui = Ui_MainWindow()
         self.ui.setupUi (self)

     def Rx_Thread (): #este es el hilo que recibe los datos
         while (True):
             reg = c.read_holding_registers(0, 5)
             time.sleep(1)
         if reg:
             #self.ui.textEdit.setPlainText("%s
" % text) #esto es lo que quiero modificar
             print(reg)
         else:
             print("not")

     _thread = threading.Thread(name='Rx_Thread',target=Rx_Thread, daemon = True)
     _thread.start()


if __name__ == '__main__':
     app=QtWidgets.QApplication([])
     main_app = Main()
     main_app.show()
     sys.exit(app.exec())
Hola, bienvenido!

Qt tiene una API para hilos similar a la de Python, y un sistema de señales para comunicarse entre diversos hilos. Te dejo un ejemplo de cómo se usa que vas a poder adaptar a tu código:

Código:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel


class MyThread(QThread):
    
    countChanged = pyqtSignal(int)

    def run(self):
        count = 1
        while True:
            self.countChanged.emit(count)
            count += 1
            time.sleep(1)


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("Ejemplo de QThread")
        self.resize(400, 300)
        self.label = QLabel("Cuenta: 0", self)
        self.label.setGeometry(20, 20, 200, 25)
        
        self.thread = MyThread()
        self.thread.countChanged.connect(self.countChanged)
        self.thread.start()
    
    def countChanged(self, count):
        self.label.setText(f"Cuenta: {count}")


if __name__ == "__main__":
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()

Este programa inicializa un hilo que cada un segundo aumenta un contador y actualiza el texto de una etiqueta (QLabel). El contador se actualiza en el hilo (clase MyThread), pero emite una señal (countChanged) a la cual el hilo principal (clase MainWindow) conecta la función MainWindow.countChanged(), que es llamada cada vez que se recibe esa señal, y ahí se hace la actualización del texto de la etiqueta. En términos más simples: el hilo MyThread emite la señal countChanged que es recibida en el hilo principal MainWindow.

En el ejemplo la señal (MyThread.countChanged) y la función que recibe esa señal (MainWindow.countChanged) tienen el mismo nombre, pero eso no es para nada necesario. Le podés dar el nombre que quieras tanto a tu señal (en tu caso sería algo así como "registerChanged" o no sé qué dato estás leyendo) como a tu función.

Saludos
Muchas Gracias Francisco me fue de mucha ayuda y ya me funciona a la perfección. Saludos