Как оставить QTcpsocket соединение после закрытия DialogWindow?

В моем приложении Qt у меня есть MainWindow и DialogWindow. DialogWindow предназначен для настройки IP-адреса и порта сервера. В то время как MainWindow предназначен для выполнения связи после успешного подключения.

Однако установка QTcpSocket *socket в DialogWindow означает, что когда я закрою DialogWindow, socket будет уничтожен, таким образом, socket будет отключен от сервера.

Я хотел бы, чтобы сокет был подключен к серверу после закрытия DialogWindow. Существуют ли какие-либо методы, которые могут достичь этого результата?

Пожалуйста, дайте мне несколько комментариев и идей по этому поводу. Я совсем новичок в Qt.

DialogSetup.cpp

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

    socket = new QTcpSocket(this);
    connect(socket, SIGNAL(connected()),this, SLOT(wasconnected()));
    connect(socket,SIGNAL(disconnected()),this,SLOT(wasdisconnected()));
}
DialogSetup::~DialogSetup()
{
    delete ui;
}

void DialogSetup::on_pushButtonConnect_clicked()
{
    m_strIPAdd = ui->lineEditIPAdd->text();
    m_strPort = ui->lineEditPort->text().toInt();

    socket->connectToHost(m_strIPAdd,m_strPort);

    if(!socket->waitForConnected(10000))
    {
       ui->labelStatus->setText("Error");
       QMessageBox::information(this,"Error",socket->errorString());
    }
}
void DialogSetup::wasconnected()
{
    socket->write("Hello server!");
    ui->labelStatus->setText("Connected!");
    ui->pushButtonDisconnect->setDisabled(false);
}

void DialogSetup::wasdisconnected()
{
    ui->labelStatus->setText("Disonnected!");
}

void DialogSetup::on_pushButtonDisconnect_clicked()
{
    socket->close();
}

Главное окно.cpp

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

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

void MainWindow::on_actionSetup_triggered()
{
    dialogsetup = new DialogSetup(this);
    dialogsetup->show();
}

person Ryan    schedule 30.06.2015    source источник
comment
Вы можете поместить указатель сокета в класс MainWindow и общаться с сигналами сокета через форму DialogSetup.   -  person t3ft3l--i    schedule 30.06.2015


Ответы (2)


Переместите сокет за пределы класса диалога. Что-то такое:

void MainWindow::on_actionSetup_triggered()
{
    socket = new QTcpSocket(this); //declared as private in MainWindow
    dialogsetup = new DialogSetup(socket, this);
    connect(socket,SIGNAL(connected()), dialogsetup, SLOT(wasconnected()));
    connect(socket,SIGNAL(disconnected()), dialogsetup ,SLOT(wasdisconnected()));
    dialogsetup->show();
}

Класс диалога хранит указатель на сокет и работает с ним:

DialogSetup::DialogSetup(QTcpSocket *socket, QWidget *parent) :
    QDialog(parent),
    socket_(socket),
    ui(new Ui::DialogSetup)
{
    ui->setupUi(this);
}

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

void DialogSetup::on_pushButtonConnect_clicked()
{
    m_strIPAdd = ui->lineEditIPAdd->text();
    m_strPort = ui->lineEditPort->text().toInt();

    socket_->connectToHost(m_strIPAdd,m_strPort);

    if(!socket_->waitForConnected(10000))
    {
       ui->labelStatus->setText("Error");
       QMessageBox::information(this,"Error",socket->errorString());
    }
}
void DialogSetup::wasconnected()
{
    socket_->write("Hello server!");
    ui->labelStatus->setText("Connected!");
    ui->pushButtonDisconnect->setDisabled(false);
}

void DialogSetup::wasdisconnected()
{
    ui->labelStatus->setText("Disonnected!");
}

void DialogSetup::on_pushButtonDisconnect_clicked()
{
    socket_->close();
}
person Sommerwild    schedule 30.06.2015
comment
Нужно сохранить еще один указатель на этот сокет в DialogSetup, чтобы обеспечить возможность нажатия на кнопку в DialogSetup - person t3ft3l--i; 30.06.2015
comment
Спасибо, ребята, помогите! @ t3ft3l--i, вы имеете в виду, что будет 2 указателя: 1 для настройки диалога и 1 для главного окна? И могу ли я узнать, что такое возможность, нажатая на кнопку? - person Ryan; 01.07.2015
comment
@Ryan присутствияvoid DialogSetup::on_pushButtonConnect_clicked(), так что я вижу, что у вас есть QPushButton и некоторые действия с socket_ в этом слоте. Поэтому нужен доступ к socket_ в DiaglogSetup. Вот почему я сказал о хранении еще одного указателя на сокет: 1 для Dialog Setup и 1 для MainWindow. Или сделать более сложную слот-сигнальную связь между этими классами. - person t3ft3l--i; 01.07.2015
comment
@ t3ft3l--i @Cits У меня проблемы с пониманием указателей, которые используются между классами. Таким же образом socket_ является указателем, объявленным в DialogSetup. И я получил этот error: C2065: 'socket_' : undeclared identifier, это значит, что мне нужно объявить указатель socket_ в DialogSetup? Кроме того, означает ли это socket_(socket) , что у класса DialogSetup есть указатель сокета? Большое спасибо~~! - person Ryan; 01.07.2015
comment
@ Райан, да, вам нужно объявить в DialogSetup.h файле QTcpSocket *socket_ - person t3ft3l--i; 01.07.2015
comment
Да, как сказал t3ft3l - person Sommerwild; 01.07.2015

Измените его родителя или вообще удалите родителя (хотя вам придется удалить сокет вручную).

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

DialogSetup::DialogSetup(QTcpSocket *socket_, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogSetup),
    socket(socket_)

...

void MainWindow::on_actionSetup_triggered()
{
    dialogsetup = new DialogSetup(socket, this);
    dialogsetup->show();
}
person Amartel    schedule 30.06.2015
comment
Вы не можете определить Конструктор с параметрами DialogSetup(QObject *parent = 0, QTcpSocket *socket), изменить порядок параметров. - person t3ft3l--i; 30.06.2015
comment
@ t3ft3l - я забыл о заголовке - мой плохой. Спасибо за исправление. - person Amartel; 30.06.2015
comment
Спасибо за вашу помощь!! Однако у меня есть эта ошибка error: C2511: 'DialogSetup::DialogSetup(QTcpSocket *,QWidget *)' : overloaded member function not found in 'DialogSetup' . , значит ли это, что мне нужно что-то добавить в декларацию? Я пробовал общедоступный QTcpSocket class DialogSetup : public QDialog, public QTcpSocket { Q_OBJECT, но также получил ошибки. - person Ryan; 30.06.2015
comment
@Ryan в DialogSetup.h вам нужно изменить определение конструктора DialogSetup на explicit DialogSetup(QTcpSocket *socket, QWidget *parent = 0); - person Amartel; 30.06.2015