Когда я должен использовать qApp->setProperty на Qt

В документации по Qt я не нахожу раздел, объясняющий qApp->setProperty() вариант (возможно, он есть, но я не могу его найти). Может кто-нибудь объяснить мне, в основном, как это работает и когда я должен его использовать?

Я спрашиваю об этом, потому что мне нужно определить путь к файлу моей базы данных как "глобальную константу", которая будет использоваться во многих классах, поэтому я подумал об установке его с помощью setProperty функция.

Например:

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

Затем получите к нему доступ, используя:

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

Могу ли я сделать это или есть лучший / правильный способ сделать это?

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 указатель, к которому может обращаться вся ваша программа

Свойства предоставляются QObject, который QApplication это.

Используемые вами свойства являются так называемыми динамическими свойствами и очень полезны, когда у вас есть объект, который вы не можете изменить другим способом, но вам нужно добавить к нему некоторые дополнительные данные.

Обратите внимание, что передача строковых литералов в действительно плохой стиль property или же 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;
}
Другие вопросы по тегам