Sir*_*aat 4 qt multithreading signals qlist slot
在我的 qt 应用程序中,我有一个类(worker),它是从在线程中运行的对象调用的。在我的工人阶级中,我创建了 QList,如下所示
QList <QString> albums;
while (i.hasNext())
{
QRegularExpressionMatch album = i.next();
albums.append(album.captured("album"));
}
emit SignalGotAlbums(albums);
Run Code Online (Sandbox Code Playgroud)
我在另一个包装我的工作线程的类中收到这个信号,以供线程使用。我们将此类命名为 GetAlbumsThread。在那里我成功地在插槽中接收到 SignalGotAlbums
void GetAlbumsThread::Reply(QList <QString> &list)
{
emit gotAlbums(list);
emit finished();
}
Run Code Online (Sandbox Code Playgroud)
在这个插槽中,我正在触发另一个信号gotAlbums,该信号应该与我的gui线程中的插槽连接,并将我的QList传递到那里。我的问题是,当我尝试将 QList 从线程传递到 gui 时,它不起作用!插槽未收到 gotAlbums 信号;
信号声明如下:
void gotAlbums(QList<QString> &);
Run Code Online (Sandbox Code Playgroud)
并连接到我的 gui 插槽(当然在我的 gui 线程中),如下所示:
private slots:
void AlbumsReceived(QList<QString> &list)
...
QThread* albumsThread = new QThread();
GetAlbumsThread *albumsObject = new GetAlbumsThread();
albumsObject->moveToThread(albumsThread);
connect(albumsThread, SIGNAL(started()), albumsObject, SLOT(process()));
connect(albumsObject, SIGNAL(gotAlbums(QList<QString> &)), this, SLOT(AlbumsReceived(QList<QString> &));
albumsThread->start();
Run Code Online (Sandbox Code Playgroud)
由于某种原因,AlbumsReceived 从未被调用。连接返回真。有人可以帮我弄这个吗。我认为问题在于线程之间传递 QList。
小智 6
您是否尝试在调用 Object::connect(...) 之前注册 QList 对象?
您可以使用以下代码声明元类型:
qRegisterMetaType< QList<QString> >( "QList<QString>" );
Run Code Online (Sandbox Code Playgroud)
这里的问题是您正在使用信号/槽的参考,即QList<QString> &. 这与线程不兼容,因为它们使用自己的私有堆栈,在这种情况下,您要做的是将指向堆栈中对象的指针从一个线程传递到另一个线程。
可能性是:
QList<QString>信号/槽,这将强制进行复制。QList<QString>a 分配new(因此将进入堆而不是堆栈),并使用QList<QString> *信号/槽。下面的代码说明了这两种方法:
// A.h
#include <QObject>
#include <QDebug>
class A: public QObject
{
Q_OBJECT
public slots:
void foo(int i) { qDebug() << i; }
void bar(QList<int> l) { foreach(int i, l) qDebug() << i; }
void bar2(QList<int> * l) { foreach(int i, *l) qDebug() << i; }
};
// Worker.h
#include <QObject>
class Worker: public QObject
{
Q_OBJECT
public slots:
void process()
{
// pass an int
emit foo(1);
// pass a list by value
emit bar(QList<int>() << 2 << 3 << 4);
// pass a poniter to a list
list = new QList<int>();
*list << 5 << 6 << 7;
emit bar2(list);
emit finished();
}
signals:
void finished();
void foo(int);
void bar(QList<int>);
void bar2(QList<int> *);
private:
QList<int> * list;
};
// main.cpp
#include <QApplication>
#include <QThread>
#include <QObject>
#include "A.h"
#include "Worker.h"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
A * a = new A();
Worker * worker = new Worker();
QObject::connect(worker, SIGNAL(foo(int)), a, SLOT(foo(int)));
QObject::connect(worker, SIGNAL(bar(QList<int>)), a, SLOT(bar(QList<int>)));
QObject::connect(worker, SIGNAL(bar2(QList<int>*)), a, SLOT(bar2(QList<int>*)));
QThread * thread = new QThread();
worker->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), worker, SLOT(process()));
QObject::connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
QObject::connect(thread, SIGNAL(finished()), &app, SLOT(quit()));
thread->start();
return app.exec();
}
Run Code Online (Sandbox Code Playgroud)
输出:
1
2
3
4
5
6
7
Run Code Online (Sandbox Code Playgroud)