Qt - 用第二个线程更新主窗口 [英] Qt - updating main window with second thread

查看:366
本文介绍了Qt - 用第二个线程更新主窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多线程的qt应用程序。当我在mainwindow.cpp中做一些进程的同时,我想从其他线程更新mainwindow.ui。

i have an multithreaded qt application. when i am doing some processes in mainwindow.cpp, at the same time, i want to update mainwindow.ui from other thread.

我有mythread.h

i have mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include "mainwindow.h"

class mythread : public QThread
{
    public:
        void run();
        mythread( MainWindow* ana );
     MainWindow* ana;
private:

};

#endif // MYTHREAD_H

mythread.cpp

mythread.cpp

mythread::mythread(MainWindow* a)
{
    cout << "thread created" << endl;
        ana = a;
}

void mythread::run()
{
    QPixmap i1 (":/notes/pic/4mdodiyez.jpg");
    QLabel *label = new QLabel();
    label->setPixmap(i1);
    ana->ui->horizontalLayout_4->addWidget(label);


}

但问题是,到达 ana-> ui-> horizo​​ntalLayout_4-> addWidget(label);

这是吗?

推荐答案


但问题是,我无法达到
ana - > ui-> horizo​​ntalLayout_4-> addWidget(label);

but the problem is that, i cannot reach the ana->ui->horizontalLayout_4->addWidget(label);

将UI修改放在主窗口的插槽中,一个线程信号到那个插槽,它会工作的机会。我认为只有主线程可以访问Qt中的UI。因此,如果你想要GUI功能,它必须在那里,并且只能从其他线程发出信号。

Put your UI modifications in a slot in your main window, and connect a thread signal to that slot, chances are it will work. I think only the main thread has access to the UI in Qt. Thus if you want GUI functionality, it must be there, and can be only signaled from other threads.

好,这里是一个简单的例子。 BTW,你的场景并不需要扩展 QThread - 所以你最好不要这样做,除非你真的需要。这就是为什么在这个例子中,我将使用一个 QThread 和一个 QObject 的工人,但概念是同样如果你的子类 QThread

OK, here is a simple example. BTW, your scenario doesn't really require to extend QThread - so you are better off not doing it, unless you really have to. That is why in this example I will use a normal QThread with a QObject based worker instead, but the concept is the same if you subclass QThread:

主UI:

class MainUI : public QWidget
{
    Q_OBJECT

public:
    explicit MainUI(QWidget *parent = 0): QWidget(parent) {
        layout = new QHBoxLayout(this);
        setLayout(layout);
        QThread *thread = new QThread(this);
        GUIUpdater *updater = new GUIUpdater();
        updater->moveToThread(thread);
        connect(updater, SIGNAL(requestNewLabel(QString)), this, SLOT(createLabel(QString)));
        connect(thread, SIGNAL(destroyed()), updater, SLOT(deleteLater()));

        updater->newLabel("h:/test.png");
    }

public slots:
    void createLabel(const QString &imgSource) {
        QPixmap i1(imgSource);
        QLabel *label = new QLabel(this);
        label->setPixmap(i1);
        layout->addWidget(label);
    }

private:
    QHBoxLayout *layout;
};

...和工作对象:

class GUIUpdater : public QObject {
    Q_OBJECT

public:
    explicit GUIUpdater(QObject *parent = 0) : QObject(parent) {}    
    void newLabel(const QString &image) { emit requestNewLabel(image); }

signals:    
    void requestNewLabel(const QString &);
};

创建工作对象并移动到另一个线程,然后连接到创建标签的插槽,那么它的 newLabel 方法被调用,它只是一个包装器来发出 requestNewLabel 信号并将路径传递给图像。然后,将信号从工作线程对象/线程传递到主UI插槽以及镜像路径参数,并将一个新标签添加到布局中。

The worker object is created and moved to another thread, then connected to the slot that creates the labels, then its newLabel method is invoked, which is just a wrapper to emit the requestNewLabel signal and pass the path to the image. The signal is then passed from the worker object/thread to the main UI slot along with the image path parameter and a new label is added to the layout.

对象被创建没有父,为了能够移动到另一个线程,我们还连接线程销毁信号到工人 deleteLater()槽。

Since the worker object is created without parent in order to be able to move it to another thread, we also connect the thread destroyed signal to the worker deleteLater() slot.

这篇关于Qt - 用第二个线程更新主窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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