Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Send data on Button click via TCP. How to trigger my send method via button click?



  • Hello guys,

    I am a qt beginner so please don't blame me for my question.

    I have a simple UI and a server running in the background (in a thread) which should send some data when a button is clicked. The server code is in another class which also contains the sendData method. Now I am looking for the best practice to trigger the sendData method with a button.

    Actually, in the thread.cpp I wanted to do something like:

     connect(ui->button1, SIGNAL(clicked()), this, SLOT(sendData()));
    

    But I can not access the ui from my thread class.

    I think this is kinda easy to solve but I really couldn't find any solutions.

    Here is the full code:

    Thread.h

    #ifndef THREAD_H
    #define THREAD_H
    
    #include <QThread>
    #include <QTcpSocket>
    #include <QDebug>
    
    class Thread : public QThread
    {
        Q_OBJECT
    public:
        explicit Thread(int ID, QObject *parent = 0);
        void run();
        void sendData();
    
    signals:
        void error(QTcpSocket::SocketError socketerror);
    
    public slots:
        void readyRead();
        void disconnected();
    
    private:
        QTcpSocket *socket;
        int socketDescriptor;
    
    
    };
    
    #endif // THREAD_H
    

    Thread.cpp

    #include "thread.h"
    
    Thread::Thread(int ID, QObject *parent) : QThread(parent)
    {
        this->socketDescriptor = ID;
    }
    
    void Thread::run()
    {
        qDebug() << socketDescriptor << " Starting Thread";
        socket = new QTcpSocket();
    
        if(!socket->setSocketDescriptor(this->socketDescriptor))
        {
            emit error(socket->error());
            return;
        }
    
        connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
        connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()), Qt::DirectConnection);
        // Here is where i wanted to access the buttons signal and trigger the sendData method.
    
        qDebug() << socketDescriptor << " Client connected";
    
        exec();
    
    }
    
    void Thread::sendData()
    {
        socket->write("Data test");
    }
    
    void Thread::readyRead()
    {
        QByteArray data = socket->readAll();
        qDebug() << socketDescriptor << " Data in: " << data;
        socket->write(data);
    }
    
    void Thread::disconnected()
    {
        qDebug() << socketDescriptor << " Client disconnected";
        socket->deleteLater();
        exit(0);
    }
    
    

    MainWindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include "server.h"
    
    #include <QMainWindow>
    #include <QFileDialog>
    #include <QMessageBox>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    private slots:
    
    
        void on_btn_lightOff_clicked();
    
    private:
        Ui::MainWindow *ui;
    
    };
    #endif // MAINWINDOW_H
    
    

    MainWindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "server.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    
    
    void MainWindow::on_btn_lightOff_clicked()
    {
    
    }
    

    main.cpp

    #include "tcpsocket.h"
    #include "server.h"
    #include "mainwindow.h"
    
    
    
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        Server server;
        server.startServer();
        w.show();
        return a.exec();
    }
    
    

    Server.h

    #ifndef SERVER_H
    #define SERVER_H
    
    #include <QTcpServer>
    #include <QDebug>
    #include <thread.h>
    
    
    class Server : public QTcpServer
    {
        Q_OBJECT
    public:
        explicit Server(QObject *parent = 0);
        void startServer();
    
    signals:
    
    protected:
        void incomingConnection(qintptr  socketDescriptor);
    
    };
    
    #endif // SERVER_H
    
    

    Server.cpp

    #include "server.h"
    
    Server::Server(QObject *parent) : QTcpServer(parent)
    {
    
    }
    
    void Server::startServer()
    {
        if(!this->listen(QHostAddress::Any,1337))
        {
           qDebug() << "Error starting Server...";
        }
        else
        {
            qDebug() << "Listening...";
        }
    }
    
    void Server::incomingConnection(qintptr  socketDescriptor)
    {
        qDebug() << socketDescriptor << " Connecting...";
        Thread *thread = new Thread(socketDescriptor,this);
        connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
        thread->start();
    }
    
    

  • Lifetime Qt Champion

    Then do the connect where you have access to both classes. For instance in main when MainWindow returns a pointer of your widget or better somewhere in MainWindow (then MainWindow needs a pointer to the thread).
    Why using threads at all here? It's not needed.


Log in to reply