Q_PROPERTY compile problem
I'm starting to want to use the Q_PROPERTY system for a specific case. I have a class with a member which contains the information used in various modeless dialogs. However, since these dialogs are modeless, the information might be altered while they are running. So I thought of transforming this member into a Q_PROPERTY with a NOTIFY signal that I could then connect to the dialogs so they'd refresh themselves should this data be altered. However, the member is now no longer detected as a class data member and thus the class fails to compile (giving hundreds of "undeclared identifier" errors).
The class declaration is the following:
Code:
class Canvas : public QSFMLCanvas
{
Q_OBJECT
Q_PROPERTY(std::vector<Fault> faults READ GetFaults WRITE SetFaults NOTIFY FaultsEdited)
Q_PROPERTY(std::vector<Horizon> horizons READ GetHorizons NOTIFY HorizonsEdited)
/*...*/
//std::vector<Fault> faults;
//std::vector<Horizon> horizons;
/*...*/
public:
std::vector<Fault> GetFaults() const;
void SetFaults(std::vector<Fault> v);
std::vector<Horizon> GetHorizons() const;
/*...*/
signals:
void FaultsEdited();
void HorizonsEdited();
};
As well, should I uncomment the original data members, it compiles just fine, but the NOTIFY signal is not emitted.
Re: Q_PROPERTY compile problem
Create your obvious private members.
In the rest of the code, use the property functions like getFaults and setFaults.
Re: Q_PROPERTY compile problem
They are created. The compiling problem isn't with the functions, but with the data members, faults and horizons.
1>.\Canvas.cpp(74) : error C2065: 'faults' : undeclared identifier
1>.\Canvas.cpp(78) : error C2065: 'horizons' : undeclared identifier
Re: Q_PROPERTY compile problem
Not in the header you posted.
You need a member that can store the values you set and get.
Re: Q_PROPERTY compile problem
Wait, in the examples in the doc (http://doc.trolltech.com/latest/prop...simple-example), the member is given in the Q_PROPERTY line and never again.
Code:
Q_PROPERTY(Priority priority READ priority WRITE setPriority)
It later defines the enum type Priority, but doesn't create a member priority.
So, as I understand, the macro already creates the data member.
As well, should I uncomment the original data members (which are commented in the given header), it compiles just fine, as stated in the OP. However, the signal is not emitted. Even if the value is altered via the WRITE function.
I mean, I'm not supposed to manually emit() the signal from within the WRITE function, right? That's precisely what the NOTIFY keyword is supposed to do for me, right?
EDIT: Just read this, which cleared my doubt regarding the variable declaration, but there's still the issue of the signal not being emitted.
Re: Q_PROPERTY compile problem
Quote:
but there's still the issue of the signal not being emitted.
This is an implementation issue, with out the code responsible for it, its hard to tell what you are doing wrong.
Re: Q_PROPERTY compile problem
As a pure test, I created a bogus slot in Canvas (::asd()).
I then did the following:
Code:
class Canvas : public QSFMLCanvas
{
Q_OBJECT
Q_PROPERTY(std::vector<Fault> faults READ GetFaults WRITE SetFaults NOTIFY FaultsEdited)
Q_PROPERTY(std::vector<Horizon> horizons READ GetHorizons NOTIFY HorizonsEdited)
std::vector<Fault> faults; //contains all faults in project
std::vector<Horizon> horizons; //contains all horizons in project
public:
Canvas
(const QPoint
& Position,
const QSize
& Size,
QWidget* Parent
=0);
Canvas();
std::vector<Fault> GetFaults() const;
void SetFaults(std::vector<Fault> v);
std::vector<Horizon> GetHorizons() const;
public slots:
void asd();
signals:
void FaultsEdited();
void HorizonsEdited();
};
Canvas::Canvas()
{
//...
connect(this,SIGNAL(FaultsEdited()),this,SLOT(asd()));
std::vector<Fault> v;
v.push_back(Fault());
SetFaults(v);
//...
}
void Canvas::SetFaults(std::vector<Fault> v)
{
faults=v;
}
void Canvas::asd()
{
int u=1;
}
I run this in Debug Mode with a breakpoint inside asd() so that, should the signal be emitted and received, the program simply stops at the breakpoint. This is a quick and easy method I use often.
But this time, nothing happens, telling me the signal wasn't emitted. Again, I don't have to emit the NOTIFY signal myself, do I? The macro should do that for me, right?
Re: Q_PROPERTY compile problem
There is no magic there. Qt won't do your work for you. Q_PROPERTY only marks certain things as available for the property system but you have to implement all the getters and setters yourself. Including all signal emissions. Only you know what should happen inside a setter and if you just add "emit FaultsEdited();" in your setter then this will not be a proper solution. You can only emit the signal if the contents of the property really changed.
Code:
void Canvas::SetFaults(std::vector<Fault> &v) {
if(faults==v) return;
faults = v;
emit FaultsEdited();
// better yet: emit FaultsEdited(faults);
}
Re: Q_PROPERTY compile problem
Ah, okay. I thought that Q_PROPERTY was just as magic-imbued as SIGNALS and SLOTS. I also thought that there might be uses for it outside of the Meta-Object System. But that answers all my doubts. Merci.
Re: Q_PROPERTY compile problem
Quote:
Originally Posted by
Wasabi
Ah, okay. I thought that Q_PROPERTY was just as magic-imbued as SIGNALS and SLOTS.
Not that much. There are properties that are not mapped to fields in the class so if Qt did that automatically, it would bring needless memory overhead. Just look at QWidget - there are a couple of properties related to geometry of the widget (geometry, pos, rect, size, width, height, x, y) but they all work on one single rectangle.