Почему данный код многопоточного приложения не работает? (Используется PyQt, MoveToThread)
Подскажите почему данный код не работает и не вывод ничего в консоль? Видимо я ещё недостаточно силен в многопоточности. Если есть советы по написанию кода, то буду рад поучиться.
main.pyw
from design import MainWindow
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QObject, QThread
import sys
import algorithm
class AlgThread(QObject):
def __init__(self, font_name, lang, save_path, open_):
super(AlgThread, self).__init__()
self.font_name = font_name
self.lang = lang
self.save_path = save_path
self.open_ = open_
def run(self):
algorithm.make_prescription(self.font_name, self.lang, self.save_path, self.open_)
def saving(font_name, lang, save_path, open_):
thread = QThread(window)
alg = AlgThread(font_name, lang, save_path, open_)
alg.moveToThread(thread)
thread.started.connect(alg.run)
thread.start()
app = QApplication(sys.argv)
window = MainWindow()
window.saving_sgl.connect(saving)
window.show()
sys.exit(app.exec_())
design.py
from PyQt5 import QtWidgets, QtCore
class MainWindow(QtWidgets.QWidget):
saving_sgl = QtCore.pyqtSignal(str, str, str, bool)
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.resize(200, 150)
self.btn = QtWidgets.QPushButton('Отправить')
vbox = QtWidgets.QVBoxLayout()
vbox.addWidget(self.btn)
self.setLayout(vbox)
self.btn.clicked.connect(self.creating_file)
def creating_file(self):
f, t, p, o = 'hello', 'my', 'friend', True # Эти переменные берут данные из сторонних источников
self.saving_sgl.emit(f, t, p, o)
algorithm.py
def make_prescription(font_name, lang, save_path, open_):
print(font_name, lang, save_path, open_)
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Я немного изменил ваш код и прокомментировал его:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
from PyQt5.QtCore import QObject, QThread, pyqtSignal
#import algorithm
def make_prescription(font_name, lang, save_path, open_):
print(f'\n def make_prescription: {font_name}, {lang}, {save_path}, {open_}')
return [font_name, lang, save_path, open_] # +++
class AlgThread(QObject):
def __init__(self): # - , font_name, lang, save_path, open_):
super(AlgThread, self).__init__()
self.font_name = ''
self.lang = ''
self.save_path = ''
self.open_ = False
def run(self):
while True:
if self.open_: # если условный `self.open_` истина, то сделаем какие-то действия
#algorithm.make_prescription(self.font_name, self.lang, self.save_path, self.open_)
# для теста сделал паузу, как-будто запрос выполняется 2 сек
QThread.msleep(2000) # (уберите)
rez = make_prescription(self.font_name, self.lang, self.save_path, self.open_)
# возможно вам понадобится передавать `rez` в основной поток (сигналы и слоты)
self.open_ = False # запрос выполнен и мы отключились. Ждем следующего клика.
QThread.msleep(100)
class MainWindow(QWidget):
saving_sgl = pyqtSignal(str, str, str, bool)
def __init__(self):
super().__init__()
self.btn = QPushButton('Отправить')
self.btn.clicked.connect(self.creating_file)
vbox = QVBoxLayout(self)
vbox.addWidget(self.btn)
self.saving_sgl.connect(self.saving)
# формируем и запускает дополнительный поток,
# который все время в работе,
# но запрос в нем будет выполняться только по клику
# и при передачей условной переменной `open_ = True`
self.thread = QThread()
self.alg = AlgThread()
self.alg.moveToThread(self.thread)
self.thread.started.connect(self.alg.run)
self.thread.start()
def creating_file(self):
# Эти переменные берут данные из сторонних источников
f, t, p, o = 'hello', 'my', 'friend', True
self.saving_sgl.emit(f, t, p, o)
def saving(self, font_name, lang, save_path, open_):
self.alg.font_name = font_name
self.alg.lang = lang
self.alg.save_path = save_path
self.alg.open_ = open_
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.resize(200, 150)
window.show()
sys.exit(app.exec_())
