Qt c ++ Data с двойной эмиссией

У меня есть multiserverapp, который до сих пор работает отлично. Я получил 4 файла cpp.
Main.cpp создает программу. MainWindow.cpp создает пользовательский интерфейс и запускает (через нажатие кнопки) MyServer.cpp. MyServer.cpp создает поток и запускает MyThread.cpp.
Моя цель — показать несколько основных шагов (например, «сервер запущен», «новое соединение» и т. Д.) В textBrowser.

Я передаю результаты из MyServer.cpp через emit updateUI("server started"); в mainwindow.cpp, где вывод ловится:

    //Mainwindow.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"#include "myserver.h"#include "mythread.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

}

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

void MainWindow::AppendToBrowser(const QString text)
{
ui->textBrowser->append(text);
}

void MainWindow::on_startButton_clicked()
{
MyServer* mServer = new MyServer;
connect(mServer, SIGNAL(updateUI(const QString)), this, SLOT(AppendToBrowser(const QString)));
mServer->StartServer();

ui->textBrowser->setPlainText("Server Started");
}

Это работает правильно, потому что команда connect находится в самом mainwindow.cpp.
Проблема начинается на один шаг «глубже» в mythread.cpp.

Я создал еще один сигнал в

//MyThread.h

signals:
void updateUI_serv(const QString text);

и связал его в MyServer.cpp с MainWindow.cpp.

    //MyServer.cpp

#include "myserver.h"#include "mainwindow.h"
MyServer::MyServer(QObject *parent) :
QTcpServer(parent)
{
}

void MyServer::StartServer()
{
if(!this->listen(QHostAddress::Any,1234))
{
qDebug("Server Error");
}
else
{
qDebug("Server started");
}
}

void MyServer::incomingConnection(int socketDescriptor)
{
qDebug("new connection");MyThread *thread = new MyThread(socketDescriptor,this);
MainWindow *mMain = new MainWindow;
connect(thread, SIGNAL(updateUI_serv(const QString)),mMain ,SLOT(AppendToBrowser(const QString)));//flags thread for selfdeletion
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));//calls run
thread->start();

emit updateUI("thread started!");
}

// MyThread.cpp

#include "mythread.h"#include "mainwindow.h"#include "myserver.h"
MyThread::MyThread(int ID, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
emit updateUI_serv("start");
}

void MyThread::run()
{
//thread stars here
qDebug("Starting thread");
socket = new QTcpSocket();
emit updateUI_serv("hallo");
//set socketdescriptor number
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);qDebug("client connected");

exec();
}

void MyThread::readyRead()
{
QByteArray Data = socket->readAll();
QString Datain = QString::fromLatin1(Data);
qDebug("Date in:");

emit updateUI_serv("data in:");
socket->write(Data);
}

void MyThread::disconnected()
{
qDebug("Disconnected");
socket->deleteLater();
exit(0);
}

Команда подключения находится здесь «между» сигналом (updateUI_serv из mythread.cpp) и файлом слота (AppendToBrowser из mainwindow.cpp).
В этот момент программа вылетает, как только я пытаюсь записать данные (как клиент через telnet) в serverapp.

Я попытался установить команду подключения в главном окне и мифреде, но оба раза у меня возникали разные проблемы (например, проблемы с отладкой, или текст просто не отображается в textBrowser).
Пока спасибо.

0

Решение

В конечном итоге myServer-Object не работает в MainThread, поэтому доступ к элементу пользовательского интерфейса из другого потока приводит к сбою вашего приложения.

Вы можете убедиться, что будут отображаться только сообщения из mainThread, добавив следующий код в слот AppendToBrowser:

if( QApplication::instance()->thread() == QThread::currentThread() )
ui->textBrowser->setPlainText("whateverTextThereShallBe");
else
return;
//You should not run into this else...

Этот раздел if проверяет, является ли текущий объект, вызывающий обновление, mainThread. Секция else проверяет наличие ошибок. Если вы работаете в else-разделе, вы пытаетесь изменить ui-элементы из потока, который не является mainThread (UI-Thread). Подключите ваш SIGNAL на сервере к другому SIGNAL (соединение SIGNAL-> SIGNAL) и добавьте соединение к SIGNAL (SERVER) -> SLOT (MainWindow) в вашем MainWindow.cpp. В конце концов попробуйте ваш Connect-Call с 5-го. параметр для соединения в очереди (Qt :: QueuedConnection IIRC).

0

Другие решения

Ааа, я получил это самостоятельно.
Я решил проблему, создав новую функцию ( void forwarding(const Qstring); ) и в этой функции я испустил его с обычным emit updateUI(text); .. все работает окончательно!

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector