Use a QTimer or don't use a QTimer, doesn't matter to me...
Use a QTimer or don't use a QTimer, doesn't matter to me...
Okay. So here is my revised code. Is this okay?
QueryView.hpp:
QueryView.cpp:
Qt Code:
QueryView::QueryView() { connect(SignalClass.get(),SIGNAL(updateViewSignal(QueryTerm&)), this, SLOT(updateView(QueryTerm&))); connect(queryButton, SIGNAL(clicked()),this, SLOT(doQuery())); } void QueryView::doQuery() { emit fSignalClass->stopExistingQuery(); std::shared_ptr<QueryAction> action = std::make_shared<QueryAction>(queryTerm); action->moveToThread(t); t->start(); emit fSignalClass->excuteSignal(); } QueryView::updateView(QueryTerm& term) { ...update view with query result }To copy to clipboard, switch view to plain text mode
QueryAction class:
Qt Code:
QueryAction::QueryAction(QueryTerm& queryTerm): fQueryTerm(queryTerm) { connect(SignalClass.get(), SIGNAL(excuteSignal()), this, SLOT(startSearch())); connect(SignalClass.get(), SIGNAL(stopExistingQuery()), this, SLOT(stopQuery())); continueQuery = true; } void QueryAction::startSearch() { //init cursor while (db_cursor != empty) { ...get query result if (continueQuery) emit fSignalClass->updateViewSignal(aResult); } } void QueryAction::stopQuery() { continueQuery = false; }To copy to clipboard, switch view to plain text mode
You should protect continueQuery with a QMutex and you should also return from startSearch (or break out of while loop) where you check whether continueQuery is true on line 14.
Other than that, does it work?
Okay, so here is my revised QueryAction class:
Qt Code:
//QueryAction.hpp: class QueryAction { QMutex m_mutex; } //QueryAction.cpp QueryAction::QueryAction(QueryTerm& queryTerm): fQueryTerm(queryTerm) { connect(SignalClass.get(), SIGNAL(excuteSignal()), this, SLOT(startSearch())); connect(SignalClass.get(), SIGNAL(stopExistingQuery()), this, SLOT(stopQuery())); continueQuery = true; } void QueryAction::startSearch() { //init cursor while (db_cursor != empty) { ...get query result if (continueQuery) emit fSignalClass->updateViewSignal(aResult); else break; } } void QueryAction::stopQuery() { continueQuery = false; }To copy to clipboard, switch view to plain text mode
Is this correct logic? I haven't tried it yet, for one, this will need a large amount of code change and I am not ready for it now, and secondly, I want to understand it fully before I get my hands dirty, so trying to get my logic right..
Yep yep, of course. Will do the entire code and get back to you..
If this is the cross-thread connection then a reference is not correct (and it would quite uncommon for any type of connection).
Qt Code:
connect(queryAction, SIGNAL(updateViewSignal(QueryTerm)), this, SLOT(updateView(QueryTerm)));To copy to clipboard, switch view to plain text mode
Don't emit another object's signals. This would not even compile in Qt4.
If this is the slot invoked through the cross-thread signal/slot connection then it won't get a reference
Qt Code:
void QueryView::updateView(const QueryTerm& term)To copy to clipboard, switch view to plain text mode
Cheers,
_
Cupidvogel (19th April 2015)
Well, emitting other object's signal does work for me. I ma using Qt 5.3.1, and it works fine like this:
Qt Code:
{ Q_OBJECT public: { } signals: void excuteSignal(); }To copy to clipboard, switch view to plain text mode
And using it like this:
Qt Code:
//somewhere we emit it std::shared_ptr< SignalClass > fSignalClass = std::make_shared< SignalClass >(); emit fSignalClass->randomSignal(fString); //and somewhere else connect it to individual slotTo copy to clipboard, switch view to plain text mode
I will remove the references from cross thread signal-slot connections. Cheers!
Yes, in Qt5 the access level for signals had to be made "public" (was "proteced" before) in order to make the compile time connect() work.
Emitting another object's signals is of course still a very bad idea, they used to be protected for a reason.
Especially in the presence of threads, when QObject thread-affinity matters.
Cheers,
_
Okay, so what other way can I make it work?
Sorry. What I meant is that what other way can I connect a signal from one object to a slot in another? I mean, I can define a signal in the class that raises it and raise it, and I can define a slot in the receiver object, but how do I connect the two in the receiver object?
connect() always works the same way:
I.e. the code that runs the connect() needs access to both objects.Qt Code:
connect(sender, SIGNAL(...), receiver, SLOT(...));To copy to clipboard, switch view to plain text mode
Whether none, one or both of these objects is "this" doesn't matter to connect().
Cheers,
_
Cupidvogel (19th April 2015)
Yeah, that is definitely one way of doing it, but I did not do it because it would introduce cyclic dependency, that is A will include B and B will include A, etc. But I will make it work anyhow. In the mean time, I tried out the entire revised code.
The query results are coming out correctly, I am applying a qDebug() on them when they are generated and they are printed correctly. But the view is not being updated through the signal/slot. I am getting this debugging message:
Qt Code:
(Make sure 'std::shared_ptr< QueryResult >' is registered using qRegisterMetaType().) //this starts coming from the qDebug() statement... Query result: context of a process and investigates the Query result: this proved it as becauseTo copy to clipboard, switch view to plain text mode
How can I make it work?
Bad news. To temporarily check whether it actually works, instead of passing QueryResult to the slot in the view, I just passed QString and made the view display it as a QPushButton. It is hanging even more than before I multithreaded it. Previously the app was stalling and freezing, but now it is completely hanging, and not being restored until the querying is complete. I verified, the thread ids for the Action thread and main thread are different.
How does that introduce a dependency of any sort, much less a cyclic one?
Neither receiver nor sender need to know about each other!
Seems like you have an argument type that you did not register with the Qt type system, as explained earlier by jefftee.
Especially the shared_ptr looks strange given that you should have a "const QueryResult&" as the argument type for both signal and slot.
So make sure that
1) your QueryResult class has been marked with Q_DECLARE_METATYPE
2) your QueryResult class has been registered with qRegisterMetaType()
3) your signal has a signature with either "QueryResult" or "const QueryResult&" as its argument type
4) your slot has a matching signature.
Cheers,
_
I have worked around it.
How do I do it? I found an example here: http://stackoverflow.com/questions/1...eta-type-in-qt, is this how it will work?
Qt Code:To copy to clipboard, switch view to plain text mode
Where do I call the qRegisterMetaType() method on QueryTerm then? And okay, I will change the signature to const QueryAction& instead of std::shared_ptr<QueryAction>.
Okay, I wil try to do it. But in the mean time, performance has not only not improved, it has badly worsened. I am just passing in a dummy QString to the view instead of the QueryAction object to check whether it actually works..
Post your code again please. I have lost track of where your overall code base has morphed since the many posts to this thread have been made. Also, please elaborate on what performance badly worsened means.
Bookmarks