PySide Qt4 - Qtabwidget - 禁用拖放单个q选项卡小部件

时间:2015-08-06 02:16:50

标签: python pyqt4 pyside move qtabwidget

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

从我发现的所有内容中,无法为每个标签单独启用setMovable

到目前为止,我提出的最佳解决方法是,如果用户移动它(或前面的另一个标签),只需将第一个标签移回位置0。这显然不是理想的,但如果它正常工作就可以接受......它可以工作一段时间,但它偶尔会使应用程序崩溃(当用户在它之前拖动一个标签并持有鼠标时似乎会发生这种情况那里,所以它在一个不断循环的尝试重新排列和低级别的崩溃)

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

1 个答案:

答案 0 :(得分:2)

我发现的唯一方法是&#34; pin&#34; QTabWidget的第一个标签是使用QTabBar的子类。全局策略包括在eventFilter的子类上安装QTabBar并有条件地阻止MouseMove事件以便:

  1. 将第一个标签的位置固定在索引0;
  2. 防止其他标签的左边缘移动到第一个标签右边缘的左侧。这样可以防止其他选项卡在第一个选项卡前移动。
  3. 下面的代码提供了一个简单的应用程序来展示如何做到这一点。

    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_())
    

    结果是:

    enter image description here