从后台工作线程修改Qt GUI [英] Modify Qt GUI from background worker thread

查看:287
本文介绍了从后台工作线程修改Qt GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Qt工作,当我按下GO按钮时,我需要不断将包裹发送到网络并使用收到的信息修改界面.

问题是我的按钮中有一个while(1),因此按钮从未完成,因此界面从未更新.我想在按钮上创建一个线程,然后在其中放置while(){}代码.

我的问题是如何从线程修改接口? (例如,如何修改线程中的textBox?

解决方案

关于Qt的重要事项是,您必须只能从GUI线程(即主线程)使用Qt GUI.

这就是为什么执行此操作的正确方法是从工作线程中通知主线程,并且主线程中的代码实际上会更新文本框,进度栏或其他内容.

我认为,最好的方法是使用QThread而不是posix线程,并使用Qt signals 在线程之间进行通信.这将是您的工人,thread_func的替代者:

class WorkerThread : public QThread {
    void run() {
        while(1) {
             // ... hard work
             // Now want to notify main thread:
             emit progressChanged("Some info");
        }
    }
    // Define signal:
    signals:
    void progressChanged(QString info);
};

在窗口小部件中,定义一个插槽,其原型与.h中的信号相同:

class MyWidget : public QWidget {
    // Your gui code

    // Define slot:
    public slots:
    void onProgressChanged(QString info);
};

在.cpp中实现此功能:

void MyWidget::onProgressChanged(QString info) {
    // Processing code
    textBox->setText("Latest info: " + info);
}

现在在您要生成线程的位置(单击按钮):

void MyWidget::startWorkInAThread() {
    // Create an instance of your woker
    WorkerThread *workerThread = new WorkerThread;
    // Connect our signal and slot
    connect(workerThread, SIGNAL(progressChanged(QString)),
                          SLOT(onProgressChanged(QString)));
    // Setup callback for cleanup when it finishes
    connect(workerThread, SIGNAL(finished()),
            workerThread, SLOT(deleteLater()));
    // Run, Forest, run!
    workerThread->start(); // This invokes WorkerThread::run in a new thread
}

连接信号和插槽后,在工作线程中发出带有emit progressChanged(...)的插槽将向主线程发送消息,并且主线程将在此调用连接到该信号的插槽.

P.s.我尚未测试代码,因此如果我在某个地方输入错误,请随时提出修改建议

I work in Qt and when I press the button GO I need to continuously send packages to the network and modify the interface with the information I receive.

The problem is that I have a while(1) in the button so the button never finishes so the interface is never updated. I thought to create a thread in the button and put the while(){} code there.

My question is how can I modify the interface from the thread? (For example how can I modify a textBox from the thread ?

解决方案

Important thing about Qt is that you must work with Qt GUI only from GUI thread, that is main thread.

That's why the proper way to do this is to notify main thread from worker, and the code in main thread will actually update text box, progress bar or something else.

The best way to do this, I think, is use QThread instead of posix thread, and use Qt signals for communicating between threads. This will be your worker, a replacer of thread_func:

class WorkerThread : public QThread {
    void run() {
        while(1) {
             // ... hard work
             // Now want to notify main thread:
             emit progressChanged("Some info");
        }
    }
    // Define signal:
    signals:
    void progressChanged(QString info);
};

In your widget, define a slot with same prototype as signal in .h:

class MyWidget : public QWidget {
    // Your gui code

    // Define slot:
    public slots:
    void onProgressChanged(QString info);
};

In .cpp implement this function:

void MyWidget::onProgressChanged(QString info) {
    // Processing code
    textBox->setText("Latest info: " + info);
}

Now in that place where you want to spawn a thread (on button click):

void MyWidget::startWorkInAThread() {
    // Create an instance of your woker
    WorkerThread *workerThread = new WorkerThread;
    // Connect our signal and slot
    connect(workerThread, SIGNAL(progressChanged(QString)),
                          SLOT(onProgressChanged(QString)));
    // Setup callback for cleanup when it finishes
    connect(workerThread, SIGNAL(finished()),
            workerThread, SLOT(deleteLater()));
    // Run, Forest, run!
    workerThread->start(); // This invokes WorkerThread::run in a new thread
}

After you connect signal and slot, emiting slot with emit progressChanged(...) in worker thread will send message to main thread and main thread will call the slot that is connected to that signal, onProgressChanged here.

P.s. I haven't tested the code yet so feel free to suggest an edit if I'm wrong somewhere

这篇关于从后台工作线程修改Qt GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆