【发布时间】:2012-12-30 17:33:55
【问题描述】:
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 编辑
我正在尝试创建一个类,它将在我的客户端和服务器之间做一些事情。我希望它有自己的线程。所以我做的是:
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 和所有类对象..
编辑
目前我认为解决方案还不错——剩下的唯一问题是如何为此编写析构函数。我不知道如何在这里完成。
【问题讨论】:
-
是的,不再推荐继承QThread,参见Qt文档
-
出于好奇,如果您在原始示例中使用 moveToThread(my_thread); 放置的位置,它会改变什么吗?比如说,如果您将该语句作为构造函数的最后一行 - 那么您将对象及其所有子对象移动到新线程后,一旦它完全构造?或者,就在连接套接字之前但在创建之后?
-
@IlyaKobelevskiy qt-project.org/doc/qt-4.8/qthread.html:“详细说明”和“注释(页面底部)”
-
对于析构函数,请查看 Maya Posch 示例 - mayaposch.wordpress.com/2011/11/01/… 由于您的线程不是 MyClass 的子线程,也许您可以在析构函数中将线程作为第一件事完成,并将完成的信号连接到 deleteLater 线程?跨度>
-
有一些示例说明如何在不继承 QThread 的情况下正确执行此操作。您应该将自定义插槽连接到线程启动和停止时发出的信号......然后启动线程。线程发出的信号将调用槽并且仍然在该线程中。不要对该主线程中的对象执行任何其他操作。
标签: multithreading qt qthread qt4.8