1

在Qt文档中,我没有找到解释该qApp->setProperty()选项的部分(它可能在那里,但我找不到)。有人可以基本上向我解释它是如何工作的,我应该什么时候使用它?

我问它是因为我需要将我的数据库文件的路径定义为“全局常量”,以便在许多类中使用,所以我正在考虑使用该setProperty函数设置它。

例如:

qApp->setProperty("DATABASE_PATH", "C:/../Database.db");

然后,使用以下命令访问它:

qApp->property("DATABASE_PATH").toString();

我可以这样做还是有更好/正确的方法可以这样做?

4

2 回答 2

2

此功能不会显示在QApplication 文档的主视图中。

在此页面上有一个部分称为:所有成员列表,包括继承的成员,在其中您将找到您拥有的所有属性或独占或您的父类。

寻找这个功能建立在QObject

bool QObject::setProperty(const char *name, const QVariant &value)

将对象的 name 属性的值设置为 value。

如果使用 Q_PROPERTY 在类中定义属性,则成功时返回 true,否则返回 false。如果该属性未使用 Q_PROPERTY 定义,因此未在元对象中列出,则将其添加为动态属性并返回 false。

有关所有可用属性的信息通过 metaObject() 和 dynamicPropertyNames() 提供。

动态属性可以使用 property() 再次查询,并且可以通过将属性值设置为无效的 QVariant 来删除。更改动态属性的值会导致将 QDynamicPropertyChangeEvent 发送到对象。

注意:以“ q ”开头的动态属性是为内部目的而保留的。

另请参见 property()、metaObject()、dynamicPropertyNames() 和 QMetaProperty::write()。

setProperty用于通过其名称公开属性,如果您可以在您的情况下使用它,因为它qApp是一个可以被整个程序访问的指针。

于 2017-05-31T18:57:57.990 回答
1

属性由 提供QObject,即QApplication-a。

您使用的属性是所谓的动态属性,当您有一个无法以其他方式修改但需要向其添加一些额外数据的对象时非常有用。

请注意,将字符串文字传递给propertyor是一种非常糟糕的风格setProperty:您很容易让拼写错误潜入。因此,属性只能与唯一的常量名称一起使用:

// common code
// proplist.h

PROPLIST_PROP(databasePath)
PROPLIST_PROP(foo)

// interface
// properties.h

#define PROPLIST_PROP(name) static const char name[];
struct Prop {
  #include "proplist.h"
};
#undef PROPLIST_PROP

// implementation
// properties.cpp

#define PROPLIST_PROP(name) const char Prop::name[] = #name;
#include "proplist.h"

// use
obj.setProperty(Prop::databasePath, ...);
auto path = obj.property(Prop::databasePath).toString();

您可以封装属性的类型名称:

// common code
// proplist.h

PROPLIST_PROP(QString, databasePath)
PROPLIST_PROP(int, foo)

// interface
#define DECLARE_PROPERTY(type_, name_) using name_ = Property<type_, struct name_>;
#define DEFINE_PROPERTY(type_, name_) const char name_::name[] = #name_;

template <typename T, typename Tag> Property {
  static const char name[];
  static T get(QObject * obj) {
    return obj->property(name).value<T>();
  }
  static void set(QObject * obj, const T& val) {
    obj->setProperty(name, QVariant::fromValue(val));
  }
};

#define PROPLIST_PROP DECLARE_PROPERTY
namespace Prop {
  #include "proplist.h"
}
#undef PROPLIST_PROP

// implementation
#define PROPLIST_PROP DEFINE_PROPERTY
namespace Prop {
  #include "proplist.h"
}    

// use
Prop::DatabasePath::set(obj, ...);
auto path = Prop::DatabasePath::get(obj);

我看到的主要问题是您很可能正在滥用属性系统,而可能会从全局设置对象中受益:

// interface
struct SettingsData {
  SettingsData() { Q_ASSERT(!m_instance); m_instance = this; }
  ~SettingsData() { m_instance = nullptr; }
  static SettingsData * instance() { return m_instance; }

  QString databasePath = "some default value";
  int gizmoSize = 44;
private:
  static SettingsData * m_instance;
};

SettingsData & Settings() { return *SettingsData::instance(); }

// implementation
SettingsData * SettingsData::m_instance;

// use
int main(int argc, char ** argv) {
  QApplication app(argc, argv);
  SettingsData settings;
  ...
}

void test() {
  Settings().databasePath = ...;
  auto path = Settings().databasePath;
}
于 2017-06-02T19:48:32.127 回答