将QThread专门用于对象

时间:2012-12-30 17:33:55

标签: multithreading qt qthread qt4.8

EDIT2

以下解决方案适用于将QThread专门提供给对象的以下问题。

我已经改变了问题的方法。我不想再在MyClass中关闭QThread了,因为下面的解决方案看起来更简单,也不会太糟糕。

我的解决方案是修改此处给出的解决方案:http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

该解决方案的问题在于没有真正删除QObject worker(检查它)。

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

这是第一个解决myObj和myThread问题的解决方案,没有任何错误或其他麻烦。

ENDOF EDIT

我正在尝试创建一个类,在我的客户端和服务器之间做一些事情。我希望它有自己的线程。所以我做的是:

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

private:
    QThread *my_thread;
    QTcpSocket *sock;
}

以下是我对构造函数进行编码的方法:

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

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

这不起作用。它没有用,因为TcpSocket的代码没有在父对象当前所在的同一个线程中执行。所以我决定创建插槽和信号进行设置并在我的构造函数中发出它。以下是我的代码现在的样子。

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

public slots:
    void setup();

signals:
    void do_setup();

private:
    QThread *my_thread;
    QTcpSocket *sock;
}

其中一些实现

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

现在它起作用了,这里出现了悲伤的部分 - 它看起来很可怕!这很糟糕,我不知道如何让它看起来更好或者首先应该如何完成这样的模式。你有什么建议我去做同样的效果?

另外 - 我不知道如何为此编写好的析构函数 - 如何平滑地删除QThread以及所有类对象..

修改

现在我相信解决方案非常好 - 剩下的唯一问题是如何为此编写析构函数。我不知道如何在这里完成。

3 个答案:

答案 0 :(得分:1)

您可以使用QMetaObject::invokeMethod http://qt-project.org/doc/qt-4.8/qmetaobject.html#invokeMethod

,而不是使用信号
QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection);

但这仍然很重,但我想这是更好的选择......如果有人有更好的想法,请评论: - )

答案 1 :(得分:1)

对于析构函数,请查看Maya Posch示例: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ 既然你的线程不是MyClass的子代,也许你可以在线程上调用finish()作为析构函数中的最后一件事,并将MyClass的destroyed()信号连接到deleteLater for thread?

答案 2 :(得分:-1)

这个怎么样,我认为在连接它之前手动将套接字移动到新创建的线程应该可以工作,因为两个对象应该在新创建的一个线程中?

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

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