与主线程在 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 () 信号;在课堂上建立联系someClassconnect (this, & someClass :: signalsomeClass3fromSomeClass, someClass2Var.someClass3Var, & someClass3 :: signalsomeClass3) ;

qml调用信号signalsomeClass3fromSomeClass时,应该调用信号 someClass3 :: signalsomeClass3 反过来调用插槽 someClass4 :: slotsomeClass4 - 但它没有。为什么?

如何实现主线程与另一个线程中创建的对象的通信?这是第一个问题。

第二个问题:someClass3someClass4 类在同一个线程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 的同一线程中使用

ProgrammingError:对象是在线程 id 14408 中创建的,这是线程 id 2776。我无法创建帐户

QT5线程关闭

当主线程显然未阻塞时,QProgressDialog 冻结

QT多线程操作