Slot return value - what if it would be not lost?
-
this is how I do that each time when I need returned value:
@
signals:
void actualSend( float );
public slots:
void getReturn( int );
private:
int value;
QWaitCondition waiter;...
void SenderThread::sendValue( float a )
{
QMutex mutex;
mutex.lock();
emit actualSend( a );
waiter.wait( &mutex );
mutex.unlock();
}void SenderThread::getReturn( int val )
{
value = val; // now I can process value
waiter.wakeAll();
}
@this all (instead of just one call...) requires define signal and slot on both sides and do connections for each pair... but this is not most complex
most complex is: if I call sendValue(a) - I cannot return control after this call, this complicates entire design
-
Might "QtConcurrent":http://doc.trolltech.com/4.7/threads-qtconcurrent.html and "QFuture":http://doc.trolltech.com/4.7/qfuture.html help you out in this? Might be a simpler path.
-
They are good for MASSIVE multithreading. I do not need so much similar threads or giant vector calculations. I need just send signal to other thread and get result. My software works not as calculating supercomputer with tons of superscalar processors - but much more like common electronic circuit with different components working asynchronously. Signal/slot communications are excellent for me. But I often need get results. The emit of signal with returned value would be best for me,
-
[quote author="mlong" date="1310424203"]From here on out I won't feed the trolls.[/quote]
Don't despair mlong, Volker has raised Troll feeding to the next level: http://developer.qt.nokia.com/forums/viewthread/7463 :)
-
[quote author="Gourmand" date="1310403966"]I always used "duplex" connections to get response from QObject when needed. Especially when receiver and sender are from different plugins. But isn't that possible just think about some extension of signal/slot system? To let receive returned values more graciously. Probably this was discussed thousands of times but I didn't read all Qt disputes. Sorry if I talk about something impossible.[/quote]
It's not a matter of being technically impossible; it simply does not make sense imho.
A signal is emitted from a "component" when it changes in some way that may be interesting for other components. The emitter is completely decoupled from any connected receivers, and in fact, it knows nothing about them. At signal emission time, any number of receivers can be connected to that signal (0, 1, N). Therefore, you just don't care about the receivers: you emit the signal and move on.
Now, you already can abuse (a little bit) of this infrastructure, for instance by emitting a signal which carries a pointer and let the slots modify the pointee. This is currently being used in some places inside Qt, f.i. the QNetworkAccessManager::authenticationRequired signal expects the connected slots to fill in the QAuthenticator object (and notice that it doesn't work with queued connections).
Thus, I see no point in supporting return values across connections. If you need to receive some data from the receivers, use the trick above. Return values only introduce burden, like: how do you plan to solve the cases of 0 or N > 1 connected slots? How it's supposed to work with queued connections? A queued return does not make any sense at all, because if
@
int i = emit foo();
@
causes a queued invocation, the slot will be invoked some time later, and in the meanwhile, which value of "i" is your code going to use? -
My sentiments exactly! Thank you peppe.
bq. it can only extend flexibility limited by lack of return from signal
As stated by peppe, you remove the concept of decoupling the receivers.
bq. this slot MUST return value, if not – then return is undefined, like automatic uninitialized variables
Adding more overhead! really? Leaving a variable uninitialized in C++ is actually an error because the behavior is undefined and compiler specific.
And peppe reminded me of the most important issue of them all:
If I connect multiple slots to a single signal which return value should Qt propagate to the sender?Adding some functionality just because it seems right for your particular use-case, but actually hurts other much more common use-cases is just wrong!
-
I agree with [quote author="kkrzewniak" date="1310429619"]Adding some functionality just because it seems right for your particular use-case, but actually hurts other much more common use-cases is just wrong![/quote]
-
[quote author="Gourmand" date="1310416865"]bq. Note that you can trigger slots and get a return value.
I don't remember that, but even if it is possible - will I really get this value if signal and slot are in different threads? I use threads often and I have create duplex queued connection with mutex each time when I need returned value - and I have to send from one method, but receive and process in another, this is very not useful
but if only returning was hidden "under cover" of signal/slot system - this task would be significantly easer
now I cane easy send something from thread to thread, Qt engine delivers signal as well - but to get response it is not so easy
[/quote]It is possible, and I even pointed you to the documentation for how to do it. And yes, AFAIK it works across threads. And because you seem to using it just between two objects, it should not be too much of an issue to use it instead of a real signal-slot connection.
Again, look into [[Doc:QMetaObject]]. Specifically, look into its invokeMethod method. Among the arguments you can pass, there is also... a return argument.
But no, it would not be a signal-slot connection. It would not give you the decoupling that signal-slot gives, and it has been explained above by several people why it doesn't work in that case. Still, it might be enough for your cross-thread communication needs.
-
[quote author="Andre" date="1310446967"]But no, it would not be a signal-slot connection. It would not give you the decoupling that signal-slot gives, and it has been explained above by several people why it doesn't work in that case. Still, it might be enough for your cross-thread communication needs.[/quote]Signal/slot decoupling implies to me also that you don't care about what the listeners do with the fact that your signal is thrown. The very fact that a return value or something like that is required for proper operation, means that signal/slot is not the right approach for Gourmand. He would probably be better off using invokeMethod() as you state or just call the function he needs.
-
bq. The very fact that a return value or something like that is required for proper operation, means that signal/slot is not the right approach for Gourmand.
This is wrong... Signal/slot is best for me, cause application consists of different components communicating with each other but not knowing other's structure and names. There is frontend editor allowing users visually connect components. Each component is distributed as plugin. Plugin exports to main app just a set of signals and slots. Some of them require single directed connection but some require response. Some are automatic, main app performs their connections at load time. But some are manual. In this design sender cannot know how receiver's responding method is called. Even it doesn't know where it's signal will be connected to - user can change connections dynamically. Using signal/slot this all works relatively simple. But with QMetaObject and invokeMethod this will become monstrously complex. And it will mostly duplicate existing signal/slot system.
-
I think what people try to explain is that decoupling the emitter and the receiver of a signal is a fundamental principle of Qt - and a good one - and this won't change, even you might have a use case for such a behaviour.
However, there are various programming techniques to circumvent this "limitation" - and most of them have been already posted here.
-
bq. I think what people try to explain is that decoupling the emitter and the receiver of a signal is a fundamental principle of Qt
"returning" value does not violate this principle - in spite of this principle we still can transmit parameters to receiver, but returned value does not differ from them... treat this as a "parameter" sent back from receiver to sender using same connection
-
[quote author="Gourmand" date="1310466527"]"returning" value does not violate this principle[/quote]
Yes, it does. The simple fact that your emitting object relies on the receiving object is the most obvious proof that there is no such decoupling in your application design.
[quote author="Gourmand" date="1310466527"]in spite of this principle we still can transmit parameters to receiver[/quote]
Yes, because passing parameters does not create dependencies between the emitter and the receiver ...
[quote author="Gourmand" date="1310466527"]but returned value does not differ from them... treat this as a "parameter" sent back from receiver to sender using same connection
[/quote]... while this will do.
Signals are defined as unidirectional connections to prevent dependencies of the emitting object to the receiving object. They are not functions nor methods. If you need the functionality of functions or methods you will need to use them.
-
You clearly have some issues understanding what others are telling you. And IMHO you are having a hard time understanding that passing a parameter to the receiver is not the same as passing a parameter back to the sender (the most obvious part being that there might be more than one receiver).
And frankly your ignorance of what people are trying to tell you is starting to get annoying. If you really think that you are smarter then all of us put together, than you really should be able to patch Qt with your required functionality and use it!
-
bq. Yes, it does. The simple fact that your emitting object relies on the receiving object
No. It does not. It does not rely more than it already relies because of parameters type must match.
bq. because passing parameters does not create dependencies between the emitter and the receiver
But it creates!!... you cannot connect methods with different parameters types and number, that means receiver already depends from sender and vise versa
Returning value does not create more dependencies than already exist... There are only some incomprehensibilities with returned value from several slots or if returned type does not match expected - but this can be worked around.
bq. passing a parameter to the receiver is not the same as passing a parameter back to the sender
Not exactly the same, but it could be implemented under cover looking as the same to be more useful
bq. you really should be able to patch Qt
no-no... all of this would be better implemented by Qt-developers, they know internals much better than me
-
sigh...
Let's agree that Qt currently does not support your use case, it won't in the near future and that you will have to create such a mechanism on your own.
And let's agree that if you feel the urgent need that the Qt developers should do that work for you you are free to file a feature request to the bugtracking system and see what time will bring.