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