Когда я должен использовать 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;
}