【问题标题】:cx_Freeze with PyQt5 and Threading使用 PyQt5 和线程的 cx_Freeze
【发布时间】:2017-09-10 06:39:02
【问题描述】:

如果我运行下面的 thread_test.py 代码,我在线程中的函数运行良好。但是,如果我使用 cx_Freeze 编译它,那么它会在调用 glob 时挂起。它不会给出错误并且 gui 仍然响应,但线程似乎挂起(什么都不做)。除了 glob 之外,我还测试了其他几个函数,所以 glob 本身不是问题。我尝试从多处理中添加 freeze_support,即使我没有使用多处理,但这并没有帮助。关于可能导致这种情况的原因有什么想法吗?是否与使用 Anaconda 而不是 vanilla python 有关?

我意识到像这样使用日志可能不是线程安全的,但对于这个演示来说它很好。

作为参考,我正在使用:

  • Windows 7 企业版,Service Pack 1
  • Anaconda 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)

【问题讨论】:

    标签: python anaconda pyqt5 cx-freeze qthread


    【解决方案1】:

    不管怎样,我刚刚安装了 Anaconda3(Anaconda 4.2.0 和 Python 3.5.2)并安装了 cx_Freeze。使用它,一切正常。所以也许这是python 2.7上cx_Freeze中的一个错误,我不确定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      • 2020-08-18
      • 2014-06-30
      • 2017-03-25
      • 2014-06-22
      • 1970-01-01
      相关资源
      最近更新 更多