Solved using qobject_cast with QFutureWatcher
-
Hi,
Inside a slot, I want to access the result property of my watcher.
In my constructor, I haveQFutureWatcher<bool> *watcher = new QFutureWatcher<bool>; QFuture<bool> future; connect(watcher, SIGNAL(finished()), this, SLOT(handle_db_connection())); connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater())); future = QtConcurrent::run([=](){return db->init();}); watcher->setFuture(future);
In the slot handle_db_connection, I want to test the value of the bool return by the thread.
Here is the implementation of my slotvoid MainWindow::handle_db_connection() { QFutureWatcher<bool> *watcher = qobject_cast<QFutureWatcher<bool>*>(sender()); if(!watcher->result()){ // Put actions here } }
However at compilation time, the compilers tells me that QObject_cast requires the Q_OBJECT marco. Does it mean that the QFutureWatcher class does not have that macro in its definition? In my class
MainWindow
, I have put the macro.If it's the case, any idea of how to retrieve the value of the watcher in the slot?
Thanks!
-
You can only use qobject_cast<> if the class is derived from QObject. If it's not the case then you have to use other ways like e.g. dynamic_cast<> or static_cast<>.
-
@Christian-Ehrlicher
You mean my MainWindow class? Because this class derives fromQMainWindow
-
@Thombou said in using qobject_cast with QFutureWatcher:
You mean my MainWindow class?
I don't see where a MainWindow is involved in your qobject_cast... it's
qobject_cast<QFutureWatcher...>
-
@Christian-Ehrlicher
That is what thought, it is related to the destination type. But then I dont understand because QFutureWatcher derives from QObject -
@Thombou
Yes, QFutureWatcher derives from QObject but does not have the Q_OBJECT marco.
You can see that from qfuturewatcher.h
I think maybe Q_OBJECT macro cannot be used in a template class.
You can use a lambda here as a slot. -
Hi,
Why not make the watcher a member of your MainWindow class ?
Or are you expecting to create other watchers ? -
@SGaist I dont know what are the general good practices... I asked a question about it some days ago but it has not got any reply yet. If I only use the watcher once, does it need to be a member of the class? I thought that I should only put objects as member when they are reused several times.
Any advice is welcome :) -
Then a follow-up question. What are you doing in that thread ? Seems you are doing some database setup but that makes it look like you are about to do some nasty stuff with regard to Qt's SQL module.
-
@SGaist Indeed I was starting a database connection. However I removed this because I found out that if I start a connection to a database in a thread, then I cannot use it from another thread. I was doing so becasue when the database server is not found, it takes time until db.open() returns false, and during this time, the main window dost not show up and is not responsive.
At the end I removed the thread thing, but because I might need it in the future to run expensive computation tasks, I'm still interested in knowing how to use it properly to avoid blocking the main thread (and the event loop).To continue on good practices, here is the topic I have wrote some days ago and I describe what I want to do. and some questions that are related.
Just a question: I understood that it is good in general to separate operations on the database (model side) from operations on the view side. Therefore I thought that writing a class that would handle all database requests and return pointers to the different models created would be a good idea. It would also take care of the inserts etc. Is that a good way to work with the QtSql module? In the constructor of my database class I check is there is not already an existing connection. -
@SGaist what you suggest if we are expecting to create other watchers and we need to recover it on slot to read some property from them?
-
@Juan-Garcia hi,
What kind of properties do you have in mind ?
Are you thinking of creating a lot of watchers ?