我只是不明白Qt中的线程

I just don't understand threads in Qt

本文关键字:线程 Qt 明白      更新时间:2023-10-16

好了,事情是这样的。

我目前正在使用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();
}

mainwindow.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:我知道代码可能违反了大约十万种代码约定,但截止日期很快就到了,我不得不求助于拼凑。不过这只是一个学校的项目)。

您的代码中存在逻辑错误。你把void IPCEventListener::run()作为一个方法,它在一个循环中,再次执行,但它不是。QThread::run()是一个方法,你只需要初始化你的线程并执行exec()函数来启动事件循环。这意味着在当前版本的应用程序中,您尝试只接收一次消息,然后您的线程只是等待一些事件,而不使用它们做任何事情。

因此,您需要的是一个无限循环,您将尝试在其中接收消息。不要忘记在程序关闭时停止这个循环。