工作线程和主线程中的PyQt QMutex

时间:2018-07-17 12:46:41

标签: pyqt mutex qthread

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

我已经通过将锁设为全局变量来使其工作,但是互联网上的每个人都说全局变量是一个坏主意。但是,在Main Window和Worker类定义的__init__部分中将锁声明为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控制的定位平台进行通讯。

0 个答案:

没有答案