erp
erp

Reputation: 555

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:

stuff I've looked at:

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.

Upvotes: 5

Views: 3891

Answers (2)

erp
erp

Reputation: 555

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)

Upvotes: 2

justengel
justengel

Reputation: 6320

Your problem is that you override the tab bar positioning by adding the tab bar to a layout.

The tab bar is no longer in the tab widget when you use the lines.

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

These lines re-parent the tab bar. It looks like you just want to use setTabPosition() instead of creating your own tab bar. You don't need to set a new tab bar unless you create a custom tab bar class and want to use that.

I don't know why you would want it in a separate layout, but the other option is use

tabLayoutBox.setSpacing(0)

This is the spacing in between widgets to separate them. That spacing is for widgets. You have a layout in a layout, so setSpacing(0) may not apply to the spacing on a layout. If not you may have to sub-class QVBoxLayout and create your own layout.

EDIT

I've found that insertSpacing works a lot better.

mainHBox.insertSpacing(1, -25)

Upvotes: 0

Related Questions