Multithreading – passing qlist * to signals from qthread

In my QT application, I have a class called from an object running in a thread In my worker class, I created qlist, just like this

QList <QString> albums;

while (i.hasNext())
{
  QRegularExpressionMatch album = i.next();
  albums.append(album.captured("album"));
}
emit SignalGotAlbums(albums);

I received this signal in another class containing my worker for thread use We call this class getalbumsthread There I successfully received signalgotalbums in a slot

void GetAlbumsThread::Reply(QList <QString> &list)
{

 emit gotAlbums(list);
 emit finished();
}

In this slot, I send another signal gotalbums, assuming it is connected to a slot in my GUI thread and passes my qlist there My problem is that when I try to pass qlist from a thread to the GUI, it just doesn't work! The slot does not receive the gotalbums signal;

The signal statement is as follows:

void gotAlbums(QList<QString> &);

And connect to my GUI slot (in my GUI thread of course):

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();

Albumsreceived has never been called for some reason Connect returns true Can someone help me with this I think the problem is passing qlist between threads

Solution

The problem here is that you are using the signal / slot reference, that is, qlist < qstring > & put This is not compatible with threads because they use their own private stack, in which case all you do is pass a pointer from one thread to another

The possibilities are:

>Using the original qlist < qstring > signal / slot will force replication. > Assign qlist < qstring > to use new (so it will enter the heap instead of the stack) and use qlist < qstring > * signal / slot

The following code illustrates both methods:

// 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>)),SLOT(bar(QList<int>)));
    QObject::connect(worker,SIGNAL(bar2(QList<int>*)),SLOT(bar2(QList<int>*)));

    QThread * thread = new QThread();
    worker->moveToThread(thread);

    QObject::connect(thread,worker,SLOT(process()));
    QObject::connect(worker,SIGNAL(finished()),thread,SLOT(quit()));
    QObject::connect(thread,&app,SLOT(quit()));
    thread->start();

    return app.exec();
}

Output:

1 
2 
3 
4 
5 
6 
7
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>