user77177928
user77177928

Reputation: 465

Pyqt5 GUI Still Hangs When Using Thread

I'm new to python and pyqt. I'm learning how to use threading with GUI.

I followed this tutorial http://www.xyzlang.com/python/PyQT5/pyqt_multithreading.html

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
import threading
from _ast import While

class Communicate(QObject):
    signal = pyqtSignal(int, str)

class My_Gui(QWidget):
    def __init__(self):
        super().__init__()

        self.comm = Communicate()
        self.comm.signal.connect(self.append_data)
        self.initUI()

    def initUI(self):

        btn_count = QPushButton('Count')
        btn_count.clicked.connect(self.start_counting)
        self.te = QTextEdit()

        vbox = QVBoxLayout()
        vbox.addWidget(btn_count)
        vbox.addWidget(self.te)

        self.setLayout(vbox)
        self.setWindowTitle('MultiThreading in PyQT5')
        self.setGeometry(400, 400, 400, 400)
        self.show()

    def count(self, comm):
        '''
        for i in range(10):
            data = "Data "+str(i)
            comm.signal.emit(i, data)
        '''
        i = 0
        while True:
            data = "Data "+str(i)
            comm.signal.emit(i, data)
            i+=1

    def start_counting(self):
        my_Thread = threading.Thread(target=self.count, args=(self.comm,))
        my_Thread.start()

    def append_data(self, num, data):
        self.te.append(str(num) + " " + data)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    my_gui = My_Gui()
    sys.exit(app.exec_())

I changed the for loop to infinite while loop(incrementing the 'i').

If I execute the program, the GUI still hangs but if I remove the emit signal inside the loop, it no longer hangs.

Are there some tricks to make it not hangs?

Upvotes: 2

Views: 1371

Answers (2)

NCJ
NCJ

Reputation: 21

while True makes an endless loop in the background

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
import threading
from _ast import While

class Communicate(QObject):
    signal = pyqtSignal(int, str)

class My_Gui(QWidget):
    def __init__(self):
        super().__init__()

        self.comm = Communicate()
        self.comm.signal.connect(self.append_data)
        self.initUI()

    def initUI(self):

        btn_count = QPushButton('Count')
        btn_count.clicked.connect(self.start_counting)
        self.te = QTextEdit()

        vbox = QVBoxLayout()
        vbox.addWidget(btn_count)
        vbox.addWidget(self.te)

        self.setLayout(vbox)
        self.setWindowTitle('MultiThreading in PyQT5')
        self.setGeometry(400, 400, 400, 400)
        self.show()

    def count(self, comm):
        for i in range(10):
            data = "Data "+str(i)
            comm.signal.emit(i, data)
        # While True below will never stop and cause your program to stuck
        '''
        i = 0
        while True:
            data = "Data "+str(i)
            comm.signal.emit(i, data)
            i+=1
        '''

    def start_counting(self):
        my_Thread = threading.Thread(target=self.count, args=(self.comm,))
        my_Thread.start()

    def append_data(self, num, data):
        self.te.append(str(num) + " " + data)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    my_gui = My_Gui()
    sys.exit(app.exec_())

Upvotes: 2

Patrick K.
Patrick K.

Reputation: 14

I think you are getting downvoted for two things:

  1. you did only copy and paste the code from the tutorial
  2. you didn't read the tutorial

In the tutorial, the author states:

In the above example, we have created a QPushbutton and QTextEdit. When the button is clicked it creates a new Thread that counts from 0 to 9 and emits the signal in order to append the number and data in the QTextEdit. In class Communicate signal is initialized as pyqtSignal(int, str). This int and str means when a signal will be emitted it will also pass two arguments the first one will be of Integer type and second one will be of String type.

By changing the loop to while true you continuosly emit signals and append the text in the QTextEdit. Probably not what you want. Also commenting the emit statement internally continues to run the while loop.

Upvotes: 0

Related Questions