In PyQt5, it is not possible to create tabs on the left and arrange them horizontally by aligning them vertically. You can place it only on the left, but then the tabs will be vertically arranged. I found a code that allows you to place tabs horizontally on the left, but the names of the tabs are aligned in the middle. Is it possible to align tabs to the left without the ProxyStyle class?
Image:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QWidget
import sys
class TabWidget(QtWidgets.QTabWidget):
def __init__(self):
QtWidgets.QTabWidget.__init__(self)
self.setTabBar(self.TabBar(self))
self.setTabPosition(QTabWidget.TabPosition.West)
class TabBar(QtWidgets.QTabBar):
def tabSizeHint(self, index):
s = QtWidgets.QTabBar.tabSizeHint(self, index)
s.transpose()
return s
def paintEvent(self, event):
painter = QtWidgets.QStylePainter(self)
opt = QtWidgets.QStyleOptionTab()
for i in range(self.count()):
self.initStyleOption(opt, i)
painter.drawControl(QStyle.ControlElement.CE_TabBarTabShape, opt)
painter.save()
s = opt.rect.size()
s.transpose()
r = QtCore.QRect(QtCore.QPoint(), s)
r.moveCenter(opt.rect.center())
opt.rect = r
c = self.tabRect(i).center()
painter.translate(c)
painter.rotate(90)
painter.translate(-c)
painter.drawControl(QStyle.ControlElement.CE_TabBarTabLabel, opt);
painter.restore()
# class ProxyStyle(QtWidgets.QProxyStyle):
# def drawControl(self, element, opt, painter, widget):
# if element == QStyle.ControlElement.CE_TabBarTabLabel:
# r = QtCore.QRect(opt.rect)
# r.setHeight(opt.fontMetrics.horizontalAdvance(opt.text))
# r.moveBottom(opt.rect.bottom())
# opt.rect = r
# # QtWidgets.QProxyStyle.drawControl(self, element, opt, painter, widget)
# super().drawControl(element, opt, painter, widget)
if __name__ == '__main__':
app = QApplication([])
# app.setStyle(ProxyStyle()) # Is it possible to align the names without this class?
tab = TabWidget()
tab.setGeometry(0, 0, 5000, 5000)
tab.addTab(QWidget(), "Tab with a long name")
tab.addTab(QWidget(), "Tab 2")
tab.show()
sys.exit(app.exec())
I solved my problem (get rid of the custom ProxyStyle class and register the left alignment in the TabWidget.
class TabWidget(QtWidgets.QTabWidget):
def __init__(self):
QtWidgets.QTabWidget.__init__(self)
self.setTabBar(self.TabBar(self))
self.setTabPosition(QTabWidget.TabPosition.West)
class TabBar(QtWidgets.QTabBar):
def tabSizeHint(self, index):
s = QtWidgets.QTabBar.tabSizeHint(self, index)
s.transpose()
s.setHeight(int(s.height() * 1.3)) # We increase the height of each panel in which the tab name is placed
return s
def paintEvent(self, event):
painter = QtWidgets.QStylePainter(self)
opt = QtWidgets.QStyleOptionTab()
for i in range(self.count()):
self.initStyleOption(opt, i)
painter.drawControl(QStyle.ControlElement.CE_TabBarTabShape, opt)
painter.save()
r = self.tabRect(i)
r.moveLeft(r.left() + 20) # Move the rectangle to the left to align to the left edge
opt.rect = r
painter.translate(r.topLeft())
painter.drawText(QtCore.QRect(0, 0, r.width(), r.height()), QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, opt.text)
painter.restore()