[Solved] Multi-threaded Network and User Interface



  • What i want to do is very simple.

    When my server receives data, i want to be able to display the information sent into a QTextEdit located into my MainWindow.ui file.

    The problem is, whenever i try to connect one of my QThread's method to one of my MainWindow's method, i get this error :

    @QObject::connect: Cannot connect (null)::dataReceived(QByteArray) to MainWindow::grabData(QByteArray)@

    What am i doing wrong?

    MainWindow.h

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>

    #include "server.h"

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    public slots:
    void grabData(QByteArray);
    private:
    Ui::MainWindow *ui;
    Server *server;
    };

    #endif // MAINWINDOW_H@

    MainWindow.cpp

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    server = new Server(this);
    
    server->Start();
    connect(server->thread, SIGNAL(dataReceived(QByteArray)), this, SLOT(grabData(QByteArray)));
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::grabData(QByteArray msg){
    QString message(msg);
    ui->Txt_ChatOutput->append(message);
    }@

    NetworkThread.h

    @#ifndef NETWORKTHREAD_H
    #define NETWORKTHREAD_H

    #include <QThread>
    #include <QTcpSocket>
    class NetworkThread : public QThread
    {
    Q_OBJECT
    public:
    explicit NetworkThread(int ID, QObject *parent = 0);
    void run();

    signals:
    void error(QTcpSocket::SocketError socketError);
    void dataReceived(QByteArray);
    public slots:
    void readyRead();
    void disconnected();
    private:
    QTcpSocket *socket;
    int socketDescriptor;
    };

    #endif // NETWORKTHREAD_H@

    NetworkThread.cpp

    @#include "networkthread.h"

    NetworkThread::NetworkThread(int ID, QObject *parent) :
    QThread(parent)
    {
    this->socketDescriptor = ID;

    }

    void NetworkThread::run(){
    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);
    
    exec&#40;&#41;;
    

    }

    void NetworkThread::readyRead(){
    QByteArray Data = socket->readAll();
    socket->write(Data);
    emit dataReceived(Data);
    }

    void NetworkThread::disconnected(){
    socket->deleteLater();
    exit(0);
    }@

    Server.h

    @#ifndef SERVER_H
    #define SERVER_H

    #include <QTcpServer>
    #include "networkthread.h"

    class Server : public QTcpServer
    {
    Q_OBJECT
    public:
    explicit Server(QObject *parent = 0);
    void Start();

    NetworkThread *thread;
    

    signals:

    public slots:

    protected:
    void incomingConnection(qintptr socketDescriptor);
    };

    #endif // SERVER_H@

    Server.cpp

    @#include "server.h"

    Server::Server(QObject *parent) :
    QTcpServer(parent)
    {
    }

    void Server::Start(){
    if(this->listen(QHostAddress::Any, 2424)){

    }
    

    }

    void Server::incomingConnection(qintptr socketDescriptor){
    thread = new NetworkThread(socketDescriptor,this);
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    thread->start();
    }
    @


  • Moderators

    Server::thread only gets initialized when incomingConnection() is called.
    But you do the connection right after you've created an Server-instance and called start() on it.
    At this time server->thread is not yet initialized and thus there is no object to do the connection with.



  • [quote author="raven-worx" date="1383577334"]Server::thread only gets initialized when incomingConnection() is called.
    But you do the connection right after you've created an Server-instance and called start() on it.
    At this time server->thread is not yet initialized and thus there is no object to do the connection with.[/quote]

    Alright, i understand.
    But now, how can i fix this?

    I really can't think of a solution here.

    If i can't connect my QThread right after creating my MainWindow object, how am i ever going to connect it if i don't have access to my User Interface outside of Main.cpp or MainWindow.h/.cpp?


  • Moderators

    at a quick glance you anyway use a single thread in your server design.
    So quickest solution would be to create a thread instance in your Server::start() method or constructor. Just before you try to connect it...
    And start the thread in Server::incomingConnection() (like you already do).


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.