【问题标题】:PySide Qt4 - Qtabwidget - Disable drag and drop of a single q tab widgetPySide Qt4 - Qtabwidget - 禁用单个 q 选项卡小部件的拖放
【发布时间】:2015-10-29 00:17:05
【问题描述】:

我有一个qtabwidget,在任何给定时间都包含一个或多个标签。 我希望用户能够以任何顺序重新排列第二个到最后一个选项卡,但第一个选项卡保持在索引 0。

从我发现的所有内容来看,无法为每个选项卡独立启用setMovable

到目前为止,我想出的最佳解决方法是如果用户移动第一个选项卡(或它前面的另一个选项卡),只需将第一个选项卡移回位置 0。这显然不是理想的,但如果它正常工作是可以接受的......它工作了一小会儿,但它偶尔会导致应用程序崩溃(当用户在它之前拖动一个标签并将鼠标放在那里时,它似乎会发生,所以它处于一个不断尝试重新排列的循环中,并且一些低级崩溃)

关于可行解决方法的任何其他建议(对于此方法,或此功能更易于实现的类似小部件)?我认为它可能会重新分类 QTabWidget 以忽略第一个选项卡上的鼠标拖动,但我不确定如何防止另一个选项卡在它之前移动......

【问题讨论】:

  • 我打算为此发布一个解决方案,供我的一个软件项目使用。然后我发现它有一个错误,实际上并没有阻止标签被拖到位置 0....doh!

标签: python pyqt4 pyside move qtabwidget


【解决方案1】:

迄今为止,我发现“固定”QTabWidget 的第一个选项卡的唯一方法是使用 QTabBar 的子类。全局策略包括在QTabBar 的子类上安装eventFilter 并有条件地阻止MouseMove 事件,以便:

  1. 将第一个选项卡的位置固定在索引 0 处;
  2. 防止其他选项卡的左边缘向第一个选项卡右边缘的左侧移动得更远。这可以防止其他选项卡移动到第一个选项卡的前面。

下面的代码展示了一个简单的应用程序来展示如何做到这一点。

import sys
from PySide import QtGui, QtCore

class myQTabBar(QtGui.QTabBar):
    def __init__(self, *args, **kargs):
        super(myQTabBar, self).__init__(*args, **kargs)

        self.setMovable(True)
        self.installEventFilter(self)

    def eventFilter(self, source, event):

        if event.type() == QtCore.QEvent.Type.MouseMove:

            if source.currentIndex() == 0: # Block MouseMove for first tab.             
                return True 

            else: # For remaining tabs:

                  # block MouseMove if the left edge of the moving tab goes
                  # farther to the left than the right edge of first tab.

                moving_leftEdge = event.pos().x() - self.edge_offset
                fixed_rightEdge = self.tabRect(0).width()

                if moving_leftEdge < fixed_rightEdge:                    
                    return True  

        elif event.type() == QtCore.QEvent.Type.MouseButtonPress:

            # Get mouse click horizontal position.
            xclick = event.pos().x()

            # Get the left edge horizontal position of the targeted tab.
            xleft = self.tabRect(self.tabAt(event.pos())).x()

            # Compute and store offset between mouse click horizontal 
            # position and the left edge of the targeted tab            
            self.edge_offset = xclick - xleft

        return QtGui.QWidget.eventFilter(self, source, event)

class myQTabWidget(QtGui.QTabWidget):
    def __init__(self, *args, **kargs):
        super(myQTabWidget, self).__init__(*args, **kargs)

        tab_bar = myQTabBar()       
        self.setTabBar(tab_bar)

        self.addTab(QtGui.QWidget(), 'Tab1')
        self.addTab(QtGui.QWidget(), 'Tab2')
        self.addTab(QtGui.QWidget(), 'Tab3')


if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    instance1 = myQTabWidget()
    instance1.show()
    sys.exit(app.exec_())

结果:

【讨论】:

  • 太棒了!正是我想要的!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多