问题描述
我目前正在尝试设置边界,以便选项卡不能超出 QTabBar 的每一端。默认情况下,只要将可移动选项卡拖到 QTabBar 区域之外,它就会消失在 void 中 - An example of the QTab being dragged outside of the QTabBar's Area.
这在大多数情况下都很好,但从视觉上看,我希望标签在到达 QTabBar 边缘时完全停止移动。我试图通过 Qt 的事件系统来实现这个目标,目前只支持左边界。每当用户点击 QTab 时,我都会记录他的鼠标初始位置和当前标签未移动的位置和大小。然后我使用这些值来确定如果用户将鼠标向左移动,当前选项卡将到达 QTabBar 边缘的 x 位置。如果到达此位置,则过滤事件以防止标签进一步移动。
def eventFilter(self,source,event):
if event.type() == QEvent.Type.MouseButtonPress:
self.startingpos = event.x()
self.tabOrigin = self.curTab.x()
self.tabroom = self.startingpos - self.tabOrigin
if event.type() == QEvent.Type.MouseMove:
if self.curIndex != self.tabs.currentIndex():
self.curIndex = self.tabs.currentIndex()
self.curTab = self.tabs.tabBar().tabRect(self.curIndex)
if event.x() < self.tabroom:
return True
return False
除非用户快速向左移动鼠标,否则此策略是有效的。这会导致移动选项卡在到达 QTabBar 的边缘之前,在超过指定边界之前卡在鼠标的最后记录位置 - An example of the QTab getting stuck before reaching the left side of the QTabBar.
我不确定如何解决这个问题。我知道移动选项卡实际上与最初单击的选项卡不同。无论如何访问移动选项卡的位置并手动设置其位置?如果没有,我们将不胜感激任何有关如何解决此问题的建议。
解决方法
鼠标事件不是线性的,如果用户移动鼠标太快,它们会“跳过”像素。
问题在于“移动选项卡”完全在内部实现,因此无法访问该选项卡(实际上,它是临时绘制在其余选项卡上的“假”小部件)。
一个可能的解决方案是检测当前按下的标签,获取相对于该标签的水平鼠标位置,检查移动是否超出限制(左侧为 0,右边距为最后一个标签的右侧),基于此合成一个新的鼠标事件,然后发布该事件。
mapping
请注意, def eventFilter(self,source,event):
if (event.type() == event.MouseButtonPress and
event.button() == QtCore.Qt.LeftButton):
tabRect = source.tabRect(source.tabAt(event.pos()))
self.leftDistance = event.x() - tabRect.left()
self.rightMargin = tabRect.right() - event.x()
self.rightLimit = source.tabRect(self.tabs.count() - 1).right()
elif (event.type() == event.MouseMove and
event.buttons() == QtCore.Qt.LeftButton):
if event.x() - self.leftDistance < 0:
pos = QtCore.QPoint(self.leftDistance,event.y())
newEvent = QtGui.QMouseEvent(
event.type(),pos,event.button(),event.buttons(),event.modifiers())
QtWidgets.QApplication.postEvent(source,newEvent)
return True
elif event.x() + self.rightMargin > self.rightLimit:
pos = QtCore.QPoint(
self.rightLimit - self.rightMargin,newEvent)
return True
return super().eventFilter(source,event)
应该总是返回基本实现,否则在某些情况下您可能会遇到意外行为。