PDA

View Full Version : Qt5 result of connect() call



RolandHughes
10th June 2015, 16:20
In the good ole days of Qt 4 many places I worked had a policy of checking connect() results something like this:

bool rslt=true;

rslt &= connect( blah...)
rslt &= connect( blah...)
rslt &= connect( blah...)
rslt &= connect( blah...)
rslt &= connect( blah...)

if (!rslt) do someting

I'm now using qt5.4 from the _run file on Ubuntu 12.4.5 32-bit. According to the Assistant connect() is supposed to return QMetaObject::Connection. Ok, fine. According to the Assistant documentation one #include <Connection> should obtain a class definition which has a bool() method.

Problem 1: There is no Connection header file, but the IDE does seem to recognize the class.
Problem 2: There is no bool() method shown in the list of options. There is an operator RestrictedBool and something else called RestrictedBool

I _assume_ the doc hasn't caught up to the coding changes. Just want to know how I'm supposed to actually check it now. Hopefully the doc only has the header file wrong and this can quickly be resolved.

Thanks,

d_stranz
10th June 2015, 16:44
Connection is a class defined within QMetaObject. You use the QMetaObject header to include it, but this is already done for you if you include the header for any QObject-derived class.

QMetaObject::Connection has a bool() cast operator (QMetaObject::Connection::bool()) which means your current code will continue to work just fine because C++ will cast the Connection object returned by connect() to a bool (which will be set to the status of the connect() call).

You can verify this by using the debugger to examnine the content of your "rslt" variable after the connect call. I presume you initialize it to "true" before using it in "&=", right?

RolandHughes
10th June 2015, 17:58
Connection is a class defined within QMetaObject. You use the QMetaObject header to include it, but this is already done for you if you include the header for any QObject-derived class.

QMetaObject::Connection has a bool() cast operator (QMetaObject::Connection::bool()) which means your current code will continue to work just fine because C++ will cast the Connection object returned by connect() to a bool (which will be set to the status of the connect() call).

You can verify this by using the debugger to examnine the content of your "rslt" variable after the connect call. I presume you initialize it to "true" before using it in "&=", right?

Yes, I init the bool.

I would verify it if it would compile. This method, which always worked in Qt4, seems busted now.


bool rslt=true;

rslt &= connect( &m_appProcess, SIGNAL(aboutToClose()), this, SLOT(appClosed()));
if (!rslt)
qDebug() << "unable to connect all signals and slots";


/home/developer/MyWatchdog/mywrapper.cpp:26: error: no match for 'operator&=' in 'rslt &= QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)(qFlagLocation(((const char*)"2finished(int,QProcess::ExitStatus)\000../MyWatchdog/mywrapper.cpp:26")), ((const QObject*)(&((MyWrapper*)this)->MyWrapper::<anonymous>)), qFlagLocation(((const char*)"1appShutDown(int,QProcess::ExitStatus)\000../MyWatchdog/mywrapper.cpp:26")), (Qt::ConnectionType)0u)'

Changing rslt &= to just rslt = makes it compile clean. Of course I have many other connects so that isn't a solution. m_appProcess is just a QProcess object declared as a member variable.

If I do an __ugly__ hack, declare bool yn then assign the result of the connect directly to it, then rslt &= yn; things work, but it makes for some mighty ugly code.

Btw, I had to change names of files and variables in that error message so please don't pick at it too closely.

d_stranz
10th June 2015, 18:12
So do an explicit cast: rslt &= bool( connect( ... ) ); The compiler is complaining because bool operator&=() const is not defined for QMetaObject::Connection.

Lesiok
10th June 2015, 18:14
Because QMetaObject::Connection don't have defined operator & (bitwise AND).
rslt &= another_rslt is equivalent to rslt = rslt & another_rslt. This is not the same as rslt = rslt && another_rslt.

RolandHughes
10th June 2015, 18:34
So do an explicit cast: rslt &= bool( connect( ... ) ); The compiler is complaining because bool operator&=() const is not defined for QMetaObject::Connection.

Thanks, but not allowed. It's a coding standards thing. Not my rules, I just charge by the hour.

wysota
10th June 2015, 18:41
Thanks, but not allowed. It's a coding standards thing. Not my rules, I just charge by the hour.

Then either define that operator yourself or rewrite the code to use X = X && Y syntax. Or better yet rewrite it to something more useful, e.g. series of if(!connect(...)) { ...; return; } as it probably makes little sense to make further connections if earlier ones fail.

RolandHughes
12th June 2015, 15:43
@wysota,

I originally had a series of if statements, but that is not the standard here. I do what the client pays for. Thanks for your input though.

d_stranz
12th June 2015, 17:41
Seems like the client needs some re-education. But you're not being paid for that, you're being paid to write to the "standard". Guarantees that the same mistakes will keep being perpetuated so that future developers will think it's OK. Sure glad I work for myself and by own rules (which, being malleable, can be changed as needed to keep them up to date).