$> man42.net Blog written by a human

I faced some problems while playing with custom Q_PROPERTY through Qt Style Sheet in Qt 4, here is my solution.

# What I wanted

  • I wanted to add a custom Q_PROPERTY to a child of QAbstractItemDelegate.

# Why it didn't work

  • QAbstractItemDelegate inherits from QObject whereas Qt style sheets only work with children of QWidget.
  • It's not possible to inherit both from QAbstractItemDelegate and from QWidget as multiple inheritance from QObject is forbidden.
  • A Widget parent should be set in order to receive style sheet updates.

# My Solution (see code example below)

  • Creating a dedicated class MyStyle inheriting from QWidget.
  • Adding Q_PROPERTY having a WRITE method (mandatory) and a type supported by Qt Style Sheets.
  • Prefixing property name with qproperty- in your qss file (see example below).

Note: if you already have a class that inherits from QWidget you can add properties directly to it!

# Code example

Let's say you want a class MyStyle to act as a Qt Style Sheet receiver. You will use it in your class MyDelegate.

# MyStyle.h & MyStyle.cpp

(inlined for readability convenience)

#include <QWidget>
#include <QColor>

class MyStyle : public QWidget
{
  Q_OBJECT

  Q_PROPERTY(QColor available_color READ availableColor
             WRITE setAvailableColor DESIGNABLE true SCRIPTABLE true)
  Q_PROPERTY(QColor unavailable_color READ unavailableColor
             WRITE setUnavailableColor DESIGNABLE true SCRIPTABLE true)

public:
  inline explicit MyStyle(QWidget* parent)
    : QWidget(parent)
    , _availableColor(Qt::white)
    , _unavailableColor(Qt::black)
  {
  }

  inline QColor availableColor() const
  {
    return _availableColor;
  }

  inline void setAvailableColor(const QColor& value)
  {
    this->_availableColor = value;
  }

  inline QColor unavailableColor() const
  {
    return _unavailableColor;
  }

  inline void setUnavailableColor(const QColor& value)
  {
    this->_unavailableColor = value;
  }

private:
  QColor _availableColor;
  QColor _unavailableColor;
};

# MyDelegate.h & MyDelegate.cpp

(sample - inlined for readability convenience)

// headers include here

class MyDelegate : public QStyledItemDelegate
{
  Q_OBJECT

public:
  MyDelegate(const MyStyle& style, QObject* parent = 0)
    : QStyledItemDelegate(parent), _myStyle(style)
  {
  }

  void paint(QPainter* painter,
             const QStyleOptionViewItem& option,
             const QModelIndex& index) const
  {
    // some code here

    // to access your property:
    QColor drawingColor = this->_myStyle.availableColor();

    // some code here
  }

private:
  const MyStyle& _myStyle;
};

# MyApp.h & MyApp.cpp

(sample - inlined for readability convenience)

// ...

class MyApp : public QMainWindow // ...
{
  Q_OBJECT

public:
  MyApp() : _myStyle(this)
  {
  }

protected:
  MyDelegate* _createDelegate()
  {
    return new MyDelegate(this->_myStyle, this);
  }

private:
  MyStyle _myStyle;
};

# my_app.qss

(your Qt Style Sheet)

MyStyle {
  qproperty-available_color: rgb(233, 246, 174);
  qproperty-unavailable_color: rgb(250, 198, 198);
}

I hope it helped you!

Buffer this pageShare on TumblrDigg thisShare on FacebookShare on LinkedInTweet about this on TwitterEmail this to someoneShare on Google+Share on RedditPin on Pinterest