use QThread exclusively for an object

只谈情不闲聊 提交于 2019-12-23 02:39:31

问题


EDIT2

Here is the solution that works for the following problem of giving a QThread exclusively to the object.

I've changed the approach for the problem. I don't want to close QThread in MyClass anymore, cause the following solution seems easier and not too bad looking.

My solution is modification of the solution given here: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

The problem with that solution was that QObject worker wasn't really deleted (checked it).

QThread *myThread = new QThread();
SCIntermediary* myObj = new MyClass();
myObj->moveToThread(myThread);
connect(myThread, SIGNAL(started()), myObj, SLOT(setup()));
connect(myObj, SIGNAL(destroyed()), myThread, SLOT(quit()), Qt::DirectConnection);
connect(myObj, SIGNAL(finished()), myObj, SLOT(deleteLater()));
connect(myThread, SIGNAL(finished()), myThread, SLOT(deleteLater()));
myThread -> start();

// do your work bla bla bla

myObj -> finishIt(); // this function only emits finish() signal of myObj
myThread -> wait();

This is the first solution that worked for me destroying both myObj and myThread without any errors or other troubles at all.

ENDOF EDIT

I'm trying to create a class will do some stuff between my client and my server. I'd like it to have it's own thread. So what I did is:

class Myclass : public QObject {
    Q_OBJECT
public:
    Myclass();
    ~Myclass();

private:
    QThread *my_thread;
    QTcpSocket *sock;
}

Here is how I coded my constructor:

Myclass::Myclass(){
    my_thread = new QThread();
    my_thread -> start();
    moveToThread(my_thread);

    sock = new QTcpSocket(this);
    sock -> connectToHost("host", port);
}

This didn't work. It didn't work, because the code for TcpSocket wasn't executed in the same thread the parent object currently is. So what I decided to do is to create slot and signal for setup and emit it in my constructor. Here is how my code looks right now.

class Myclass : public QObject {
    Q_OBJECT
public:
    Myclass();
    ~Myclass();

public slots:
    void setup();

signals:
    void do_setup();

private:
    QThread *my_thread;
    QTcpSocket *sock;
}

And some of it's implementation

Myclass::Myclass(){
    my_thread = new QThread();
    my_thread -> start();
    moveToThread(my_thread);

    connect(this, SIGNAL(do_setup()), this, SLOT(setup()));
    emit do_setup();
}

void Myclass::setup(){
    sock = new QTcpSocket();
    sock -> connectToHost("host", port);
}

Now it works and here comes the sad part - it looks terrible! It's awful and I have no idea how to make it look better or how such pattern should be done in the first place. What would you advice me to do to get the same effect?

Additionally - I have no idea how to write good destructor for this - how to delete QThread smoothly and all the class objects..

EDIT

For now I believe the solution is quite alright - the only problem left is how to write a destructor for that. I have no idea how it can be done here.


回答1:


For destructor, check out Maya Posch example: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ Since your thread is not child of MyClass, perhaps you can call finish() on thread as last thing in destructor and connect destroyed() signal of MyClass to deleteLater for thread?




回答2:


Instead of using a signal, you could use QMetaObject::invokeMethod http://qt-project.org/doc/qt-4.8/qmetaobject.html#invokeMethod

QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection);

But this is still heavy, but I guess this is the better option... If anyone have better idea, comment :-)




回答3:


What about this, I think manually moving socket to newly created thread right before connecting it should work, since both objects should be in the same thread which is newly created one?

Myclass::Myclass()
{
    my_thread = new QThread();
    my_thread -> start();
    moveToThread(my_thread);

    sock = new QTcpSocket(this);
    sock -> moveToThread(my_thread);
    sock -> connectToHost("host", port);
}


来源:https://stackoverflow.com/questions/14092915/use-qthread-exclusively-for-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!