如何在 QT 中使用标志作为自定义小部件 属性 类型?
How to use flags as custom widget property type in QT?
我无法将标志用作 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 属性编辑器中的结果如下图所示:
您可以看到 属性 enum_prop(使用自定义枚举)和 flag_prop_2(使用内置标志 Qt::Alignment)按预期工作。但是 属性 flag_prop 不见了。
我研究了"%QT_ROOT%\Qt5.6.0.6\msvc2013\include\QtWidgets\qgraphicsview.h"中的代码。没有搞清楚为什么。
谁能给我一些提示,说明为什么它没有按预期工作?提前致谢。
你有没有添加 Q_DECLARE_FLAGS macro? See also the correct usage of 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)
您必须添加 属性 宏和可调用函数才能获取当前选项:
Q_PROPERTY(Option option READ getOption())
Q_INVOKABLE Option getOption() const;
并注册元类型 qRegisterMetaType 或 Q_DECLARE_METATYPE():
Q_DECLARE_METATYPE(MyClass::Option);
经过多次尝试,终于解决了这个问题。重点是:
MEMBER 关键字似乎不适用于 Q_FLAGS 属性;
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)
我无法将标志用作 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 属性编辑器中的结果如下图所示:
您可以看到 属性 enum_prop(使用自定义枚举)和 flag_prop_2(使用内置标志 Qt::Alignment)按预期工作。但是 属性 flag_prop 不见了。
我研究了"%QT_ROOT%\Qt5.6.0.6\msvc2013\include\QtWidgets\qgraphicsview.h"中的代码。没有搞清楚为什么。
谁能给我一些提示,说明为什么它没有按预期工作?提前致谢。
你有没有添加 Q_DECLARE_FLAGS macro? See also the correct usage of 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)
您必须添加 属性 宏和可调用函数才能获取当前选项:
Q_PROPERTY(Option option READ getOption())
Q_INVOKABLE Option getOption() const;
并注册元类型 qRegisterMetaType 或 Q_DECLARE_METATYPE():
Q_DECLARE_METATYPE(MyClass::Option);
经过多次尝试,终于解决了这个问题。重点是:
MEMBER 关键字似乎不适用于 Q_FLAGS 属性;
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)