Properties are provided by QObject
, which QApplication
is-a.
The properties you're using are so-called dynamic properties and are very useful when you have an object that you can't otherwise modify, but need to add some additional data to it.
Note that it's really bad style to pass string literals to property
or setProperty
: you can easily let typos sneak in. Because of that, properties should only be used with unique constant names:
// 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();
You can encapsulate the type and the name of a property:
// 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);
The major issue I see is that most likely you're abusing the property system and instead might benefit from a global settings object:
// 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;
}