0

これまでのところ正常に動作する multiserverapp があります。4 つの cpp ファイルを取得しました。Main.cpp はプログラムを構築します。MainWindow.cpp は UI を構築し、(ボタンクリックによって) 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);
}

connect コマンドは、シグナル (mythread.cpp からの updateUI_serv) とスロット (mainwindow.cpp からの AppendToBrowser) ファイルの "中間" に置かれます。この時点で、(telnet 経由のクライアントとして) データを serverapp に書き込もうとすると、プログラムがクラッシュします。

connect コマンドを mainwindow と mythread にも設定しようとしましたが、どちらも異なる問題が発生します (デバッグの問題や、テキストが textBrowser に表示されないなど)。これまでありがとう。

4

2 に答える 2

0

ああ、私は自分でそれを手に入れました。NEW関数()を作成して問題を解決しvoid forwarding(const Qstring);、その関数で通常のemit updateUI(text);..ものでそれを発行しました最終的に動作します!

于 2013-07-05T13:06:44.313 に答える
0

最終的に myServer-Object は MainThread で実行されないため、別のスレッドから ui 要素にアクセスするとアプリがクラッシュします。

次のコードを AppendToBrowser スロットに追加することで、mainThread からのメッセージのみが表示されるようにすることができます。

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接続)、MainWindow.cppにSIGNAL(SERVER)-> SLOT(MainWindow)への接続を追加します。最終的には 5 番目で接続呼び出しを試みます。キュー接続 (Qt::QueuedConnection IIRC) のパラメーター。

于 2013-07-05T10:29:58.927 に答える