-
[QT4] threads, signals, and slots, please help.
I am in learning Qt phase here, so please bear with me. :)
Imagine a threaded fortune server that serves a different fortune base don a strign you send to it when you conenct. Got the idea? Good.
Now, here is the general shape of what I have:
main_thread
(QtCoreApplication used, no GUI at all)
QTcpServer based class
FortuneDBServerObject (not a *network* server)
connection threads (one per connection)
Essentially the connection threads are "siblings" of the db object, and all are children of the QTcpServer object.
What I need to do is pass a QString (call it StringA) from a connection thread to the FortuneDBServer, and get a response (StringB) back.
I figured I could use a direct connection on the signal to send StringA to the fortunedb object (QObject) with a return value of StringB. Initially I set the signal up inside the thread but that failed wonderfully (i.e. appeared to work but did not). Now I am trying to connect the signal in the QTcpServer class and it is simply nto getting called. At the moment I've changed the dbserver slot to only print it was called and return a static string, just to verify it gets called. Which it does not. No errors, no warnings it just never calls it.
I've tested the networking separately and it all works perfectly. I've even tested the dbserver seperately and it also works perfectly. It is solely the communication bewteen the two I am having difficulty with.
Links, pointers, and example code welcome. Even if it means redesigning it because I have the wrong "model". ;)
-
Re: [QT4] threads, signals, and slots, please help.
Can you post some code of yours here?
-
Re: [QT4] threads, signals, and slots, please help.
Quote:
Originally Posted by wysota
Can you post some code of yours here?
Which part(s) do you want?
In the connection thread I have this:
Code:
if ( has_target ) {
cout << "Have target. " ;
if ( have_terminator ) {
cout << "Have terminator " <<endl;
action = emit getActionForTarget(target);
Which as you can see is where the signal is emitted. The couts before and after the emit do indeed print out.
The QTcpServer based class has:
Code:
void Server::incomingConnection(int socketDescriptor) {
DBServerA* dbserver = &db;
ConnectionThread *thread = new ConnectionThread(socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()), Qt::DirectConnection );
connect(thread, SIGNAL(getActionForTarget()), dbserver, SLOT(getActionForTarget()), Qt::DirectConnection );
thread->start();
}
and the slot in the dbserver (a QObject) is:
Code:
int DBServerA
::getActionForTarget( QString target
) { qDebug() << "getAction called for target" <<target <<endl;
int action = 0;
}
(Yes other debug statements are showing up. ;) )
The original code for the tcpserver came from the qt-interest list, (http://lists.trolltech.com/qt-intere...ad01010-0.html) and as I said works exactly as expected ... except of course that the signal to the dbobject does seem to be getting emitted (or maybe it is but nobody is listening).
-
Re: [QT4] threads, signals, and slots, please help.
You connected the signal
Code:
getActionForTarget()
instead of
You have to fix the SIGNAL and the SLOT. And why do you use direct connections? You can use those only securely when the sending and receiving object are owned by the current thread. Just use the default - Qt should do the right thing ;)
Do you call QThread::exec in your threads to allow event processing of queued events?
-
Re: [QT4] threads, signals, and slots, please help.
Quote:
And why do you use direct connections?
Well that's what the advice was in the link I listed. ;)
As far as calling exec ... no, but other signals/slots are working fine (i.e. the signals from the socket).
.... Added QString as you said and it is now working. Thanks. Why didn't that throw some error or warning at compile time?
-
Re: [QT4] threads, signals, and slots, please help.
Code:
action = emit getActionForTarget(target);
Since when does "emit" have a return value? :)
Maybe you should just "register" an object will return the action and call it directly here instead of such weird statements as the one above?
-
on minor correction ...
The slot is being activated as desired, and has an appropriate return value, but back in the connection thread, the value I get is NOT what I expect. I am expecting an int back, and well I get a number but it isn't the single digit int I send back.
a..l..m..os..t..there
-
Re: on minor correction ...
Quote:
Originally Posted by ucntcme
The slot is being activated as desired, and has an appropriate return value, but back in the connection thread, the value I get is NOT what I expect. I am expecting an int back, and well I get a number but it isn't the single digit int I send back.
a..l..m..os..t..there
Probably because return values from slots are ignored and you get a random value here. Look at my previous post, I suggested a solution there.
-
Re: [QT4] threads, signals, and slots, please help.
Quote:
Originally Posted by wysota
Code:
action = emit getActionForTarget(target);
Since when does "emit" have a return value? :)
Since I wanted it to, naturally. ;)
Actually, I was mislead by statements (elsewhere) that emit was "just a decoration for the programmer", that the signal was still "just a function call". I was actually thiking about this last night while sleeping and thinking of alternate routes of getting the data back to the connection thread.
Quote:
Originally Posted by wysota
Maybe you should just "register" an object will return the action and call it directly here instead of such weird statements as the one above?
As soon as I figure out just what you mean, I'm sure I'll try it. :)
Thanks again.
Cheers,
Bill
-
Re: [QT4] threads, signals, and slots, please help.
Quote:
Originally Posted by ucntcme
Since I wanted it to, naturally. ;)
Actually, I was mislead by statements (elsewhere) that emit was "just a decoration for the programmer", that the signal was still "just a function call".
It is (usually) a function call. But! What happens if there are two or more slots connected to a signal? Return value of which of them should then be returned?
Quote:
As soon as I figure out just what you mean, I'm sure I'll try it. :)
I mean to pass a pointer or reference of the object which is to deliver some information to the other one. This way you'll be able to call the method directly on a single object, without signal/slot mechanism:
Code:
struct aaa {
int action(someclass &);
};
class bbb {
public:
void registerDeliverer(aaa *a){ m_ad = a; }
void do_something();
private:
aaa *m_ad;
}
void bbb::do_something(){
//...
if(!m_ad)
return;
int act = m_ad->action(); // fetch an int from registered object
//...
}
//...
aaa action_deliverer;
bbb obj;
//...
obj->registerDeliverer(&action_deliverer);
//...
obj->do_something();
//...
-
Re: [QT4] threads, signals, and slots, please help.
Quote:
Originally Posted by wysota
It is (usually) a function call. But! What happens if there are two or more slots connected to a signal? Return value of which of them should then be returned?
Well obviously the only one I am interested in! :D
Seriously though, that makes sense explained that way.
Perhaps it would be nice if a warning/error was issued at compile time if a signal was declared as anything other than void? As a newbie that would make some sense to me, and would have alerted me to the head-banging route I was travelling upon. :)
Quote:
Originally Posted by wysota
I mean to pass a pointer or reference of the object which is to deliver some information to the other one. This way you'll be able to call the method directly on a single object, without signal/slot mechanism:
Code:
struct aaa {
int action(someclass &);
};
class bbb {
public:
void registerDeliverer(aaa *a){ m_ad = a; }
void do_something();
private:
aaa *m_ad;
}
void bbb::do_something(){
//...
if(!m_ad)
return;
int act = m_ad->action(); // fetch an int from registered object
//...
}
//...
aaa action_deliverer;
bbb obj;
//...
obj->registerDeliverer(&action_deliverer);
//...
obj->do_something();
//...
I suspected that was what you meant, and had begun working on that. Of course, I've done it wrong and get segfaults, but I'm sure it's not a Qt related segfault, rather programmer naivete. ;) Some of it I just *have* to bang away at until I get it. But then again, once I get it, I've got it. Know what I mean?
But one quick question on the above ... what is "someclass" representing?
-
Re: [QT4] threads, signals, and slots, please help.
Quote:
Originally Posted by ucntcme
Perhaps it would be nice if a warning/error was issued at compile time if a signal was declared as anything other than void? As a newbie that would make some sense to me, and would have alerted me to the head-banging route I was travelling upon. :)
No, because slots are regular methods, just with additional capabilities. You can invoke them as normal methods and use their return values as usual.
Quote:
But one quick question on the above ... what is "someclass" representing?
Some data which is processed by "action" method... That's just an example, nothing specific.
-
Re: [QT4] threads, signals, and slots, please help.
Quote:
Originally Posted by wysota
No, because slots are regular methods, just with additional capabilities. You can invoke them as normal methods and use their return values as usual.
Well it was a nice thought anyway. ;)
Quote:
Originally Posted by wysota
Some data which is processed by "action" method... That's just an example, nothing specific.
Well I finally found the route out of segfault land (a nap can do wonders ;) ) and it is all working perfectly. Thanks again!