我在QDialog中有一个QListWidget,我想将所有轮事件重定向到列表,所以我这样做了:
class Form(QDialog):
def __init__(self):
...
self.myList = QListWidget()
...
def wheelEvent(self, scrollEvent):
if not scrollEvent.isAccepted():
scrollEvent.accept()
self.myList.wheelEvent(scrollEvent)
它可以正常工作,直到滚动操作尝试将列表移动到其限制之外。似乎在那些情况下,QListWidget不接受(忽略)滚动事件并将其(忽略)传送给它的父,Form,它再次将它再次发送到QListWidget,直到“超出最大递归深度”提出错误消息。
如果事件在被重定向到QListWidget之前被接受,为什么当它返回到Qdialog时会再次重定向到QListWidget?似乎事件的“accept”标志未被保留(或者QListWidget将其设置回“不被接受”),并且当它返回QDialog时被视为新事件。即使列表位于顶部/底部,我如何保留这些标志或使QListWidget接受事件?
我试图定义一个QListWidget的子类,并在将其重定向到超类之前接受该子类的事件,但同样的结果,该事件返回到Dialog,因为不被接受。
编辑:再次嗨!我找到了解决方案:
class Form(QDialog):
def __init__(self):
...
self.processingWheel = False
self.myList = QListWidget()
...
def wheelEvent(self, scrollEvent):
if not self.processingWheel:
self.processingWheel = True
self.myList.wheelEvent(scrollEvent)
self.processingWheel = False
现在,当QListWidget不处理事件时(导致列表位于顶部/底部),事件再次到达QDialog,但第二次没有再次重定向到QListWidget。我想它被重定向到QDialog父级,并且它已被处理(什么都不做)。
如果允许,我想让问题保持开放,因为我仍然想知道为什么我必须自己管理该标志,并且无法使用与该事件相关联的isAccepted()标志。尝试。我担心在Qt中的事件传播期间我没有理解事件标志背后发生的事情。
答案 0 :(得分:1)
注意:这适用于Qt5 - 在Qt4中,事情可能会有所不同。
当您致电self.myList.wheelEvent(scrollEvent)
时,会在内部调用QListView.wheelEvent(event)
,这将创建一个新的QWheelEvent
,并将其转发到相应的滚动条窗口小部件。如果滚动条无法处理该事件,则会将接受的标志设置为false。这将导致事件立即重新传播到对话框,整个事情将再次出现。
将事件发送到list-widget后,在myList.wheelEvent()
返回之前,您无法重新设置accept标志。但是,当然,如果list-widget的滚动条忽略了该事件,它永远不会返回,因为它会立即进入无限回归。
在转发事件之前调用event.flag()
将无效,因为默认情况下滚动条将其重置为false,并且只有在显式处理事件时才将其设置为true。
鉴于这一切,使用外部标志的解决方案似乎是唯一可行的解决方案(它有点类似于blockSignals机制)。