Home Articles

Qt c双重发射数据

Asked
Viewed 1262 times
0

我有一个到目前为止工作正常的multiserverapp . 我有4个cpp文件 . Main.cpp构造程序 . MainWindow.cpp构造ui并启动(通过buttonclick)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);

并使用MainWindow.cpp将其连接到MyServer.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);
}

connect命令在这里放置信号(来自mythread.cpp的updateUI_serv)和插槽(来自mainwindow.cpp的AppendToBrowser)文件 . 此时,一旦我尝试将数据(作为客户端通过telnet)写入serverapp,程序就会崩溃 .

我试图将connect命令设置为主窗口和mythread,但两次我都遇到不同的问题(比如调试问题,或者文本没有显示在textBrowser中) . 谢谢到目前为止 .

2 Answers

  • 0

    最终myServer-Object没有在MainThread中运行,因此从另一个线程访问ui元素会导致应用程序崩溃 .

    您可以通过将以下代码添加到AppendToBrowser Slot来确保只显示来自mainThread的消息:

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

    此if部分检查调用更新的当前对象是否为mainThread . else-section检查错误 . 如果您在else-section中运行,则尝试将ui-elements更改为不是mainThread(UI-Thread)的线程 . 将服务器中的SIGNAL连接到另一个SIGNAL(SIGNAL-> SIGNAL连接),并在MainWindow.cpp中添加到SIGNAL(SERVER) - > SLOT(MainWindow)的连接 . 最后尝试与5号连接通话 . 排队连接的参数(Qt :: QueuedConnection IIRC) .

  • 0

    啊,我自己得到它 . 我通过创建一个新函数( void forwarding(const Qstring); )来解决这个问题,并且在该函数中我用普通的 emit updateUI(text); 发出它..这些东西最终起作用!

Related