How to change text alignment in QTabWidget?
Asked Answered
A

2

7

I cannot find a way to set the text alignment in a QTabWidget.

After I've created an instance of this widget, I've set its tabPosition property to West, but I wish it showed text/label horizontally. I've given a look to the Qt's stylesheets, but as you can see, the text-align property can only be set on QPushButton and QProgressBar.

I already searched on the web, but I just found a bugreport, a non-answered question, and finally a user that suggests to re-implement the paint() method. Maybe I'd solve, but I'm using Python (PyQt or PySide) and I don't know how to do it.

Can you help me?

EDIT: thanks to Teukamm, I wrote a bit of code:

from PyQt4 import QtGui, QtCore

class HorizontalTabWidget(QtGui.QTabBar):
    def paintEvent(self, event):
        for index in range(self.count()):
            painter = QtGui.QPainter()
            painter.begin(self)
            painter.setPen(QtCore.Qt.blue);
            painter.setFont(QtGui.QFont("Arial", 10));
            tabRect = self.tabRect(index)
            painter.drawText(tabRect, QtCore.Qt.AlignVCenter | QtCore.Qt.TextDontClip, self.tabText(index));
            painter.end()

     def sizeHint(self):
         return QtCore.QSize(60, 130)

import sys
app = QtGui.QApplication(sys.argv)
tabs = QtGui.QTabWidget()
tabs.setTabBar(HorizontalTabWidget())
widget1 =  QtGui.QWidget()
widget2 =  QtGui.QWidget()
tabs.addTab(widget1, "Widget1")
tabs.addTab(widget2, "Widget2")
tabs.setTabPosition(2)
tabs.show()
sys.exit(app.exec_())

And finally I've my text aligned as I expected, but I've a little (big?) problem: when you click on the right side of every tab button, it doesn't send the currentChanged SIGNAL. I've also tried to expand the width of every tabRect, in paintEvent, but it doesn't work. What should I change?

Thank you :)

BTW: you could not inherit from QTabWidget, but from QTabBar ;)

EDIT:

Solved! Just changed the method sizeHint in tabSizeHint and it works well :)

Artless answered 31/8, 2010 at 9:26 Comment(2)
you cant override the paint method in puQt?Semipro
Yes, I wanted to override that method, but I thought it was not included in the Python implementation (don't know exactly why I supposed this...) Thank you for your comment :)Artless
O
1

To get you started, you need to create a custom class that is a subclass of QtGui/QTabWidget and redefine the painting method:

class HorizontalTabWidget(QtGui.QTabWidget):
   def paintEvent(self, event):
      QPainter p;
      p.begin(this);
      # your drawing code goes here
      p.end();

Here's the documentation for QWidget.paintEvent method that you are reimplementing.

Of course you need to know how painting works in general, please refer to the documentation for QPainter.

Unfortunately I don't have a PyQt installation handy at the moment, so I can't give you a more specific solution.

Orta answered 31/8, 2010 at 12:35 Comment(2)
I forgot you may need to reimplement sizeHint() as well.Orta
Thank you very much! However, I've edited the question. Maybe you can help me :)Artless
A
8

I've put a worked example together on GitHub that solves this here: https://gist.github.com/LegoStormtroopr/5075267

The code is copied across as well:

Minimal example.py:

from PyQt4 import QtGui, QtCore
from FingerTabs import FingerTabWidget

import sys

app = QtGui.QApplication(sys.argv)
tabs = QtGui.QTabWidget()
tabs.setTabBar(FingerTabWidget(width=100,height=25))
digits = ['Thumb','Pointer','Rude','Ring','Pinky']
for i,d in enumerate(digits):
    widget =  QtGui.QLabel("Area #%s <br> %s Finger"% (i,d))
    tabs.addTab(widget, d)
tabs.setTabPosition(QtGui.QTabWidget.West)
tabs.show()
sys.exit(app.exec_())

FingerTabs.py:

from PyQt4 import QtGui, QtCore

class FingerTabWidget(QtGui.QTabBar):
    def __init__(self, *args, **kwargs):
        self.tabSize = QtCore.QSize(kwargs.pop('width'), kwargs.pop('height'))
        super(FingerTabWidget, self).__init__(*args, **kwargs)

    def paintEvent(self, event):
        painter = QtGui.QStylePainter(self)
        option = QtGui.QStyleOptionTab()

        for index in range(self.count()):
            self.initStyleOption(option, index)
            tabRect = self.tabRect(index)
            tabRect.moveLeft(10)
            painter.drawControl(QtGui.QStyle.CE_TabBarTabShape, option)
            painter.drawText(tabRect, QtCore.Qt.AlignVCenter |\
                             QtCore.Qt.TextDontClip, \
                             self.tabText(index));

    def tabSizeHint(self,index):
        return self.tabSize
Adulterate answered 3/3, 2013 at 9:54 Comment(1)
Need's a lot of improvement, i have added a lot of things, but for initial script is very good and It works. This is more complete answer, not only for the alignment, but for 'Finger Tabs' too. Thanks!Reagent
O
1

To get you started, you need to create a custom class that is a subclass of QtGui/QTabWidget and redefine the painting method:

class HorizontalTabWidget(QtGui.QTabWidget):
   def paintEvent(self, event):
      QPainter p;
      p.begin(this);
      # your drawing code goes here
      p.end();

Here's the documentation for QWidget.paintEvent method that you are reimplementing.

Of course you need to know how painting works in general, please refer to the documentation for QPainter.

Unfortunately I don't have a PyQt installation handy at the moment, so I can't give you a more specific solution.

Orta answered 31/8, 2010 at 12:35 Comment(2)
I forgot you may need to reimplement sizeHint() as well.Orta
Thank you very much! However, I've edited the question. Maybe you can help me :)Artless

© 2022 - 2024 — McMap. All rights reserved.