如何在QT中使用标志作为自定义小部件属性类型?

时间:2017-02-20 09:57:41

标签: c++ qt qt-designer qtplugin

我很难将标志用作QT自定义窗口小部件属性类型。期望的属性不会显示在QT Designer属性编辑器中。

代码如下:

#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

qt designer属性编辑器的结果如下所示: enter image description here

您可以看到属性enum_prop(使用自定义枚举)和flag_prop_2(使用内置标志Qt :: Alignment)按预期工作。但缺少属性flag_prop。

我研究过“%QT_ROOT%\ Qt5.6.0 \ 5.6 \ msvc2013 \ include \ QtWidgets \ qgraphicsview.h”中的代码。并且没有找出原因。

有人能给我一些暗示,为什么它不按预期工作?提前谢谢。

2 个答案:

答案 0 :(得分:1)

经过多次尝试,终于解决了这个问题。关键点是:

  1. 似乎MEMBER关键字不适用于Q_FLAGS属性;

  2. Q_DECLARE_OPERATORS_FOR_FLAGS宏必须在全局命名空间中使用;

    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)
    

答案 1 :(得分:0)

您是否添加了Q_DECLARE_FLAGS宏?另请参阅Q_FLAGS()

的正确用法

这是WindowsStateFlags定义的一个示例:

class MyClass
{
public:
    enum Option {
        NoOptions = 0x0,
        ShowTabs = 0x1,
        ShowAll = 0x2,
        SqueezeBlank = 0x4
    };
    Q_DECLARE_FLAGS(Options, Option)
    Q_FLAGS(Options)
    ...
};

Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::Option)

您必须添加属性宏和可调用函数才能获得curren选项:

Q_PROPERTY(Option option READ getOption())
Q_INVOKABLE Option getOption() const;

注册元类型qRegisterMetaType或Q_DECLARE_METATYPE():

Q_DECLARE_METATYPE(MyClass::Option);