我想用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控制的定位平台进行通讯。