[PyKDE] PyQt: Better highlighting in QTabWidgets (improves eric3
and other Qt3.x apps)
Thilo Ernst
te0006 at web.de
Wed Dec 14 14:17:45 GMT 2005
Hello,
in our own simulation-related PyQt app as well as in eric3 we found that
the current tab in a QTabWidget is visually hard to recognize: apart
form the decoration lines and a barely visible increase in the height of the
tab's background it looks just like the other tabs. As a consequence,
the user is sometimes mistaken about which tab is active, types into the
wrong page, etc.
We thus went digging for ways to have the current tab highlighted in some
way - which turned out to be surprisingly difficult. The only feasible way
involved subclassing QTabBar and overriding its paintLabel() method.
However this had to be combined with a rather nonintuitive way of detecting
the current tab, otherwise strange rendering problems (some tabs not being
painted at all) would occur when the app used more than one QTabWidget
instance. Also, among the many conceivable ways to actually do the
highlighting (foreground or background color, font weight etc.) , only
using
font().setUnderline() proved to be both working in the first place and
to not
result in unwanted side effects (such as font metrics problems).
The code snippet below is the result of our efforts: a working QTabWidget
drop-in replacement class which renders the current tab underlined.
To have this widget work with Qt-Designer-generated code without the need
to touch said generated code, we devised only a rather dirty solution:
monkey-patching the qt module such that the 'QTabWidget' entry in the
module
dictionary refers to our new class (cf. last code line). If anybody
knows a cleaner
approach, please let the list know.
Feel free to use this code snippet in your own application. We would be
delighted to see it ending up e.g. in a forthcoming version of eric3.
(Hint: inserting it after line 15 of eric-3.8.0/eric/eric3.py suffices
functionally,
although this admittedly won't yield any style points :-)
Best regards,
Thilo Ernst, Fraunhofer FIRST
--- snip ---
import qt
class HighlightedTabBar(qt.QTabBar):
"""a tab bar where the label of the selected tab is painted
underlined"""
def paintLabel(self, painter, rect, tab, has_focus):
# don't use QTabBar.currentTab() - here be dragons
selected= (self.tabAt(self.indexOf(self.currentTab()))==tab)
if selected:
painter.save()
# options for style emphasis: foreground/background colors
don't work.
# Bold works but disturbs the font metrics. Underline Just
Works.
painter.font().setUnderline(True)
qt.QTabBar.paintLabel(self, painter, rect, tab, has_focus)
if selected:
painter.restore()
QTabWidget_orig=qt.QTabWidget
class HighlightedTabWidget(QTabWidget_orig):
"""A QTabWidget equivalent which uses our HighlightedTabBar"""
def __init__(self, parent, *args):
QTabWidget_orig.__init__(self, parent, *args)
self.setTabBar(HighlightedTabBar(self))
qt.QTabWidget=HighlightedTabWidget # monkey-patch the qt module to use
this implementation
-- snip ---
More information about the PyQt
mailing list