0

よし、これで取り引きだ。

現在、SysV IPC を使用して小さなチャット メッセージング シミュレーション/プロジェクトを作成しており、クライアント アプリに Qt を使用しています。私が欲しいのは、メッセージ キューで待機し、新しいメッセージが来るたびにシグナルを GUI スレッドに送信するバックグラウンド スレッドです。QThread の継承を使用してコードを記述しようとしましたが、うまくいかないようで、メッセージが表示されず、ここに何かが欠けていると思います。

コードについて: ipcEventListener.h:

class IPCEventListener : public QThread
{
    Q_OBJECT
public:
    IPCEventListener();
    void run();
    messageWrapper mw;
signals:
    void sendChatMsg(MSG_CHAT_MESSAGE cm);
};

ipcEventListener.cpp

IPCEventListener::IPCEventListener()
{

}
void IPCEventListener::run()
{
        mutex.lock();
        int n = msgrcv(myQueueId, &mw, sizeof(mw)-sizeof(long), 0, IPC_NOWAIT);
        mutex.unlock();
        if (n>0)
        {
            snip...
            else if (mw.resp.type == MESSAGE)
            {
                emit sendChatMsg(mw.chatMsg);
            }
        }
    exec();
}

メインウィンドウ.cpp:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    listener = new IPCEventListener(this);
    connect(this->listener, SIGNAL(sendChatMsg(MSG_CHAT_MESSAGE)), this, SLOT(message_received(MSG_CHAT_MESSAGE)));
    connect(this->ui->pushButton, SIGNAL(clicked()), this, SLOT(on_pushButton_clicked()));
    listener->start();
    ui->comboBox->addItem("Client");
    ui->comboBox->addItem("Room");
}
void MainWindow::message_received(MSG_CHAT_MESSAGE cm)
{
    QString formattedMessage = "";
    formattedMessage.append("[");
    formattedMessage.append(cm.send_time);
    formattedMessage.append("] ");
    if (cm.msg_type == PRIVATE) formattedMessage.append("[PRIV:] ");
    formattedMessage.append(cm.sender);
    formattedMessage.append(": ");
    formattedMessage.append(cm.message);
    formattedMessage.append("\n");
    ui->textEdit->append(formattedMessage);
}

私は何が欠けていますか?

(PS: このコードがおそらく約 10 万のコード規則に違反していることはわかっていますが、締め切りが迫っているので、手抜きをしなければなりません。ただし、これは単なる学校のプロジェクトです)。

4

1 に答える 1

2

コードに論理エラーがあります。void IPCEventListener::run() をループ内にあり、再度実行しているメソッドとして扱いますが、そうではありません。QThread::run() は、スレッドを初期化して exec() 関数を実行し、イベント ループを開始するメソッドです。これは、アプリケーションの現在のバージョンでは、メッセージを一度だけ受信しようとすると、スレッドは何もせずにいくつかのイベントを待機していることを意味します。

したがって、必要なのは、メッセージを受信しようとする inifite ループです。プログラムを閉じている間、このループを停止することを忘れないでください。

于 2013-03-07T21:12:45.037 に答える