Потоки в 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_())
