从QLayout中移除QTabBar的填充/边距

5

我有一个应用程序,我想让QTabBar在与QTabWidget区域分离的单独VBoxLayout中。使用下面的代码可以实现,但是我遇到了样式问题。在将QTabBar与QTabWidget分离之前,我没有任何问题,但现在我无法弄清楚如何按照我想要的方式设置样式。

#!/usr/bin/env python2

from PyQt4 import QtGui, QtCore
from peaks import *

class mainWindow(QtGui.QWidget):

    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setWindowFlags(QtCore.Qt.Dialog)

        self.tabWidget = QtGui.QTabWidget()
        self.tabBar = QtGui.QTabBar()
        self.tabBar.setContentsMargins(0,0,0,0)
        self.tabWidget.setTabBar(self.tabBar)
        self.tabWidget.setTabPosition(QtGui.QTabWidget.West)
        self.tabWidget.setIconSize(QtCore.QSize(35, 35))

        self.tab1 = QtGui.QWidget()
        self.tab2 = QtGui.QWidget()

        tabLayoutBox = QtGui.QVBoxLayout()
        tabLayoutBox.setContentsMargins(0,0,0,0)
        tabLayoutBox.addWidget(self.tabBar)

        mainHBox = QtGui.QHBoxLayout()
        mainHBox.setContentsMargins(0,0,0,0)
        mainHBox.setSpacing(0)
        mainHBox.setMargin(0)
        mainHBox.addLayout(tabLayoutBox)
        mainHBox.addWidget(self.tabWidget)

        mainVBox = QtGui.QVBoxLayout()
        mainVBox.addWidget(QtGui.QWidget())
        mainVBox.addLayout(mainHBox)
        self.setLayout(mainVBox)


        self.tabWidget.addTab(self.tab1, 'tab1')
        self.tabWidget.addTab(self.tab2, 'tab2')

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    app.setStyleSheet(
            "QTabBar { alignment: right; }"
            "QTabBar::tear { width:0; border: none; }"
            "QTabBar::scroller { width:0; border: none; }"
            )


    main = mainWindow()
    main.show()
    sys.exit(app.exec_())

然而,有几件事情我想做但是不知道如何做到:

  • 我想要消除 QTabWidget 和 QTabBar 之间的间隙。我试过一些方法,例如使用 setContentsMargins(0,0,0,0) 和设置样式表,但是我尝试的所有方法都没有起作用。

  • 我想让 QTabBar 与 QTabWidget 顶部对齐。有趣的是,每当窗口调整大小时,选项卡似乎会快速在顶部之间切换。

我查看了以下内容:

更新: 我可以通过将 QTabBar 的 minimumSizeHint() 设置为 (15,15) 并设置 QTabBar::tab { margin-right: -15px; } 来模拟所需的行为,但这不允许我实际点击选项卡。由于某种原因,在选项卡下面(即右侧)有一个空间,我不知道如何去除它。

第二次更新: 我认为已经找到了主要问题。我的代码使用:

        self.tabWidget.setTabPosition(QtGui.QTabWidget.West)

要将选项卡移动到左侧,但QTabWidget假定那里有一个tabBar,因此会有额外的空间。如果我这样做:

        self.tabWidget.setTabPosition(QtGui.QTabWidget.East)

那个空白的区域出现在右边。 所以我可以直接在选项卡栏 (tabBar) 上设置 tabShape。

self.tabBar.setShape(QtGui.QTabBar.RoundedWest)

然而,这将在QTabWidget期望QTabBar的顶部留下一个空白空间。我可以在setShape之前使用setTabPosition将该空间移至右侧,但这并没有解决真正消除它的问题。
2个回答

2

我无法找到如何隐藏空白空间,因此我正在使用一个QTabBar + QStackedWidget,这很容易实现。要使其类似于QTabWidget,您只需要将QTabBar.currentChanged连接到QStackedWidget.setCurrentIndex

    self.stacked = QtGui.QStackedWidget()
    self.tabBar = QtGui.QTabBar()
    self.tabBar.currentChanged.connect(self.stacked.setCurrentIndex)
    self.tabBar.setShape(QtGui.QTabBar.RoundedWest)
    self.tabBar.updateGeometry()
    self.tabBar.setContentsMargins(0,0,0,0)

我还编写了一个方便的函数来模拟 QTabWidget.addTab

def addTab(self, widget, name):
    self.stacked.addWidget(widget)
    self.tabBar.addTab(name)

这本来是我在没有得到其他答案后要接受的答案,但它说我还需要等16个小时才能选择它作为我的答案。我也可以删除这个问题,因为只有我自己在说话,但我认为其他人也可以从中获得一些东西。 - erp
你能否编辑一下,详细说明解决方法? - Flexo
这可能是最灵活的方法,肯定是对问题的一个有效答案。不过需要更多的解释(或者只是一些简单的示例代码)。 - ekhumoro

0

你的问题在于通过将选项卡栏添加到布局中覆盖了选项卡栏的定位。

当使用这些行时,选项卡栏不再位于选项卡小部件中。

tabLayoutBox = QtGui.QVboxLayout()
tabLayoutBox.addWidget(self.tabBar)

这些代码将重新调整选项卡栏的父级。看起来你只想使用setTabPosition()方法而不是创建自己的选项卡栏。除非你创建了一个自定义的选项卡栏类并希望使用它,否则不需要设置新的选项卡栏。

我不知道为什么你想要它在单独的布局中,但另一个选择是使用

tabLayoutBox.setSpacing(0)

这是在小部件之间用于分隔它们的间距。那个间距是为小部件而设计的。您有一个布局中的布局,因此setSpacing(0)可能不适用于布局上的间距。如果不是这样,您可能需要子类化QVBoxLayout并创建自己的布局。

编辑

我发现insertSpacing效果更好。

mainHBox.insertSpacing(1, -25)

这只是将选项卡栏向左推移并将它们的顶部截去。我希望选项卡在一个单独的布局中,这样我就可以利用它们下面的空间来放置滚动条等内容。 - erp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接