Can Qt signals return a value?
OK. So, I did a little more investigating. Seems this is possible. I was able to emit a signal, and receive value from the slot the signal was connected to. But, the problem was that it only returned the last return value from the multiple connected slots:
Here's a simple class definition (main.cpp
):
#include <QObject>
#include <QDebug>
class TestClass : public QObject
{
Q_OBJECT
public:
TestClass();
Q_SIGNALS:
QString testSignal();
public Q_SLOTS:
QString testSlot1() {
return QLatin1String("testSlot1");
}
QString testSlot2() {
return QLatin1String("testSlot2");
}
};
TestClass::TestClass() {
connect(this, SIGNAL(testSignal()), this, SLOT(testSlot1()));
connect(this, SIGNAL(testSignal()), this, SLOT(testSlot2()));
QString a = emit testSignal();
qDebug() << a;
}
int main() {
TestClass a;
}
#include "main.moc"
When main runs, it constructs one of the test classes. The constructor wires up two slots to the testSignal signal, and then emits the signal. It captures the return value from the slot(s) invoked.
Unfortunately, you only get the last return value. If you evaluate the code above, you'll get: "testSlot2", the last return value from the connected slots of the signal.
Here's why. Qt Signals are a syntax sugared interface to the signaling pattern. Slots are the recipients of a signal. In a direct connected signal-slot relationship, you could think of it similar to (pseudo-code):
foreach slot in connectedSlotsForSignal(signal):
value = invoke slot with parameters from signal
return value
Obviously the moc does a little more to help in this process (rudimentary type checking, etc), but this helps paint the picture.
Qt - Return value when signal is emitted?
You seem to be in a confusion. Even though signals in Qt can indeed return values, this is rarely used, if ever. Namely because it doesn't make a lot of sense.
What you probably want to do is not return but emit the image with a signal, this way you can connect it to a function that will receive the image and do something with it.
In that event, you want the signal to be declared as:
void downloaded(QImage img);
And emitted via:
emit downloaded(Image::fromData(fd->downloadedData()));
or just:
downloaded(Image::fromData(fd->downloadedData()));
as emit
is just decoration for the sake of readability that doesn't do anything.
What I want to achieve is to create a function that return a QImage
from a QUrl [QImage func(QUrl)]. However I want to make sure that the
data has been downloaded before returning the value.
The only way this can happen is if you use a blocking API, but it is not recommended to do that in the main/GUI thread, as your application will appear to be non-responsive to the OS. You will have to do it in another thread and pass the end result to the main thread if you want to use the image in the GUI. At any rate, you will still have to use the above signal declaration that emits to image in order to get it there. When you make the connection to the main thread, Qt will detect that the two objects run in different threads and use a queued connection for you.
Or you can do a non-blocking implementation that runs periodically in the main thread without blocking it.
But the only way to get from an URL to an image in one function is to block the function with the data download.
How can I return a value from SLOT in Qt5?
I would just emit the data as a signal and wire up the connection between that new signal and a slot where you add then string to your ui.
A quick self-contained example (which btw. "Due to the length of the code I am not able to paste it here." is just an excuse, you can pretty much always cut down your relevant code)
Header:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTextEdit>
class NetworkFile;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow(){}
public slots:
void addText(QString str)
{
edit->append(str);
}
private:
QTextEdit* edit;
NetworkFile* net;
};
class NetworkFile : public QObject
{
Q_OBJECT
public:
NetworkFile(QObject *parent = 0):
QObject(parent)
{
connect(&server, &QTcpServer::newConnection,
this, &NetworkFile::newConnection);
//TODO: check return value
server.listen(QHostAddress::Any,16001);
}
signals:
void dataRead(QString);
public slots:
void newConnection(){
//TODO: wire up socket disconnect with deleteLater, also check for null
QTcpSocket* socket = server.nextPendingConnection();
connect(socket, &QTcpSocket::readyRead,
this, &NetworkFile::dataAvailable);
}
void dataAvailable(){
//HACK: only for brevity, create a connection wrapper that contains the socket in real code
QTcpSocket* source = (QTcpSocket*)sender();
auto bytes = source->readAll();
if(bytes.size())
{
emit dataRead(QString(bytes));
}
}
private:
QTcpServer server;
};
#endif // MAINWINDOW_H
cpp file
#include "mainwindow.h"
#include <QApplication>
MainWindow::MainWindow(QWidget *parent ):
QMainWindow(parent)
{
edit = new QTextEdit(this);
net = new NetworkFile(this);
connect(net, &NetworkFile::dataRead,
this, &MainWindow::addText );
setCentralWidget(edit);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
QT return value from a signal?
You should have a connection of type Qt::BlockingQueuedConnection when the emitter and receiver are in different threads.
So it should be like:
connect(this, SIGNAL(getUserNickS(QString)), dbtrad, SLOT(getUserNick(QString)),Qt::BlockingQueuedConnection);
When you emit your signal, it causes the current thread to block until the slot is returned.
What effect will exist when using any 'return' statement inside Qt's slot
None. The signals only invoke the function, if the function returns Qt will not use it.
On the other hand in Qt/PyQt it is said that a function is a slot if you use the decorator @QtCore.pyqtSlot()
. In your case it is a simple function. Even so for a signal will not serve the data that returns the slot or function invoked.
Will this interruption have collision with the signal&slot mechanism?
No, it does not have a collision. Returning to the beginning, middle or end is irrelevant, remember every function returns something (if you do not use return the function will implicitly return None at the end).
On the other hand in a GUI the tasks of the functions must be light, if they are heavy you must execute it in another thread.
Qt: Return value of signal works, why is the official doc saying it is impossible / forbidden?
The problem is that the return types are are not checked for compatibility at connect-time, thus connecting a double-returning slot to a float-returning signal, say, will overflow the stack (no pun intended) space allocated to the float.
Is it possible to get a return value from a QRemoteObject Dynamic Replica slot?
For those who are looking for an answer on this, there is a way :) : the
QRemoteObjectPendingCall
undocumented argument.
bool success = QMetaObject::invokeMethod(_replica,"getName",Qt::DirectConnection,
Q_RETURN_ARG(QRemoteObjectPendingCall, call),
Q_ARG(QString, "id")
);
auto e = call.error();// , QRemoteObjectPendingCall::InvalidMessage);
call.waitForFinished();
//QVERIFY(call.isFinished());
qDebug() << QMetaType::typeName(call.returnValue().type());
QString retVal = call.returnValue().toString();
This is exactly the same kind a future object available for REPC Replica (except not templated)
No Documentation but there is some example in :
Qt Remote Objects integration tests
Sadly, there is currently (5.13.0) no way to get the pending reply in QML (QTBUG-77178) but Qt People are looking for it.
Related Topics
How to Set Error_Code to Asio::Yield_Context
C++ Initializing Non-Static Member Array
Opencv Gtk+2.X Error - "Unspecified Error (The Function Is Not Implemented...)"
How to Get the Address of the Std::Vector Buffer Start Most Elegantly
Calling Erase with Iterator VS Const_Iterator
Opencv Fisheye Calibration Cuts Too Much of the Resulting Image
Convert Std::Variant to Another Std::Variant with Super-Set of Types
What's the Difference Between Getline and Std::Istream::Operator>>()
C++: Calling Member Function via Pointer
C++ Inheritance and Name Hiding
Duplicate Const Qualifier Allowed in C But Not in C++
How to Open a Folder in %Appdata% with C++
Create Shared_Ptr to Stack Object
Stl Ordering - Strict Weak Ordering
Best Way to for C++ Types to Self Register in a List
Add Elements to a Vector During Range-Based Loop C++11
Why Does My Stl Code Run So Slowly When I Have the Debugger/Ide Attached