如何跟踪可移动 QTab 的本地位置?

问题描述

我目前正在尝试设置边界,以便选项卡不能超出 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) 应该总是返回基本实现,否则在某些情况下您可能会遇到意外行为。