我遇到的情况是我在异步交换数据以响应python PySide GUI中的按钮按下。我有我的代码在不同的线程中发送数据(并通过Qt信号和插槽交换数据以确保线程安全),并且一切正常。
问题是我不想双击工具栏按钮来生成两次传输。我希望在传输过程中阻止主窗口。 QProgressDialog看起来就像我想要的那样,特别是因为如果转移很快就不会显示出来。
我写了一些代码来利用它:
def startUSBProgress(self, message, operation):
title = self.tr("Transferring USB Data")
progress = QtGui.QProgressDialog(message, "", 0, 1, self)
progress.setWindowModality(QtCore.Qt.WindowModal)
progress.setCancelButton(None)
progress.setMinimumDuration(500) # half second
progress.setWindowTitle(title)
operation.completed.connect(progress.reset)
operation.completed.connect(progress.deleteLater)
operation.error.connect(progress.reset)
operation.error.connect(progress.deleteLater)
progress.setValue(0)
我正在我的所有转会中进行人工1秒睡眠测试。没有错误,但是在500毫秒延迟结束之前进度对话框不是模态(并且进度对话框变得可见),因此它实际上并没有解决我的问题。仍然可以按下多个按钮。在最短持续时间之后,对话框是模态的,而不是之前。
我不确定这是错误还是预期功能。我找不到任何关于它的讨论。无论如何,这对我的应用程序来说都是不受欢迎的行为。
我不想将minimumDelay设置为0,因为99.9%的时间事务处理非常快,并且对话框blip看起来不太好。
有什么方法可以解决这个问题吗?我倾向于稍微苛刻的选择,如暂时抑制鼠标和放大器键盘事件。注意,事件循环需要像处理完成信号一样运行。
我的开发环境(我看到这个问题)是Windows 7,但我的应用程序最终将是跨平台的。
答案 0 :(得分:0)
如果现在有Qt / Python细节,我想
progress.show()
应立即显示模态对话框。
答案 1 :(得分:0)
我找到了一种使用Qt事件过滤器实现我想要的方法。
来自https://stackoverflow.com/a/2017400/1011276
的想法过滤类:
class UserEventsFilter(QtCore.QObject):
"""
Reference: https://stackoverflow.com/a/2017400/1011276
"""
def __init__(self, parent=None):
super().__init__(parent)
self.filterEnabled = False
@QtCore.Slot()
def enableFilter(self):
self.filterEnabled = True
@QtCore.Slot()
def disableFilter(self):
self.filterEnabled = False
def eventFilter(self, obj, event):
if self.filterEnabled:
t = event.type()
if (t == QtCore.QEvent.KeyPress or
t == QtCore.QEvent.KeyRelease or
t == QtCore.QEvent.MouseButtonPress or
t == QtCore.QEvent.MouseButtonDblClick or
t == QtCore.QEvent.MouseMove or
t == QtCore.QEvent.Enter or
t == QtCore.QEvent.HoverEnter or
t == QtCore.QEvent.HoverLeave or
t == QtCore.QEvent.HoverMove or
t == QtCore.QEvent.DragEnter or
t == QtCore.QEvent.DragLeave or
t == QtCore.QEvent.DragMove or
t == QtCore.QEvent.Drop):
return True
return QtCore.QObject.eventFilter(self, obj, event)
初始代码(在主窗口的__init__
中):
self.userEventFilter = UserEventsFilter(self)
app = QtCore.QCoreApplication.instance()
app.installEventFilter(self.userEventFilter)
更新了使用代码:
def startUSBProgress(self, message, operation):
title = self.tr("Transferring USB Data")
progress = QtGui.QProgressDialog(message, "", 0, 1, self)
progress.setWindowModality(QtCore.Qt.WindowModal)
progress.setCancelButton(None)
progress.setMinimumDuration(500) # half second
progress.setWindowTitle(title)
operation.completed.connect(progress.reset)
operation.completed.connect(progress.deleteLater)
operation.completed.connect(self.userEventFilter.disableFilter)
operation.error.connect(progress.reset)
operation.error.connect(progress.deleteLater)
operation.error.connect(self.userEventFilter.disableFilter)
self.userEventFilter.enableFilter()
progress.setValue(0)