1

编辑2

这是解决以下问题的解决方案,即专门为对象提供 QThread。

我已经改变了解决问题的方法。我不想再关闭 MyClass 中的 QThread 了,因为下面的解决方案看起来更容易而且看起来也不错。

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

该解决方案的问题是 QObject 工作人员并没有真正被删除(检查过)。

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 而没有任何错误或其他麻烦。

结束编辑

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

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 和所有类对象..

编辑

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

4

3 回答 3

1

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

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

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

于 2012-12-30T19:16:05.950 回答
1

对于析构函数,请查看 Maya Posch 示例: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ 因为您的线程不是MyClass,也许您可​​以在析构函数中调用线程上的finish()并将MyClass的destroy()信号连接到线程的deleteLater?

于 2013-01-06T03:17:33.933 回答
-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);
}
于 2012-12-31T16:49:56.153 回答