Search code examples
qtpropertiespyqtdesigner

Exposing child's properties in the parent


I want to create a custom widget that contains a QSpinBox. I want the custom widget to expose some of QSpinBox's properties as its own so it can work conveniently in Designer.

Is there a convenient way to do this kind of property proxying in Qt?

I want to reiterate that the relationship between my custom widget and the QSpinBox is containment, not inheritance. I am using pyqt, but will happily accept a pure qt answer.

To clarify, I want to create variations of standard widgets that have some extra decorations. For example, I will be adding a toggleable icon to sit beside my QSpinBox. However I still want to be able to configure the QSpinBox in designer (ie, set the suffix, upper and lower limits, increment, etc).


Solution

  • Alrite, so here's a way to do it.

    It's better than writing a function manually for each property. Basically, you write a macro that expands the code for you. I have a doubleSpinBox in my widget and its value is changed whenever I change the property. And you emit a signal whenever the property changes, which is connected to the doubleSpinBox->setValue(). Tested and works perfectly. Complete code at this link.

    #ifndef MYWIDGET_H_
    #define MYWIDGET_H_
    
    #include <QtGui/QWidget>
    #include <QtGui/QLabel>
    #include "ui_mywidgetform.h"
    
    #define MYPROPERTY_SET_FUNC(_PROPCLASS_, _PROP_PARAM_NAME_, _PROP_SET_FUNC_NAME_, _PROP_NOTIFY_) \
      void _PROP_SET_FUNC_NAME_(_PROPCLASS_ _PROP_PARAM_NAME_) \
      { \
        emit _PROP_NOTIFY_(_PROP_PARAM_NAME_); \
      }
    
    #define MYPROPERTY_GET_FUNC(_PROPCLASS_, _PROP_READ_FUNC_NAME_, _PROP_VARIABLE_)\
      _PROPCLASS_ _PROP_READ_FUNC_NAME_() const  \
      { return _PROP_VARIABLE_; }
    
    class MyWidget : public QWidget
    {
      Q_OBJECT
    
    public:
      MyWidget(QWidget *parent = 0);
      ~MyWidget();
      enum Accuracy {Good, Bad};
    
    signals:
      void doubleSpinBoxValueChanged(double);
      void accuracyChanged(Accuracy);
    
    private:
        Q_PROPERTY(Accuracy accuracy READ accuracy WRITE setAccuracy NOTIFY accuracyChanged)
        Q_PROPERTY(double doubleSpinBoxValue READ doubleSpinBoxValue WRITE setDoubleSpinBoxValue)
    
    private:
      Accuracy m_accuracy;  //custom class property
      Ui::Form m_ui;
    
    public:
      //Getter functions
      MYPROPERTY_GET_FUNC (double, doubleSpinBoxValue, m_ui.doubleSpinBox->value())
      MYPROPERTY_GET_FUNC (Accuracy, accuracy, m_accuracy)
      //Setter functions
      MYPROPERTY_SET_FUNC(Accuracy, accuracy, setAccuracy, accuracyChanged)
      MYPROPERTY_SET_FUNC(double, doubleSpinBoxValue, setDoubleSpinBoxValue, doubleSpinBoxValueChanged)
    
    };
    
    #endif // MYWIDGET_H_