Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove padding/margin from QTabBar in QLayout

I have an application where I want the QTabBar to be in a separate VBoxLayout from the QTabWidget area. It sort of works using the code below but I'm having styling problems. Before I separated the QTabBar from the QTabWidget I didn't have any problems but now I can't figure out how to style it the way I want.

#!/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_())

However there are a couple of things that I want that I can't figure out how to do:

  • I want to eliminate the gap between the QTabWidget and the QTabBar. I've been trying various things like setContentsMargins(0,0,0,0) and setting stylesheets but nothing I've tried has worked.

  • I want QTabBar to be flush with the top of the QTabWidget. Interesting to note that the tabs seem to rapidly switch back and forth between the top whenever the window is resized.

stuff I've looked at:

  • Qt Use QTabBar in a Different QLayout
  • http://doc.qt.io/qt-5/stylesheet-examples.html
  • https://wiki.qt.io/Adjust_Spacing_and_Margins_between_Widgets_in_Layout

update: I can emulate my desired behavior by setting the QTabBar miminumSizeHint() to (15,15) and setting QTabBar::tab { margin-right: -15px; } but this doesn't let me actually click the tabs. there's a space underneath (ie to the right of) the tabs for some reason and I've no idea how to get rid of it.

second update: I've identified the main problem I think. my code uses

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

to move the tab to the left side but the QTabWidget assumes that there is a tabBar there, hence the extra space. If I do

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

that blank space shows up at the right. So one thing I can do is set the tabShape directly on the tabBar:

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

however this leaves a blank space at the top where the QTabWidget expects the QTabBar to be. I can move that space to the right using setTabPosition before setShape but that doesn't solve the problem of actually getting rid of it.

like image 415
erp Avatar asked Nov 01 '22 05:11

erp


1 Answers

I wasn't able to figure out how to hide the empty space so instead I'm just using a QTabBar + QStackedWidget which is quite easy to implement. In order to make one like a QTabWidget all you need to do is connect QTabBar.currentChanged to 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)

I also wrote a convenience function that emulates QTabWidget.addTab:

def addTab(self, widget, name):
    self.stacked.addWidget(widget)
    self.tabBar.addTab(name)
like image 87
erp Avatar answered Nov 10 '22 19:11

erp