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 ---

_______________________________________________
PyKDE mailing list    [email protected]
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde

Reply via email to