与主线程在 QThread 中创建的连接对象失败,并且一个 QThread 中的对象之间的连接失败
Posted
技术标签:
【中文标题】与主线程在 QThread 中创建的连接对象失败,并且一个 QThread 中的对象之间的连接失败【英文标题】:Fail connection objects created in QThread with main thread and fail connection beetwen objects in one QThread 【发布时间】:2021-12-18 21:58:38 【问题描述】:main
中的 someClass
some1
类对象在 qml
上下文中创建和注册。这个类创建了一个类someClass2Var = new someClass2 ();
,它被推送到线程someClass2Var-> moveToThread (& someThread);
。在这个类someClass2Var
在线程someThread
内部运行(运行)期间创建了两个对象:
发出someClass4Var = new someClass4 ();
和someClass3Var = new someClass3 ();
和signalVarCreated ()
信号;在课堂上建立联系someClass
connect (this, & someClass :: signalsomeClass3fromSomeClass, someClass2Var.someClass3Var, & someClass3 :: signalsomeClass3) ;
。
从qml
调用信号signalsomeClass3fromSomeClass
时,应该调用信号
someClass3 :: signalsomeClass3
反过来调用插槽 someClass4 :: slotsomeClass4
- 但它没有。为什么?
如何实现主线程与另一个线程中创建的对象的通信?这是第一个问题。
第二个问题:someClass3
和someClass4
类在同一个线程someThread
中,在someClass3
类中,当调用完成时会创建一个计时器并发出
与插槽someClass4 :: slotsomeClass4
关联的signalsomeClass3 ()
信号,但调用也不会发生。为什么?如何实施?有可能吗?
这个版本的工作是考虑让应用程序在android上工作,有一个项目在Windows下工作,当在Android中调用另一个服务时,应用程序会停止,我的想法是将必要的类转移到一个单独的线程,正如实践所表明的那样,它不会停止,与主线程不同,在当前项目中一切都已实现,所以我想尽可能多地这样做 要使用它,上述实现将是一个解决方案..
int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
someClass some1;
qmlRegisterType<someClass>("FuelCore", 1, 0, "SomeClass");
engine.rootContext()->setContextProperty("MySomeClass", &some1);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl)
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
, Qt::QueuedConnection);
engine.load(url);
return app.exec();
//---------------------------------------------------------
#ifndef SOMECLASS_H
#define SOMECLASS_H
#include <QObject>
#include <QThread>
#include "someclass2.h"
#include "someclass3.h"
#include "someclass4.h"
class someClass : public QObject
Q_OBJECT
public:
explicit someClass(QObject *parent = nullptr);
someClass2* someClass2Var;
QThread someThread;
signals:
void signalSomeClass();
void signalsomeClass3fromSomeClass();
;
#endif // SOMECLASS_H
//------------------------------------------------------------
#include "someclass.h"
someClass::someClass(QObject *parent) : QObject(parent)
someClass2Var = new someClass2();
connect(&someClass2Var, &someClass2::signalVarCreated, this, [this]()
connect(this,&someClass::signalsomeClass3fromSomeClass,someClass2Var.someClass3Var,&someClass3::signalsomeClass3);
);
connect(&someThread, &QThread::started, someClass2Var, &someClass2::run);
connect(this,&someClass::signalsomeClass3fromSomeClass,someClass2Var,&someClass2::signalsomeClass3_2);
someClass2Var->moveToThread(&someThread);
someClass2Var->setRunning(true);
someThread.start();
//----------------------------------------------------
#ifndef SOMECLASS2_H
#define SOMECLASS2_H
#include <QObject>
#include "someclass3.h"
#include "someclass4.h"
#include "someclass.h"
class someClass;
class someClass2 : public QObject
Q_OBJECT
public:
bool m_running;
explicit someClass2(QObject *parent = nullptr);
bool running() const;
void run();
int count;
void setRunning(bool running);
someClass3* someClass3Var;
someClass4* someClass4Var;
someClass *someParent;
signals:
void signalVarCreated();
void signalsomeClass3_2();
;
#endif // SOMECLASS2_H
//-------------------------------------------
#include "someclass2.h"
#include <QDebug>
#include <QThread>
someClass2::someClass2(QObject *parent) : QObject(parent)
bool someClass2::running() const
return m_running;
void someClass2::run()
someClass4Var= new someClass4();
someClass3Var= new someClass3();
connect(someClass3Var,&someClass3::signalsomeClass3,someClass4Var,&someClass4::slotsomeClass4);
signalVarCreated();
connect(this,&someClass2::signalsomeClass3_2,someClass4Var,&someClass4::slotsomeClass4);
while (m_running)
count++;
QThread::sleep (1);
void someClass2::setRunning(bool running)
if (m_running == running)
return;
m_running = running;
//----------------------------------------------------
#ifndef SOMECLASS3_H
#define SOMECLASS3_H
#include <QObject>
#include <QTimer>
class someClass3 : public QObject
Q_OBJECT
public:
explicit someClass3(QObject *parent = nullptr);
QTimer* tim;
signals:
void signalsomeClass3();
;
#endif // SOMECLASS3_H
//---------------------------------------------------
#include "someclass3.h"
#include <QThread>
#include <QDebug>
#include <QTimer>
someClass3::someClass3(QObject *parent) : QObject(parent)
tim = new QTimer();
tim->start(5000);
connect(tim, &QTimer::timeout, this, [this]()emit signalsomeClass3(););
//--------------------------------------------------
#ifndef SOMECLASS4_H
#define SOMECLASS4_H
#include <QObject>
#include <QDebug>
class someClass4 : public QObject
Q_OBJECT
public:
explicit someClass4(QObject *parent = nullptr);
signals:
public slots:
void slotsomeClass4() qDebug()<<"voidslotsomeClass4";;
;
#endif // SOMECLASS4_H
//------------------------------------------------------------
Window
visible: true
width: 640
height: 480
Button
text: "Call someClass4 slot of object in QThread"
onClicked:
MySomeClass.signalsomeClass3fromSomeClass()
【问题讨论】:
请edit您的问题:格式化文本,将其拆分为段落等等,以减少阅读的痛苦。 【参考方案1】:在清单中设置以下行
元数据android:名称=“android.app.background_running”android: 值 = “真”
解决了我在与 Android 上运行的 Qt 应用程序的活动重叠时停止的问题。因此,不再需要进行上述操作。
【讨论】:
【参考方案2】:为什么你从 qml 调用“signalsomeClass3fromSomeClass()”? 你标记为信号,我认为它一定是槽 请检查此https://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html
【讨论】:
如果我接受: someClass4Var= new someClass4(); someClass3Var=新的 someClass3();连接(someClass3Var,&someClass3::signalsomeClass3,someClass4Var,&someClass4::slotsomeClass4);信号变量创建();连接(这个,&someClass2::signalsomeClass3_2,someClass4Var,&someClass4::slotsomeClass4);从附加线程(void someClass2::run())到主线程(在构造函数 someClass2::someClass2(QObject *parent) 中创建它),然后一切都会工作,但我需要在附加线程中创建对象和链接它们,但据我了解这是不可能的 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。以上是关于与主线程在 QThread 中创建的连接对象失败,并且一个 QThread 中的对象之间的连接失败的主要内容,如果未能解决你的问题,请参考以下文章
使用 Flask 中的 SQLAlchemy 会话会引发“在线程中创建的 SQLite 对象只能在同一线程中使用”
在线程中创建的 SQLite 对象只能在 Django 2.2.2 和 ipdb 的同一线程中使用