2017-04-14 43 views
0

如果我運行下面的thread_test.py代碼,我的線程函數運行良好。但是,如果我用cx_Freeze編譯它,那麼它會掛起對glob的調用。它沒有給出錯誤,並且gui保持響應,但該線程似乎掛起(不做任何事)。我測試了除glob之外的其他幾個函數,所以glob本身是而不是的問題。我嘗試從多處理中添加freeze_support,儘管我沒有使用多處理,但這沒有幫助。有什麼可能導致這種情況的想法嗎?它可能與使用Anaconda而不是vanilla python有關嗎?cx_Freeze與PyQt5和線程

我意識到使用這樣的日誌可能不是線程安全的,但是對於這個演示來說很好。

作爲參考,我使用:

  • Windows 7企業,服務包1
  • 阿納康達4.2.0(Python的2.7.12)
  • cx_Freeze 5.0
  • PyQt5 5.6.0

thread_test.py:

from PyQt5 import QtWidgets 
from PyQt5.QtWidgets import QApplication, QMainWindow 
from PyQt5.QtCore import QThread, QObject, pyqtSignal, pyqtSlot 

import sys 
import time 
import glob 
import logging 

log = logging.getLogger(__name__) 
log.setLevel(logging.DEBUG) 
log.addHandler(logging.StreamHandler()) 

class worker_object(QObject): 
    finished = pyqtSignal() 

    def __init__(self): 
     super(self.__class__, self).__init__() 
     log.info('2. Worker Object Initialized') 

    @pyqtSlot() 
    def run_thread(self): 
     log.info('5. Worker 1/5') 
     time.sleep(0.5) 
     log.info(' Worker 2/5') 
     glob.glob('*.jpg') 
     log.info(' Worker 3/5') 
     time.sleep(0.5) 
     log.info(' Worker 4/5') 
     self.finished.emit() 
     log.info(' Worker 5/5') 

class test_window(QMainWindow): 
    def __init__(self): 
     super(self.__class__, self).__init__() 
     log.info('1. Window Initialization (Started)') 

     self.centralwidget = QtWidgets.QWidget(self) 
     self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) 

     self.pushButton = QtWidgets.QPushButton(self.centralwidget) 
     self.pushButton.setText('Start!') 
     self.verticalLayout.addWidget(self.pushButton) 

     self.progressBar = QtWidgets.QProgressBar(self.centralwidget) 
     self.progressBar.setRange(0,1) 
     self.verticalLayout.addWidget(self.progressBar) 

     self.setCentralWidget(self.centralwidget) 
     self.statusbar = QtWidgets.QStatusBar(self) 
     self.setStatusBar(self.statusbar) 

     self.pushButton.clicked.connect(self.execute) 

     # Setup threading 
     self.thread = QThread() 
     self.worker_object = worker_object() 
     self.worker_object.moveToThread(self.thread) 
     self.worker_object.finished.connect(self.onFinished) 
     self.thread.started.connect(self.worker_object.run_thread) 
     log.info('3. Window Initialization (Finished)') 

    def onFinished(self): 
     self.thread.quit() 
     self.statusbar.showMessage('Finished!') 
     self.setEnabled(True) 
     self.progressBar.setRange(0,1) 
     log.info('6. Thread Finished') 

    def execute(self): 
     self.statusbar.showMessage('Working') 
     self.setEnabled(False) 
     self.progressBar.setRange(0,0) 
     log.info('4. Thread Starting') 
     self.thread.start() 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    form = test_window() 
    form.show() 
    app.exec_() 

setup.py:

from cx_Freeze import setup, Executable 

buildOptions = dict(packages = [], excludes = [], includes = [], include_files = []) 

executables = [Executable('thread_test.py', base=None)] 

setup(name='thread_test', 
     version = '1.0', 
     description = 'Threading Test', 
     options = dict(build_exe = buildOptions), 
     executables = executables) 

回答

0

對於它的價值,我剛安裝Anaconda3(蟒蛇4.2.0使用Python 3.5.2)和安裝cx_Freeze。使用這個,一切工作正常。所以也許這是Python 2.7中cx_Freeze的一個bug,我不確定。