실험 설정을위한 PyQt GUI를 만들고 있습니다. 이것은 연산이 많은 연산을 포함하므로 멀티 프로세싱 모듈을 기반으로 한 아키텍처를 목표로하고 this answer에서 영감을 얻은 것입니다.임의의 서명으로 새로운 스타일의 PyQt 신호를 내 보냅니다.
QMainWindow는 메인 프로세스에 지침을 다시 보내 주 과정 및 공유 "콜백"대기열에서 지침을 얻을 수있는 개인 "작업"큐와
- 자식 프로세스를 생성
- QThread에 은 "콜백"큐를 폴링 예는 임의 시그너처
self.emit(QtCore.SIGNAL(signature), args)
오래 스타일 신호를 사용 QMainWindow
의 슬롯에 접속되는 신호들로 메시지를 번역. 내 질문 :이 기능을 새로운 스타일의 신호로 복제 할 수 있습니까?
나는 this question과 this one을 알고 있습니다. 그러나 일반 객체로 항상 valueChanged
신호를 내보내는 것은 자식 프로세스 중 하나에서받은 서명에 따라 다른 이름의 슬롯에 연결하려는 것이므로 내 필요에 맞지 않습니다. 여기
from multiprocessing import Process, Queue
import sys
from PyQt4 import QtGui, QtCore
class CallbackQueueToSignal(QtCore.QThread):
def __init__(self, queue, parent=None):
super(CallbackQueueToSignal, self).__init__(parent)
self.queue = queue
def _emit(self, signature, args=None):
if args:
self.emit(QtCore.SIGNAL(signature), args)
else:
self.emit(QtCore.SIGNAL(signature))
def run(self):
while True:
signature = self.queue.get()
self._emit(*signature)
class WorkerProcess(Process):
def __init__(self, callback_queue, task_queue, daemon=True):
super(WorkerProcess, self).__init__()
self.daemon = daemon
self.callback_queue = callback_queue
self.task_queue = task_queue
def _process_call(self, func_name, args=None):
func = getattr(self, func_name)
if args:
func(args)
else:
func()
def emit_to_mother(self, signature, args=None):
signature = (signature,)
if args:
signature += (args,)
self.callback_queue.put(signature)
def run(self):
while True:
call = self.task_queue.get()
# print("received: {}".format(call))
self._process_call(*call)
def text_upper(self, text):
self.emit_to_mother('data(PyQt_PyObject)', (text.upper(),))
class MainWin(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWin, self).__init__(parent)
self.data_to_child = Queue()
self.callback_queue = Queue()
self.callback_queue_watcher = CallbackQueueToSignal(self.callback_queue)
self.callback_queue_watcher.start()
self.child = WorkerProcess(self.callback_queue, self.data_to_child)
self.child.start()
self.browser = QtGui.QTextBrowser()
self.lineedit = QtGui.QLineEdit('Type text and press <Enter>')
self.lineedit.selectAll()
layout = QtGui.QVBoxLayout()
layout.addWidget(self.browser)
layout.addWidget(self.lineedit)
self.layout_widget = QtGui.QWidget()
self.layout_widget.setLayout(layout)
self.setCentralWidget(self.layout_widget)
self.lineedit.setFocus()
self.setWindowTitle('Upper')
self.connect(self.lineedit, QtCore.SIGNAL('returnPressed()'), self.to_child)
self.connect(self.callback_queue_watcher, QtCore.SIGNAL('data(PyQt_PyObject)'), self.updateUI)
def to_child(self):
self.data_to_child.put(("text_upper",) + (self.lineedit.text(),))
self.lineedit.clear()
def updateUI(self, text):
text = text[0]
self.browser.append(text)
def closeEvent(self, event):
result = QtGui.QMessageBox.question(
self,
"Confirm Exit...",
"Are you sure you want to exit ?",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
event.ignore()
if result == QtGui.QMessageBox.Yes:
# self.pipeWatcher.exit()
self.child.terminate()
event.accept()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
form = MainWin()
form.show()
app.aboutToQuit.connect(app.deleteLater)
sys.exit(app.exec_())
왜 연결이 서명에 의존해야합니까? 연결된 질문에서 제안 된대로 하나의 미리 정의 된 신호를 사용하고 식별자를 첫 번째 매개 변수로 보냅니다. – ekhumoro
그런 경우 신호 사용의 이점을 상실하게됩니다. 예를 들어 프로그램을 실행하는 동안 특정 신호를 특정 슬롯에 연결하거나 연결 해제 할 수 없습니다. 하지만 내가 너의 요점을 놓치고 있을까? –
새로운 스타일의 신호로 동적으로 방출되는 사용자 정의 신호를 복제하는 방법은 없습니다. 맞춤 신호는 클래스 속성으로 미리 정의해야합니다. 그러나 런타임시 신호 연결 및 연결 해제에 영향을 줄 수있는 이유는 없습니다. 또한 이것이 실제 질문과 어떻게 관련되는지 보지 못합니다. 코드 예제가 신호를 끊지 않습니다. – ekhumoro