Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Thread/Signal
#1
Hey All

I m trying to update a textbox with signals from a thread. But I am unable to wrap my head around the business of signals.

Here is what I have so far:
Main function
ThreadSignal.py
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.QtCore import pyqtSignal
from ThreadSignalUI import Ui_MainWindow
from threading import Thread

import sys
import time

class WorkThread(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.stop_work_thread = 0
        self.start()
        self.val = 0

    def run(self):
        runningval = 0
        UpdateTextBoxSignal = pyqtSignal()
        while runningval < 10:
            runningval += 1
            self.UpdateTextBoxSignal.emit(runningval)
            time.sleep(0.5)

        
class ThreadSignal(Ui_MainWindow):

    def __init__(self, Application):
        Ui_MainWindow.__init__(self)
        self.setupUi(Application)
        
        self.StartButt.clicked.connect(self.StartThreading)
    
    def StartThreading(self, event):
        self.work = WorkThread()
        self.UpdateTextBoxSignal.connect(UpdateTextBoxFunction)
        
def UpdateTextBoxFunction(self):
    self.TextBox.setText(str(runningval))

app = 0   
app = QApplication(sys.argv)
Application = QDialog()
Program = ThreadSignal(Application)
Application.show()
app.exec_()
ThreadSignalUI.py
from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(269, 232)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.TextBox = QtWidgets.QLineEdit(self.centralwidget)
        self.TextBox.setGeometry(QtCore.QRect(74, 40, 113, 20))
        self.TextBox.setObjectName("TextBox")
        self.StartButt = QtWidgets.QPushButton(self.centralwidget)
        self.StartButt.setGeometry(QtCore.QRect(94, 72, 75, 23))
        self.StartButt.setObjectName("StartButt")
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.StartButt.setText(_translate("MainWindow", "Start"))
I followed a couple of tutorials to get to this point, but still unable to get a working program.
Reply
#2
Here is a simple example of signals and threading in PyQt5:

#!/usr/bin/python3
# Threading example with QThread and moveToThread (PyQt5)
import sys
import time
from PyQt5 import QtWidgets, QtCore

class WorkerThread(QtCore.QObject):
    signalExample = QtCore.pyqtSignal(str, int)

    def __init__(self):
        super().__init__()

    @QtCore.pyqtSlot()
    def run(self):
        while True:
            # Long running task ...
            self.signalExample.emit("leet", 1337)
            time.sleep(5)

class Main(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.worker = WorkerThread()
        self.workerThread = QtCore.QThread()  # Move the Worker object to the Thread object
        self.workerThread.started.connect(self.worker.run)  # Init worker run() at startup (optional)
        self.worker.signalExample.connect(self.signalExample)  # Connect your signals/slots
        self.worker.moveToThread(self.workerThread)
        self.workerThread.start()

    def signalExample(self, text, number):
        print(text)
        print(number)

if __name__== '__main__':
    app = QtWidgets.QApplication([])
    gui = Main()
    sys.exit(app.exec_())
Reply
#3
Thank you very much Alfalfa.

I was able to use your code to finally get mine to work.
Your example was so simple and straight forward with no ambiguity. Thank you again.

For the sake of completeness, here is a working version of the problem I posted in the beginning

from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5 import QtCore
from ThreadSignalUI import Ui_MainWindow

import sys
import time

class WorkThread(QtCore.QObject):
    UpdateTextBoxSignal = QtCore.pyqtSignal(int)
    
    def __init__(self):
        super().__init__()
    
    @QtCore.pyqtSlot()
    def run(self):
        runningval = 0
        
        while runningval < 10:
            runningval += 1
            self.UpdateTextBoxSignal.emit(runningval)
            time.sleep(0.5)

        
class ThreadSignal(Ui_MainWindow):

    def __init__(self, Application):
        Ui_MainWindow.__init__(self)
        self.setupUi(Application)
        
        self.worker = WorkThread()
        self.workerThread = QtCore.QThread()
        self.workerThread.started.connect(self.worker.run)
        self.worker.moveToThread(self.workerThread)
        self.worker.UpdateTextBoxSignal.connect(self.UpdateTextBoxFunction)
    
        self.StartButt.clicked.connect(self.StartThreading)
        
    def StartThreading(self, event):
        self.workerThread.start()
        
    def UpdateTextBoxFunction(self, value):
        self.TextBox.setText(str(value))

app = 0   
app = QApplication(sys.argv)
Application = QDialog()
Program = ThreadSignal(Application)
Application.show()
app.exec_()
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020