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

问题描述:

我有麻烦使用标志作为QT自定义小部件属性类型。期望的属性不会显示在QT Designer属性编辑器上。如何在QT中使用标志作为自定义小部件属性类型?

的代码如下:

#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设计师的属性编辑器,结果如下图所示: 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”中的代码,并没有弄清楚原因。

任何人都可以给我一些暗示,为什么它不能按预期工作?提前致谢。

+0

可能是你不得不暴露潜在的枚举元对象模型。尝试添加'Q_ENUM(AccessType)' –

+0

@king_nak仍然无法工作 – ricky

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

  1. 看来MEMBER关键字不能与Q_FLAGS属性一起使用;

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

    命名空间公司{

    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) 
    

您是否添加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); 
+0

非常感谢您的回复。在我原来的文章中,我使用下面的代码在qgraphicsview.h中使用这些宏,如下所示:'Q_FLAGS(SvBasicDemo :: AccessTypes)Q_DECLARE_FLAGS(AccessTypes,AccessType)Q_DECLARE_OPERATORS_FOR_FLAGS(SvBasicDemo :: AccessTypes)'''Is我的代码有问题吗?有没有关于命名空间的事情? – ricky