首页 > 解决方案 > 工作线程和主线程中的 PyQt QMutex

问题描述

我想用 a 锁定打印功能,QMutex因此一次只有一个线程可以访问它。我用两个按钮编写了一个非常简单的 GUI,一个用于退出线程,一个用于尝试打印某些内容以查看主线程是否阻塞。

我已经通过将锁设为全局变量来使其工作,但互联网上的每个人都说全局变量是一个坏主意。__init__但是,在 Main Window 和 Worker 类定义的部分中声明锁self.lock = QtCore.QMutex()并不提供与我将其声明为全局变量时相同的行为。

确保主线程等待工作者的正确方法是什么?

以下是全局案例的代码:

import sys
from PyQt5 import QtWidgets, QtCore
import time

lock=QtCore.QMutex()

class expSignals(QtCore.QObject):
# =============================================================================
#   Signal for quitting the thread. Dunno if should be seperate class or stati
#   for main window
# =============================================================================
    pause=QtCore.pyqtSignal()

class MyApp(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
# =============================================================================
#         Create thread,worker, lock and move worker
# =============================================================================
        self.thread=QtCore.QThread(self)
        self.mot=motorpositioner()
        self.mot.moveToThread(self.thread)

# =============================================================================
#         Putting buttons and GUI stuff in place
# =============================================================================
        self.button=QtWidgets.QPushButton('Quit thread',self)
        self.button2=QtWidgets.QPushButton('Test locking',self)
        layout = QtWidgets.QHBoxLayout()
        layout.addWidget(self.button)
        layout.addWidget(self.button2)
        self.button2.move(0,50)
        self.setLayout(layout)
        self.setGeometry( 300, 300, 350, 300 )

# =============================================================================
#         Making and connecting signals
# =============================================================================
        self.qthread_sig=expSignals()
        self.thread.started.connect(self.mot.do_it)
        self.button.clicked.connect(self.qthread_sig.pause.emit)
        self.button2.clicked.connect(self.test_lock)
        self.qthread_sig.pause.connect(self.thread.quit)

# =============================================================================
#         Start Thread
# =============================================================================
        self.thread.start()

# =============================================================================
#       Mutex should lock print
# =============================================================================
    def test_lock(self):
        #global lock
        with QtCore.QMutexLocker(lock):
            print('Printed in main thread')

    def closeEvent(self,event):
        self.qthread_sig.pause.emit()
        event.accept()

class motorpositioner(QtCore.QObject):
    def __init__(self):
        QtCore.QThread.__init__(self)
# =============================================================================
#       Create timer and lock, connect timer to print
# =============================================================================
        self.timer = QtCore.QTimer(parent=self)
        self.timer.timeout.connect(self.query_mot)
        self.stat=0
    @QtCore.pyqtSlot()        
    def do_it(self):
# =============================================================================
#       Start timer
# =============================================================================
        self.timer.start(5000)

    @QtCore.pyqtSlot()
    def query_mot(self):
        #global lock
        with QtCore.QMutexLocker(lock):
            print('Printed in worker thread')
            time.sleep(5)



if __name__ == "__main__":
    if not QtWidgets.QApplication.instance():
        app = QtWidgets.QApplication(sys.argv)
    else:
        app = QtWidgets.QApplication.instance() 
    window = MyApp()
    window.show()
    app.exec_()

我实际上并不想锁定打印功能,而是确保一次只有一个线程与 PC 控制的定位平台对话。

标签: pyqtmutexqthread

解决方案


推荐阅读