pyqt - 工作线程和主线程中的 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 控制的定位平台对话。
解决方案
推荐阅读
- http - 序列化 Http 响应的原因
- kubernetes - 在 Kubernetes 节点亲和性中,什么是 IgnoredDuringExecution?
- spring-boot - Mybatis spring boot如何创建动态更新查询
- kubernetes - 零停机 K8S 部署:等到探测器知道后再真正停止 Pod?
- docker - 如何修复 Kafka Docker 容器抛出 0.0.0.0/0.0.0.0:2181:连接被拒绝?
- php - 删除嵌套类别 laravel
- python - 运行代码后遇到错误:( sumation = sum(var.copy()) TypeError: 'int' object is not subscriptable)
- python - 用 nan 进行缺失值插补
- python - odoo 14:我如何在注册中添加其他字段,例如地址等
- css - 下一个 js 中的样式