Привет стек переполнение Python Hive Mind,
Я создал комплекс PyQt5 UI
, который имеет несколько потоков, которые взаимодействуют с небольшим количеством аппаратного обеспечения. Обилие большого количества данных (в конечном счете, с некоторой графикой в пользовательском интерфейсе) и некоторая синхронизация между потоками с использованием q's
, Pipes
, Events
и pyqtsignals
. Все хорошо, все хорошо, luvly. Есть желание удалить QThread
и перейти на многопроцессорность, чтобы пользовательский интерфейс можно было отключить. Все на самом деле вполне разумно и сделано за исключением незначительной проблемы pyqtsignal
.
Многопроцессорная Процесс (ранее QThread
) выполняет from PyQt5.QtCore import pyqtSignal
и в какая-то точка будет излучать сигнал. Если сигнал передается процессу через __init__
, код выполняет __init__
, но в момент запуска процесса он падает с этой ошибкой:
" TypeError: PyQt5.QtCore.pyqtBoundSignal"object" не может выбрать "." но преимущество сигнала заключается в асинхронной природе и простоте connect
для службы f()
. Это также работает как в пользовательском, так и в не-пользовательском интерфейсе без проблем.
Интересно, если вы запустите пример Process с run()
вместо start()
он работает (см. Пример), но я знаю по горькому опыту, что это отрицательно влияет на синхронизацию процессов, что вызвало у меня стресс отладки на несколько недель.
Боюсь, что мне не хватает очевидный трюк - можете ли вы избавить меня от моих страданий?!?
фрагмент кода предполагает [MainWindow
с pushbuttons
для выхода (pb_exit)
и on_start (pb_start)
python v3.8 и PyQt5 v5.13.2 Windows 10] * 105 1 *
from PyQt5.QtCore import pyqtSignal
from multiprocessing import Process
class CTest(Process):
def __init__(self, signal):
name = 'Process'
super().__init__(name=name)
self.signal = signal
# End of __init__
def run(self):
time.sleep(5)
self.signal.emit(99)
# End of run
class MainWindow(QMainWindow, Ui_FQPositioner):
# signal to be passed to QThread but now to Process
signal = pyqtSignal(int)
def __init__(self, app):
super(MainWindow, self).__init__()
self.setupUi(self)
self.pb_exit.clicked.connect(self.closeEvent)
self.pb_start.clicked.connect(self.on_start)
self.signal.connect(self.on_position)
self.test = CTest(self.signal)
self.show()
# end of __init__
def on_start(self):
# start the service processes
self.test.start()
# self.test.run()
# end of on_position
def on_position(self,sig):
disp_text = 'signal ({})'.format(sig)
print(disp_text)
# end of on_position
def closeEvent(self, event):
QApplication.quit()
# End of closeEvent
def main():
# run the app
app = QApplication([]) # A new instance of QApplication
fqApp = MainWindow(app)
fqApp.show() # Show the form
app.exec_() # and execute the app
if __name__ == '__main__':
sys.exit(main())