gpt4 book ai didi

c++ - QObject : Cannot create children for a parent that is in a different thread

转载 作者:可可西里 更新时间:2023-11-01 18:15:18 26 4
gpt4 key购买 nike

编辑:

我试着按照你们在评论中告诉我的去做......:

Citizen * c = new Citizen(this);

QThread thread;
c->moveToThread(&thread);

connect(&thread, SIGNAL(started()), c, SLOT(ProcessActions()));
thread.start();

这会产生更多错误:

QThread: Destroyed while thread is still running
ASSERT failure in QThread::setTerminationEnabled(): "Current thread was not started with QThread.", file c:\ndk_buildrepos\qt-desktop\src\corelib\thread\qthread_win.cpp, line 542
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
QObject::killTimers: timers cannot be stopped from another thread

我遇到了这个错误的问题......我已经坚持了 2 天,无法找到解决方案。

标题:

class Citizen : public QThread
{
Q_OBJECT
QNetworkAccessManager * manager;

private slots:
void onReplyFinished(QNetworkReply* net_reply);

public:
Citizen(QObject * parent);

void run();
};

实现:

Citizen::Citizen(QObject * parent)
{
manager = new QNetworkAccessManager;
connect(_net_acc_mgr, SIGNAL(finished(QNetworkReply*)),
this, SLOT(onReplyFinished(QNetworkReply*)));
}

void Citizen::onReplyFinished(QNetworkReply* net_reply)
{
emit onFinished(net_reply);
}

void Citizen::run()
{
manager->get(QNetworkRequest(QUrl("http://google.com"));

QEventLoop eLoop;
connect(manager, SIGNAL( finished( QNetworkReply * ) ), &eLoop, SLOT(quit()));
eLoop.exec(QEventLoop::ExcludeUserInputEvents);

qDebug() << "loaded google!";

exec();
}

当执行 manager->get() 时,出现以下错误:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNetworkAccessManager(0xc996cf8), parent's thread is QThread(0xaba48d8), current thread is Citizen(0xca7ae08)

当 eLoop.exec() 被执行时:

QObject::startTimer: timers cannot be started from another thread

我按以下方式启动此线程:

Citizen * c = new Citizen(this);
c->start();

为什么会这样?如何解决?

最佳答案

QObject: Cannot create children for a parent that is in a different thread.

你得到这个是因为你在 Citizen 的构造函数中创建了 QNetworkAccessmanager,它在“原始”线程中被调用。当 Citizen 对象移动到新线程时,QNetworkAccessmanager 仍然将其线程关联设置为原始线程,但在运行调用中它将尝试在新线程中创建 QNetworkReply 对象(可能还有其他对象)。这会产生上述警告。

如果您在运行槽中创建管理器(或在 Citizen 对象移动到新线程后的任何时候),则不会发生这种情况。

但是你还有一些问题。例如,Citizen 类实际上不需要是 QThread。它不必要地使它复杂化。将 QObject 子类化就足以满足您的目的(afaict)。只需制作一个普通插槽并将其连接到 QThread::started() 信号即可。正如 OrcunC 指出的那样,您需要确保 QThread 实例的范围正确。

有关线程的更多信息:http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

例子:

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

//startWorking can be equivalent of the run function
//in your current implementation and this is where you should
//create the QNetworkAccessManager
QMetaObject::invokeMethod(worker,"startWorking");

关于c++ - QObject : Cannot create children for a parent that is in a different thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6900994/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com