1

I want to indent the title of a QDockWidget w/o adding spaces.

#include <QStyle>
#include <QProxyStyle>
#include <iostream>

class my_style : public QProxyStyle
  {

  Q_OBJECT

  public:
    my_style (QStyle* style = 0) :
        QProxyStyle (style)
      {
      }
    virtual ~my_style ()
      {
      }

    virtual QRect subElementRect (SubElement element, const QStyleOption * option, const QWidget * widget = 0) const
      {
        QRect rect = QProxyStyle::subElementRect (element, option, widget);
        if (element == QStyle::SE_DockWidgetTitleBarText)
          {
            rect.adjust (50, 0, 0, 0);
          }
        //std::cerr << "debug:" << element << std::endl;
        return rect;
      }
  };

I have no clue why but when I apply my style it's never running into that if. If I debug the method I only get an output for two different elements which are the buttons in the title bar.

Ben
  • 807
  • 1
  • 8
  • 22

1 Answers1

1

subElementRect is not called to get the title area for all styles. At least, XP, Vista and MacOSX styles are using directly QStyleOption::rect which is passed as parameter to the drawControl function for CE_DockWidgetTitle.

To handle both cases, you should also reimplement drawControl:

void drawControl(ControlElement element, const QStyleOption *option, 
    QPainter *painter, const QWidget *widget) const
  {
    const QStyleOptionDockWidget *dockWidget;

    if(element == CE_DockWidgetTitle && 
        (dockWidget = qstyleoption_cast<const QStyleOptionDockWidget *>(option)))
      {
        QStyleOptionDockWidget copy = *dockWidget;
        copy.rect.adjust(50,0,0,0);
        // or you can add spaces in the title to avoid the border moving left too
        // copy.title = QString(50 / copy.fontMetrics.width(" "), QChar(' ')) + copy.title;
        QProxyStyle::drawControl(element, &copy, painter, widget);
        return;
      }
    QProxyStyle::drawControl(element, option, painter, widget);
  }


Alternatively you could use a style sheet, with a padding or a margin:

dockWidget->setStyleSheet("::title { position: relative; padding-left: 50px;"
                          "          text-align: left center }");

The "position" rule does nothing, but is necessary, because strangely the style is only applied if some other rule categories are also present.
The text needs to be vertically realigned too because the alignment seem to be lost when using a style sheet.

alexisdm
  • 29,448
  • 6
  • 64
  • 99
  • The problem with the `drawControl` method is, that it not only indents the text but resizes the border too. If I apply the style sheet with `position: relative` it looks like some more attributes get reset so that the text does not stay in line. – Ben Mar 12 '12 at 10:23
  • 1
    @Ben I added an approximate alternative for the `drawControl` method, and a possible fix for the style sheet method. – alexisdm Mar 12 '12 at 16:06