-
-
Save Rolias/48d453a0490d36090193 to your computer and use it in GitHub Desktop.
#pragma once | |
#include <QObject> | |
//See Gist Comment for description, usage, warnings and license information | |
#define AUTO_PROPERTY(TYPE, NAME) \ | |
Q_PROPERTY(TYPE NAME READ NAME WRITE NAME NOTIFY NAME ## Changed ) \ | |
public: \ | |
TYPE NAME() const { return a_ ## NAME ; } \ | |
void NAME(TYPE value) { \ | |
if (a_ ## NAME == value) return; \ | |
a_ ## NAME = value; \ | |
emit NAME ## Changed(value); \ | |
} \ | |
Q_SIGNAL void NAME ## Changed(TYPE value);\ | |
private: \ | |
TYPE a_ ## NAME; | |
#define READONLY_PROPERTY(TYPE, NAME) \ | |
Q_PROPERTY(TYPE NAME READ NAME CONSTANT ) \ | |
public: \ | |
TYPE NAME() const { return a_ ## NAME ; } \ | |
private: \ | |
void NAME(TYPE value) {a_ ## NAME = value; } \ | |
TYPE a_ ## NAME; |
12/4/2014 Fixed wayward pair of {} after private type declaration.
This is a great idea, but unfortunately, setProperty does not work with this. The reason is that moc does not create the property because it doesn't understand the AUTO_PROPERTY macro. Do you know a solution for this?
Update: Aha! Moc does expand macros, since Qt5. I only have to take care that moc has the same include path as the C++ compiler, or otherwise make sure that moc actually finds PropertyHelper.h.
Hi, thanks for your great working
I have some ideas for updating the file.
-
Use reference in function
WRITE
inAUTO_PROPERTY
void NAME(const TYPE& value)
-
Remove function
WRITE
inREADONLY_PROPERTY
void NAME(TYPE value) {a_ ## NAME = value; }
-
Add define
READ_PROPERTY
with the Q_SIGNAL for qml can get the notify when property changed in C++.
QML can not change the property.
You can see details in https://gist.github.com/tackelua/bcae0e346fc98184ba7a044315fd0a4c/revisions#diff-b6a69a742adff907546e80f3703e301a
Overview
These macros are intended to reduce the amount of boilerplate code the user has to write when using the Qt Frameworks's Q_PROPERTY feature. The idea was to provide something similar to C#'s auto property feature.
I was after the lack of clutter not the syntax. This file contains two macros.
The First Macro
It will create a standard
macro of the passed type and name. In addition, it will create a standard getter named NAME, setter named Name and signal named NAMEChanged(TYPE value) It will also create the member data variable. Note it does not use the more standard setName syntax, mostly because I didn't know how to do the capitalization trick. The member var is named with an
a_
prefix because it is intended to remind the user to NOT use the member variable name directly. The user should use the property name instead. If you don't like thea_
prefix change the macro.The Second Macro
will create a standard
It will create the getter and the member variable name. It also creates a private setter function. The function is just named NAME, i.e. it doesn't use a set prefix. In this macro, the member variable again uses
a_
but the user is expected to initialize this variable directly. All reads of the variable should be done through the property for consistency.Example Usages
Usage Notes
Use these macros in the
private:
section of your header only. They use bothpublic
andprivate
keywords and leave the header in the private section. Putting these macros directly under theQ_OBJECT
macro at the top of the class is acceptable. If for some reason you have to use these macros in the public section it is your responsibility to add the public: keyword after the macro.Warning!
Note that these macros are only intended to be used as shown. The parameters are NOT intended to be expressions but simply the type and name. The parameters aren't parenthesized in the body of the macro and the entire macro is not parenthesized. Enjoy responsibly.
Note on Initializers
If you uses these macros at the top of your class then the member variables they create will be the first ones in your class. Therefore, to make tools like lint happy, you should add these variables to your initializer list in the order they are declared; before any variables that come after these macros. If you want to fully initialize variables in the order they are declared then even
AUTO_PROPERTY
created variables will need to be accessed directly. There is no harm in doing this. In general I was trying to adhere to the philosophy of the member variables being hidden and only the property being used.