Search code examples
c++qtqt5qt-signalsqtwidgets

How can I return a value from SLOT in Qt5?


I have been new to the Qt environment. I recently started with a QtCreator project for a simple chat application (QMainWindow). I have nearly completed the project but stuck with the SIGNAL/SLOT problem.

Let me explain my problem in brief :

Due to the length of the code I am not able to paste it here.

  1. I have two classes MainWindow and NetworkFile.
  2. The function newServerConn() in NetworkFile connects the signal readyRead() to the slot readFromClient().
  3. The string returned by client is stored in a QString in readFromClient() SLOT.

Problem:

I have to return the QString in the slot to the newServerConn() function and from there to a function in MainWindow class because only then I would be able to print the string to the plainLineEdit widget pointed by the ui object.

Question 1: How can I return a value from the slot?

Question 2: Or is there any way I could get a copy of the ui instance in the NetworkFile class so that I could use the widgets from there?

Thanks.


Solution

  • 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();
    }