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 looks like it works using the code below, but I'm having design issues. Before I split 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 few things that I want so that I cannot figure out how to do this:
-
I want to bridge the gap between QTabWidget and QTabBar. I've tried various things like
setContentsMargins(0,0,0,0)
and setting stylesheets, but nothing I've tried worked. -
I want the QTabBar to be flush with the top of the QTabWidget. It's interesting to note that the tabs seem to quickly switch between vertices each time the window is resized.
I watched:
- Qt Use QTabBar in another 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 mimic my desired behavior by setting the QTabBar miminumSizeHint () to (15,15) and setting QTabBar::tab { margin-right: -15px; }
, but that prevents me from actually clicking the tabs. for some reason there is space under (i.e. to the right of) the tabs and I don't know how to get rid of it.
second update: I have identified the underlying issue I am thinking about. my code is using
self.tabWidget.setTabPosition(QtGui.QTabWidget.West)
to move the tab to the left, but QTabWidget assumes there is a tabBar in there, hence extra space. If i do
self.tabWidget.setTabPosition(QtGui.QTabWidget.East)
that empty space appears on the right. So one thing I can do is set the tabShape directly to the tabBar:
self.tabBar.setShape(QtGui.QTabBar.RoundedWest)
however, this leaves an empty space at the top where the QTabWidget expects a QTabBar. 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.
source to share
I haven't been able to figure out how to hide the white space, so instead I just use QTabBar + QStackedWidget, which is pretty easy to implement. To make it look like QTabWidget, all you have to do is connect QTabBar.currentChanged
with 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 handy function that emulates QTabWidget.addTab
:
def addTab(self, widget, name):
self.stacked.addWidget(widget)
self.tabBar.addTab(name)
source to share
Your problem is that you are overriding the position of the tab bar by adding the tab bar to the layout.
Tab strip no longer appears in tab widgets when using strings.
tabLayoutBox = QtGui.QVboxLayout() tabLayoutBox.addWidget(self.tabBar)
These lines rename the tab bar. It looks like you just want to use setTabPosition () instead of creating your own tab bar. You don't need to install a new tab bar unless you create your own tab bar class and want to use that.
I don't know why you would want it in a separate layout, but another option is using
tabLayoutBox.setSpacing(0)
This is the gap between widgets to separate them. This spacing is for widgets. You have a layout in a layout, so setSpacing (0) may not apply to spacing in a layout. If not, you might need to subclass QVBoxLayout and create your own layout.
EDIT
I found insertSpacing to perform much better.
mainHBox.insertSpacing(1, -25)
source to share