Reputation: 555
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:
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
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
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