openKylin论坛

 找回密码

Qt Q_PROPERTY [复制链接]

本帖最后由 kylin_try 于 2013-10-21 13:47 编辑

class IconEditor : public QWidget
{
  Q_OBJECT

private:
  QColor curColor;
  .
  .
public:
   QColor penColor() const
      { return curColor; }
   void setPenColor(const QColor &newColor);
};
我这样给类添加了属性方法。

/////////  二   /////////
class IconEditor : public QWidget
{
   Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor);

private:
   QColor curColor;  
  .
  .
public:
   QColor penColor() const
      { return curColor; }
   void setPenColor(const QColor &newColor);
};

用Q_PROPERTY的目的是将属性注册到Qt的meta object system中(类似与Java的反射机制)。这样你也可以用比如 QObject::setProperty()的方法来访问这个属性。而你如果直接调用penColor()或者setPenColor()的话,就不需 要用Q_PROPERTY来注册这个属性。
一个界面类里面用到了属性,把这个类封装成控件,就会在UI编辑器里面看到你添加的属性,和原来就存在的属性(如:geometry )一样在UI编辑器里面修改属性值。Q_PROPERTY 介绍 .
QT提供了一个成熟的属性系统,但是作为一个跨平台的且与编译器无关的库,qt不依赖于非标准的编译器功能例如 __property or [property];
QT的强大之处在于它可以支持任何标准的c++编译器。 QT是基于 Meta-Object System(元对象)和signals and slots(信号槽)的.

可能还不太好理解 不过下面介绍几个特殊的例子你就豁然开朗了
[cpp] view plaincopy? Q_PROPERTY(bool focus READ hasFocus)  

  • Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
  • Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)

一个属性行为类似于类里面的数据成员,但是他是却可以通过Meta-Object System来访问。
  

Q_PROPERTY
Q_PROPERTY()是一个宏,用来在一个类中声明一个属性property,由于该宏是qt特有的,需要用moc进行编译,故必须继承于QObject类。
Q_PROPERTY(type name READ getFunction [WRITE setFunction] [RESET resetFunction] [NOTIFY notifySignal] [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] [USER bool] [CONSTANT] [FINAL])可能还不太好理解 不过下面介绍几个特殊的例子你就豁然开朗了

Q_PROPERTY(bool focus READ hasFocus) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)一个属性行为类似于类里面的数据成员,但是他是却可以通过Meta-Object System来访问。
  
在外界看来,property跟类中数据成员没有什么区别,但是还是有几点不一样,参考qt文档,主要有以下几点:
1.必须有一个read函数。它用来读取属性值。因此用Const限定。它的返回值类型必须为属性类型或者属性类型的引用或者指针。不能是其他类型例如:QWidget::hasFocus().  
2.有一个可选的write函数。它用来设置属性值,它的返回值必须为void型,而起必须要含有一个参数。例如:QWidget::setEnabled()
3.一个reset函数能够把property设置成其默认状态,它也是可选的。复位功能必须返回void,并且不带参数,
4.一个NOTIFY信号是可选的 。如果定义,它提供了一个信号这个信号在值发生改变时会自动被触发。

5.如果定义了"STODE"属性表明这是一直存在的。QWidget::minimumSize()
6.一个"DESIGNABLE"属性表明该property能在GUI builder(一般为Qt Designer)可见
7 USER 属性 表面是否可以被用户所编辑
8  CONST 设定属性是不可修改的 所以不能跟WRITE或者NOTIFY同时出现
9  FINAL 表明该属性不会被派生类中重写


**********************************************************************************************
class Test : public QObject
{
Q_OBJECT
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
public:
Test(QObject *parent = 0) : QObject(parent) {}
virtual ~Test(){}
void setEnabled(bool e) { enabled = e; }
bool isEnabled() const { return enabled; }
private:
bool enabled;
};
然后在主函数中
Test *test = new Test;
test->setProperty("enabled", true);
//test->setEnabled(true);        //ok also work
if(test->property("enabled").toBool())
***************************************************************************************************
内省 intropection   运行时查询对象信息
  • //每个对象可以通过QObject::setObjectName()和QObject:bjectName()设置、取得类的实例的名字
  • FirstQtApp obj;
  • obj.setObjectName("instanceName");
  • QString name1 = obj.objectName();   // return instanceName
  • //每个对象还可以通过它的元对象className方法得到类的名字
  • QString name2 = obj.metaObject()->className();  // return FirtstQtApp
  • //每个对象可以通过QObject::inherits方法来查询是否对前对象类派生于量一个类
  • bool isherited =  obj.inherits("QObject");         // returns true
  • isherited =  obj.inherits("QWideget");         // returns true
让我们再来一下QObject::inherits方法的底层实现:
inline bool inherits(const char *classname) const
  { return const_cast<QObject *>(this)->qt_metacast(classname) != 0; }

总结:
1.  Qt是通过QObject、QMetaObject类实现其内省机制,
2.  QObject暴露给用户的共有自省方法有objectName(), inherits(), isWidgetType()等
3.  大多数自省方法是QObject派发给QMetaObject实现 (e.g. QMetaObject::className,),元对象模型编译器moc负责自省方法的实现
4.  更多自省方法定义在QMetaObject,而是为了等信号槽通讯、事件派发等机制
转:http://www.360doc.com/content/12/1209/21/9200790_253101156.shtml#




楼主
发表于 2013-10-15 21:14:05
回复

使用道具 举报

openKylin

GMT+8, 2024-6-1 14:32 , Processed in 0.018207 second(s), 17 queries , Gzip On.

Copyright ©2022 openKylin. All Rights Reserved .

ICP No. 15002470-12 Tianjin

快速回复 返回顶部 返回列表