2017-01-12 6 views
0

PyQt 응용 프로그램을 만들려고합니다. 백그라운드에서 프로세스를 실행하고 PyQt5 애플리케이션을 새로운 지침으로 계속 사용하려면 multiprocessing을 사용하고 싶습니다. Windows OS에서 multiprocessing.process으로 Qt MainWindow 클래스의 함수를 호출 할 때이 클래스를 산 출할 때 오류가 있습니다. 그러나 Linux에서 find를 실행 중입니다.Windows에서 다중 처리를 사용하는 PyQt MainWindow

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 

import sys   
import multiprocessing 

# 
from PyQt5.QtWidgets import * 
from PyQt5.QtGui import * 
from PyQt5.QtCore import * 


class Frame_main(QMainWindow): 

    def __init__(self, parent = None): 
     super(Frame_main, self).__init__(parent) 
     self.thrd_list=[] 
     self.initUI() 

    def initUI(self): 

     # Button 
     btn_run = QPushButton('Run', self)  
     btn_run.clicked.connect(lambda: self.ThdSomething(self.DoRun)) # 
     btn_stop = QPushButton('Stop', self)  
     btn_stop.clicked.connect(self.DoStop)  


     ### TEXT Edit  
     self.textEdit_term = QTextEdit("terminal: \n ") 
     self.textEdit_term.append("") 
     self.textEdit_term.setStyleSheet("color: rgb(255, 255, 255); background-color: black;") 
     self.textEdit_term.setLineWrapMode(QTextEdit.NoWrap) 
     self.textEdit_term.setToolTip(' terminal message ') 
     self.textEdit_term.setStatusTip('textEdit1') 

     ### LAYOUT 
     Wid_main = QWidget()     # 
     grid_major = QGridLayout()    # 
     grid_major.addWidget(btn_run, 1, 5) 
     grid_major.addWidget(btn_stop, 2, 5) 
     Wid_main.setLayout(grid_major) 

     self.setCentralWidget(Wid_main) 

     ### Affichage 
     self.show()     # 

    # 
    def DoRun(self): 
     print('g starts') 
     time_start=time.time() 
     time_stop=time.time() 
     name='bob' 
     n=0 
     while time_stop-time_start <2 : 
      n+=1 
      time_stop=time.time() 
      time.sleep(0.8) 
      print ('hola', name,n, flush=True) 
     print('g stops') 

    def DoStop(self): 
     ''' subourtine kill all the thread ''' 
     print('stop action detected') 
     while len(self.thrd_list) > 0 : 
      print("Terminating the job: {}".format(self.thrd[-1].pid)) 
      os.kill(self.thrd[-1].pid, signal.SIGTERM) 
      self.thrd_list[-1].terminate() 

      self.thrd_list.pop() 


    def ThdSomething(self, job): 
     ''' subourtine to create a new thread to do the job subroutine ''' 
     arg='' 
     p=multiprocessing.Process(target=job, args=(arg)) 
     self.thrd_list.append(p) 
     p.start() 
     print("Start the job GUI: {} with PID: {}".format(str(job) ,self.thrd[-1].pid), file=sys.stdout) 


    def closeEvent(self, event): 
     ''' subroutine to define what happen when closing the main frame''' 
     self.statusBar().showMessage('waiting for a respond') 
     reply = QMessageBox.question(self, 'Message', 
      "Are you sure to quit?", QMessageBox.Yes | 
      QMessageBox.No, QMessageBox.No) 
     if reply == QMessageBox.Yes: 
      event.accept() 
     else: 
      event.ignore() 


# Main 
if __name__ == '__main__': 
    # Create QApplication and Main Frame 
    Qapp = QApplication(sys.argv) # creation de lappli Qt 
    Qapp.setStyle("fusion")   # 
    frame1 = Frame_main()   # 

    sys.exit(Qapp.exec_())   # 

편집 : 내가 좋아하는 몇 가지 유사한 사례를 발견

: Python: multiprocessing in pyqt application 하지만 그들 중 누구도 도움이되지 여기

은 예입니다. 제 사례가 MainWindow 클래스의 함수와 속성을 사용하고 있다는 사실과 관련이있을 수 있습니다.

+0

무엇이 오류입니까? – eyllanesc

+0

@eyllanesc 첫 번째 오류는'TypeError : Frame_main 개체를 제거 할 수 없습니다 '이고 두 번째는'file "E : ... \ Python36 \ lib \ multiprocessing \ reduction.py", 줄 87, steal_handle _winapi .DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE) PermissionError : [WinError 5] Acces refused' –

+0

작성한 답변을 수정하십시오. – eyllanesc

답변

2

GUI 클래스 내에서 메소드를 포크하려고 시도한 것이 맞습니다. 불행히도 Windows는 실제로 리눅스가하는 것처럼 프로세스를 포크하는 기능이 없기 때문에 코드가 리눅스가 아닌 윈도우에서 작동합니다. Python 3 documentation for the multiprocessing library에는 차이점에 대한 유용한 정보와 새 프로세스를 시작하기위한 기본 방법이 다른 플랫폼에서 수행되는 것에 대한 유용한 정보가 있습니다.

질문에 대답하기 : 대상이 GUI 개체와 관련된 메서드이기 때문에 개체 상태를 새 프로세스로 보내야하지만 PyQt GUI 개체가 피클링하기에 너무 복잡하기 때문에 피클링을 수행하지 못합니다.

코드를 다시 작성하여 대상 기능 (및 args이 지정됨)을 picklable로 작성하면 코드가 작동합니다.

관련 문제