обновление ui из другого класса

199
16 марта 2017, 23:06

Взял пример сервера http://www.voidrealms.com/index.php?r=tutorial/view&id=256 и попытался добавить к нему GUI, добавил сигнал-слотовую связь между объектом myclient и mainwindow, данные передаются но не отображаются на UI.

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void on_actionStart_Server_triggered();
public slots:
    void on_UpdateDevicesList(const QStringList &);
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

"mainwindow.cpp"

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "myserver.h"
#include "myclient.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_actionStart_Server_triggered()
{
    MyServer *Server = new MyServer();
    Server->StartServer();
}
void MainWindow::on_UpdateDevicesList(const QStringList &data){
    for (int i = 0; i < data.count(); ++i){
        qDebug() << data[i];
        ui->tableWidget->setItem(0, i, new QTableWidgetItem(data[i]));
    }
    qDebug() << "end";
}

myserver.h:

#ifndef MYSERVER_H
#define MYSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QAbstractSocket>
#include "myclient.h"
#include "mainwindow.h"
class MyServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit MyServer(QObject *parent = 0);
    void StartServer();
protected:
    void incomingConnection(int handle);
private:
    MainWindow *mainwindow;
};
#endif // MYSERVER_H

myserver.cpp:

#include "myserver.h"
MyServer::MyServer(QObject *parent) :
    QTcpServer(parent)
{
}
void MyServer::StartServer()
{
    if(listen(QHostAddress::Any,1234))
    {
        qDebug() << "started";
    }
    else
    {
        qDebug() << "not started!";
    }
}
void MyServer::incomingConnection(int handle)
{
    qDebug() << "new connection";
    MyClient *client = new MyClient();
    mainwindow = new MainWindow();
    connect(client, &MyClient::UpdateDevicesList, mainwindow, &MainWindow::on_UpdateDevicesList);
    client->SetSocket(handle);
}

myclient.h:

#ifndef MYCLIENT_H
#define MYCLIENT_H
#include <QObject>
#include <QTcpSocket>
#include <QDebug>
#include <QThreadPool>
#include "mytask.h"
#include "mainwindow.h"
class MyClient : public QObject
{
    Q_OBJECT
public:
    explicit MyClient(QObject *parent = 0);
    void SetSocket(int Descriptor);
signals:
    void UpdateDevicesList(const QStringList &);
public slots:
    void connected();
    void disconnected();
    void readyRead();
    void TaskResult(int Number);
private:
    QTcpSocket *socket;
};
#endif // MYCLIENT_H

myclient.cpp:

#include "myclient.h"

MyClient::MyClient(QObject *parent) :
    QObject(parent)
{
    QThreadPool::globalInstance()->setMaxThreadCount(15);
}
void MyClient::SetSocket(int Descriptor)
{
    socket = new QTcpSocket(this);
    connect(socket,SIGNAL(connected()),this,SLOT(connected()));
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()));
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()));
    socket->setSocketDescriptor(Descriptor);
    qDebug() << "client connected";
    QStringList fields;
    fields << "0"
           << "test"
           << "ip"
           << QString::number(Descriptor)
           << "connected";
    emit UpdateDevicesList(fields);
}

При подключении нового клиента сигнал

emit UpdateDevicesList(fields);

отправляет QStringList fields в

void MainWindow::on_UpdateDevicesList(const QStringList &data){
    for (int i = 0; i < data.count(); ++i){
        qDebug() << data[i];
        ui->tableWidget->setItem(0, i, new QTableWidgetItem(data[i]));
    }
    qDebug() << "end";
}

qDebug() выводит данные, но они не отображаются на ui, но что самое странно если я добавляю сигнал pushbutton clicked в mainwindow и по нему вызываю тот же слот on_UpdateDevicesList() то все обновляется.

Answer 1

Нужно установить количество строк и колонок, которые будут видимы, перед использованием:

ui->tableWidget->setColumnCount(data.count() - 1);
ui->tableWidget->setRowCount(1);
Answer 2

Спасибо за помощь! я нашел ошибку. Проблема в том что при каждом новом подключении я создавал новый экземпляр mainwindow:

mainwindow = new MainWindow();

Соответственно изменения не сохранялись. Возможно мое решение не совсем корректное но я сделал следующим образом: объявил указатель на MainWindow глобальным и в MyServer ссылаюсь на него как на extern:

MainWindow *pw;
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    pw = new MainWindow;
    pw->show();
    return a.exec();
}
void MyServer::incomingConnection(qintptr handle)
{
    qDebug() << "new connection";
    MyClient *client = new MyClient();
    extern MainWindow *pw;
    connect(client, &MyClient::UpdateDevicesList, pw, &MainWindow::on_UpdateDevicesList);
    client->SetSocket(handle);
}
READ ALSO
Разбить на массивы С++

Разбить на массивы С++

Всем привет ,есть очень интересная задачаЯ её решил,но проходит 52

278
Работа с сокетами в win 10

Работа с сокетами в win 10

Работал с сокетами в C,код идентичен коду с msdn сервер клиент

203
Определение видимости отрезка

Определение видимости отрезка

дано N отрезков на плоскости с началом координат в (0, 0) соответственно, расположение которых может быть абсолютно любым

318
Граф. Написать класс на С++ [требует правки]

Граф. Написать класс на С++ [требует правки]

Написать на C++ класс, описывающий граф/орграфКласс должен поддерживать следующую функциональность:

719