Search code examples
c++qtqt-designerqtplugin

How to use flags as custom widget property type in QT?


I have trouble to use flags as QT custom widget property type. The expected property does not show on QT Designer property editor.

The code is as below:

#ifndef SVBASICDEMO_H
#define SVBASICDEMO_H

#include <QString>
#include <QtUiPlugin/QDesignerExportWidget>
#include <QWidget>
#include <QLabel>
#include "svbasicwidget.h"

QT_BEGIN_NAMESPACE

namespace Company {
namespace Product {
namespace Widget {
namespace Basic {
class QDESIGNER_WIDGET_EXPORT SvBasicDemo : public SvBasicWidget
{
    Q_OBJECT
        Q_FLAGS(SvBasicDemo::AccessTypes)
        Q_PROPERTY(QString url_prop MEMBER url_prop NOTIFY propertyChange)
        Q_PROPERTY(Priority enum_prop MEMBER enum_prop NOTIFY propertyChange)
        Q_PROPERTY(AccessTypes flag_prop MEMBER flag_prop NOTIFY propertyChange)
        Q_PROPERTY(Qt::Alignment flag_prop_2 MEMBER flag_prop_2 NOTIFY propertyChange)

    Q_SIGNALS:
    void propertyChange();

    public slots:
    //更新属性的槽
    void updateProperty();

public:
    SvBasicDemo(QWidget *parent = 0);
    virtual void refresh_binding_cb();
    virtual QString help_info() const;

    enum Priority { High, Low, VeryHigh, VeryLow };
    Q_ENUM(Priority)

    enum AccessType { Read = 0x1, Write = 0x2 };

    Q_DECLARE_FLAGS(AccessTypes, AccessType)

private:
    QString url_prop;
    Priority enum_prop;
    AccessTypes flag_prop;
    Qt::Alignment flag_prop_2;
    QLabel label;
};

Q_DECLARE_OPERATORS_FOR_FLAGS(SvBasicDemo::AccessTypes)

}
}
}
}

QT_END_NAMESPACE
#endif

The result in qt designer property editor is shown as below: enter image description here

You can see property enum_prop (use custom enum) and flag_prop_2 (use built in flag Qt::Alignment) works as expected. But property flag_prop is missing.

I have study the code in "%QT_ROOT%\Qt5.6.0\5.6\msvc2013\include\QtWidgets\qgraphicsview.h"。 And did not figure out why.

Could anyone give me some hint about why it does not work as expected? Thanks in advance.


Solution

  • After tried many times, finally solved this issue. The key point is:

    1. It seems MEMBER keyword does not work with Q_FLAGS property;

    2. Q_DECLARE_OPERATORS_FOR_FLAGS macro must used in global namespace;

      namespace Company {
      
          namespace Product {
          namespace Widget {
          namespace Basic {
          class QDESIGNER_WIDGET_EXPORT SvBasicDemo : public SvBasicWidget
          {
              Q_OBJECT
                  Q_FLAGS(AccessTypes)
                  Q_PROPERTY(QString url_prop MEMBER url_prop NOTIFY propertyChange)
                  Q_PROPERTY(Priority enum_prop MEMBER enum_prop NOTIFY propertyChange)
                  // Q_PROPERTY(AccessTypes flag_prop MEMBER flag_prop NOTIFY propertyChange) // Cannot use MEMBER here, otherwise, the property will not show on qt designer property editor. I don't know why.
                  Q_PROPERTY(AccessTypes flag_prop READ getAccessTypes WRITE setAccessTypes)
                  Q_PROPERTY(Qt::Alignment flag_prop_3 MEMBER flag_prop_2 NOTIFY propertyChange)
      
          Q_SIGNALS:
          void propertyChange();
      
          public slots:
          void updateProperty();
      
      public:
          SvBasicDemo(QWidget *parent = 0);
          virtual void refresh_binding_cb();
          virtual QString help_info() const;
      
          enum Priority { High, Low, VeryHigh, VeryLow };
          Q_ENUM(Priority)
      
          enum AccessType { None = 0x0, Read = 0x1, Write = 0x2 };
          Q_DECLARE_FLAGS(AccessTypes, AccessType)
      
          inline AccessTypes getAccessTypes() const
          {
              return flag_prop;
          }
          inline void setAccessTypes(AccessTypes features)
          {
              flag_prop = features;
          }
      
      private:
          QString url_prop;
          Priority enum_prop;
          AccessTypes flag_prop;
          Qt::Alignment flag_prop_2;
          QLabel label;
      };
      }
      }
      }
      }
      // must use this macro outside namespace
      Q_DECLARE_OPERATORS_FOR_FLAGS(Company::Product::Widget::Basic::SvBasicDemo::AccessTypes)