Потоки в PyQt5, Qthread

В программе есть два потока, которые по очереди должны отображать свои значения на LCD дисплей, но отображаются данные только второго потока.

Нужно чтобы первый поток отображал float, а второй int.

from PyQt5 import QtCore, QtWidgets, QtGui
import sys

class FirstThread(QtCore.QThread):
    first_thread_signal = QtCore.pyqtSignal(float)
    first_done_signal = QtCore.pyqtSignal()
    def __init__(self):
        super().__init__()
        self.flag = True
        self.done = True
        self.num = 8

    def run(self):
        while self.num < 24 and self.flag:
            if self.done:
                self.first_thread_signal.emit(self.counter(self.num))
                self.num += 1
                self.first_done_signal.emit()
                self.msleep(1000)
            else:
                pass         

    def counter(self, num):
        self.count = 0
        while num > 0:
            self.count += (2 * num - 1) / 2 ** num
            num -= 1
        return float('{0:.3f}'.format(self.count))

class SecondThread(QtCore.QThread):
    second_thread_signal = QtCore.pyqtSignal(int)
    second_done_signal = QtCore.pyqtSignal()
    def __init__(self):
        super().__init__()
        self.flag = True
        self.done = False
        self.num = 51

    def run(self):
        while self.num < 67 and self.flag:
            if self.done:
                self.second_thread_signal.emit(self.counter(self.num))
                self.num += 1
                self.second_done_signal.emit()
                self.msleep(1000)
            else:
                pass

    def counter(self, num):
        return num // 5

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(400, 200)
        self.centralwidget = QtWidgets.QWidget()
        self.lcdNumber = QtWidgets.QLCDNumber(self.centralwidget)
        self.lcdNumber.setGeometry(QtCore.QRect(60, 50, 270, 60))
        self.start = QtWidgets.QPushButton(self.centralwidget)
        self.start.setGeometry(QtCore.QRect(70, 150, 90, 30))
        self.start.setText("Старт")
        self.stop = QtWidgets.QPushButton(self.centralwidget)
        self.stop.setGeometry(QtCore.QRect(230, 150, 90, 30))
        self.stop.setText("Стоп")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(170, 20, 90, 20))
        self.setCentralWidget(self.centralwidget)
        #first thread
        self.first_thread = FirstThread()
        self.first_thread.first_thread_signal.connect(self.first_lcd)
        self.first_thread.first_done_signal.connect(self.first_thread_done)
        #second thread
        self.second_thread = SecondThread()
        self.second_thread.second_thread_signal.connect(self.second_lcd)
        self.second_thread.second_done_signal.connect(self.second_thread_done)

        self.start.clicked.connect(self.launch_threads)
        self.stop.clicked.connect(self.stop_threads)

    def first_thread_done(self):
        self.first_thread.done = False
        self.second_thread.done = True

    def second_thread_done(self):
        self.first_thread.done = True
        self.second_thread.done = False

    def first_lcd(self, value):
        self.label.setText("Первый поток")
        self.lcdNumber.display(value)

    def second_lcd(self, value):
        self.label.setText("Второй поток")
        self.lcdNumber.display(value)

    def launch_threads(self):
        self.first_thread.flag = True
        self.second_thread.flag = True
        self.first_thread.done = True
        self.second_thread.done = False
        self.first_thread.start()
        self.second_thread.start()

    def stop_threads(self):
        self.first_thread.flag = False
        self.second_thread.flag = False

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = Window()
    main_window.show()
    sys.exit(app.exec_())

Ответы (1 шт):

Автор решения: S. Nick

я увидел вашу задачу так:

import sys
from PyQt5 import QtCore, QtWidgets, QtGui


class FirstThread(QtCore.QThread):
    first_thread_signal = QtCore.pyqtSignal(float)

    def __init__(self):
        super().__init__()
        self.flag = True         
        self.done = False        
        self.num = 8

    def run(self):
        while self.num < 24 and self.flag:
            self.done, self.flag = self.done_update()
            if self.done:
                self.first_thread_signal.emit(self.counter(self.num))
                self.num += 1
                self.done = False
            self.msleep(10)

    def done_update(self):
        return self.done, self.flag

    def counter(self, num):
        count = 0
        while num > 0:
            count += (2 * num - 1) / 2 ** num
            num -= 1
        return float('{0:.3f}'.format(count))


class SecondThread(QtCore.QThread):
    second_thread_signal = QtCore.pyqtSignal(int)
    second_finished = QtCore.pyqtSignal()

    def __init__(self):
        super().__init__()
        self.flag = True   
        self.done = False  
        self.num = 51

    def run(self):
        while self.num < 67 and self.flag:
            self.done, self.flag = self.done_update()
            if self.done:
                self.second_thread_signal.emit(self.counter(self.num))
                self.num += 1
                self.done = False
            self.msleep(10)
        self.second_finished.emit()

    def done_update(self):
        return self.done, self.flag

    def counter(self, num):
        return num // 5


class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(400, 200)
        self.centralwidget = QtWidgets.QWidget()
        self.lcdNumber = QtWidgets.QLCDNumber(self.centralwidget)
        self.lcdNumber.setGeometry(QtCore.QRect(60, 50, 270, 60))
        self.start = QtWidgets.QPushButton(self.centralwidget)
        self.start.setGeometry(QtCore.QRect(150, 150, 90, 30))
        self.start.setText("Start")
        self.start.clicked.connect(self.start_stop_func)
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(170, 20, 90, 20))
        self.setCentralWidget(self.centralwidget)

        #first thread
        self.first_thread = FirstThread()
        self.first_thread.first_thread_signal.connect(self.first_lcd)

        #second thread
        self.second_thread = SecondThread()
        self.second_thread.second_thread_signal.connect(self.second_lcd)
        self.second_thread.second_finished.connect(self.finished_func)

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.update_func)
        self.timer_flag = True

    def finished_func(self): 
        self.start.setText('Start')
        self.timer.stop()           

    def start_stop_func(self):                      
        if not self.timer.isActive():
            self.start.setText('Stop')
            self.first_thread.num = 8
            self.first_thread.flag = True
            self.first_thread.start()
            self.second_thread.num = 51
            self.second_thread.start() 
            self.second_thread.flag = True            
            self.timer.start(1000)
        else:
            self.start.setText('Start')
            self.timer.stop()    
            self.first_thread.flag = False
            self.second_thread.flag = False

    def update_func(self):
        if self.timer_flag:
            self.first_thread.done = True
            self.second_thread.done = False 
        else:
            self.first_thread.done = False
            self.second_thread.done = True             
        self.timer_flag = not self.timer_flag

    def first_lcd(self, value):
        # print(f'def first_lcd(self, value): {value}')
        self.label.setText("Первый поток")
        self.lcdNumber.display(value)

    def second_lcd(self, value):
        # print(f'def second_lcd(self, value): {value}')
        self.label.setText("Второй поток")
        self.lcdNumber.display(value)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = Window()
    main_window.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка