【问题标题】:Qt connect - object emits signal before connect is issuedQt connect - 对象在发出连接之前发出信号
【发布时间】:2015-09-14 17:42:45
【问题描述】:

我有关注main.cpp:

#include <QtQml>
#include <QApplication>
#include <QQmlApplicationEngine>

#include "database/uepeoplemodel.h"
#include "core/uestatus.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;

    UeStatus* ueApplicationStatus=new UeStatus(qApp);
    UePeopleModel* uePeopleModel=new UePeopleModel(qApp);

    QObject::connect(uePeopleModel,
                     SIGNAL(ueSignalDatabaseConnectionChanged(UeTypeDatabaseConnectionStatus)),
                     ueApplicationStatus,
                     SLOT(ueSignalDatabaseConnectionChanged(UeTypeDatabaseConnectionStatus)));

    engine.rootContext()->setContextProperty("uePeopleModel",
                                             uePeopleModel);
    engine.rootContext()->setContextProperty("ueApplicationStatus",
                                             ueApplicationStatus);
    engine.addImageProvider(QLatin1String("uePeopleModel"),
                            uePeopleModel);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

现在,在main.cpp 中,我从类中创建了两个对象:

UeStatus* ueApplicationStatus=new UeStatus(qApp);
UePeopleModel* uePeopleModel=new UePeopleModel(qApp);

我将来自UePeopleModel 的信号连接到ueApplicationStatus 中的插槽:

QObject::connect(uePeopleModel,
    SIGNAL(ueSignalDatabaseConnectionChanged(UeTypeDatabaseConnectionStatus)), 
    ueApplicationStatus,
    SLOT(ueSignalDatabaseConnectionChanged(UeTypeDatabaseConnectionStatus)));

问题是在创建uePeopleModel 时,在构造函数中发出信号:

UePeopleModel::UePeopleModel(QObject* parent)
    : QSqlQueryModel(parent),
      QQuickImageProvider(QQmlImageProviderBase::Image,
                          QQmlImageProviderBase::ForceAsynchronousImageLoading)
{
    if(!QSqlDatabase::connectionNames().contains(UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE,
                                                 Qt::CaseInsensitive))
    {
        this->ueSetDatabase(QSqlDatabase::addDatabase(UePosDatabase::DATABASE_DRIVER,
                                                      UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE));
    }   // if

    this->ueDatabase().setHostName(/*this->uePosSettings()->ueDbHostname()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_HOSTNAME);
    this->ueDatabase().setDatabaseName(/*this->uePosSettings()->ueDbName()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_NAME);
    this->ueDatabase().setUserName(/*this->uePosSettings()->ueDbUser()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_USERNAME);
    this->ueDatabase().setPassword(/*this->uePosSettings()->ueDbPassword()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_PASSWORD);

    if(this->ueDatabase().open())
    {
        emit this->ueSignalDatabaseConnectionChanged(CONNECTED);
        this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE,
                       this->ueDatabase());
/*
        if(this->lastError().isValid())
            qDebug() << this->lastError();
*/
    }
    else
    {
        emit this->ueSignalDatabaseConnectionChanged(NOT_CONNECTED);
//        qDebug() << this->ueDatabase().lastError();
    }

//    qDebug() << this->ueDatabase().connectionNames();
}   // default constructor

connect 发出之前,ueApplicationStatus 对象没有捕获带有插槽。有谁知道如何摆脱这种情况?

【问题讨论】:

  • "问题是在创建 uePeopleModel 时,在构造函数中发出信号:"好吧,不要那样做!说真的,这是什么问题?

标签: qt qt-signals


【解决方案1】:

您不应该使用构造函数打开与数据库的连接。

构造函数只用于实例化其他类、初始化变量、分配内存等。

在您的情况下,您的构造函数应该用于初始化数据库,但您可以创建另一个方法:

if(this->ueDatabase().open())
    {
        emit this->ueSignalDatabaseConnectionChanged(CONNECTED);
        this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE,
                       this->ueDatabase());
    }
    else
    {
        emit this->ueSignalDatabaseConnectionChanged(NOT_CONNECTED);
}

此方法将在您的main.cpp 中的connect 之后调用。

【讨论】:

    【解决方案2】:

    我通过添加方法void ueConnectToDatabase() 解决了这个问题,并将构造函数的内容移入其中并将main.cpp 重新定义为:

    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        UeStatus* ueApplicationStatus=new UeStatus(qApp);
        UePeopleModel* uePeopleModel=new UePeopleModel(qApp);
    
        QObject::connect(uePeopleModel,
                         SIGNAL(ueSignalDatabaseConnectionChanged(UeTypeDatabaseConnectionStatus)),
                         ueApplicationStatus,
                         SLOT(ueSignalDatabaseConnectionChanged(UeTypeDatabaseConnectionStatus)));
    
        uePeopleModel->ueConnectToDatabase();
    
        engine.rootContext()->setContextProperty("uePeopleModel",
                                                 uePeopleModel);
        engine.rootContext()->setContextProperty("ueApplicationStatus",
                                                 ueApplicationStatus);
        engine.addImageProvider(QLatin1String("uePeopleModel"),
                                uePeopleModel);
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
        return app.exec();
    }
    

    现在对象已创建,信号和槽已连接,之后发生与数据库的连接。

    【讨论】:

    • 嘿嘿嘿,和我提出的解决方案一样:)太棒了;)
    • @Tarod 还是谢谢你!今天,我并没有考虑 100% 的容量。我应该在不发布问题的情况下记住解决方案:)。
    猜你喜欢
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 1970-01-01
    • 2013-02-07
    相关资源
    最近更新 更多