Qt应用程序状态生命周期

5

我开始使用Qt,但应用程序状态对我来说不太清楚。我使用的是Qt 5.5版本。目前我在Windows上学习,但下一步是要移植到Android设备上,因此我需要关注应用程序状态。

我创建了自己的派生于QApplication的类,并注册了applicationStateChanged信号。我猜测当信号被触发时,我应该保留我的配置部分。另外,由于我想要使用QML,我可能也需要使用Qt.labs.settings

很明显,我做错了几件事情。 首先,我没有接收到任何Qt::ApplicationSuspended消息。
我已经重写了QApplication::event(e)以查看是否错过了某个信号,但似乎只有Quit事件被发送。

QML debugging is enabled. Only use this in a safe environment.
void LAACApplication::event(QEvent *e = QEvent(LanguageChange, 0x28fd00) )
void LAACApplication::event(QEvent *e = QEvent(DynamicPropertyChange, 0x28fcbc) )
void LAACApplication::event(QEvent *e = QEvent(LanguageChange, 0x28fa70) )
void LAACApplication::event(QEvent *e = QEvent(ApplicationActivate, 0x28daf4) )
void LAACApplication::event(QEvent *e = QApplicationStateChangeEvent(ApplicationActive) )
void LAACApplication::onApplicationStateChanged(Qt::ApplicationState state = Qt::ApplicationState(ApplicationActive) )
void LAACApplication::event(QEvent *e = QEvent(Quit, 0x1fd88cc8) )
void LAACApplication::event(QEvent *e = QEvent(LanguageChange, 0x28fca0) )

也许我应该研究一下这里提到的QApplication::commitData()来执行这样的任务?
简而言之:我应该如何处理Qt中的应用程序状态更改?
这是我的代码: laacapplication.h
#ifndef LAACAPPLICATION_H
#define LAACAPPLICATION_H

#include <QApplication>

class LAACApplication : public QApplication
{
    Q_OBJECT
public:
    explicit LAACApplication(int &argc, char **argv);


public slots:
    void onApplicationStateChanged(Qt::ApplicationState state);

protected:
    bool event(QEvent * e);

private:
    void readSettings();
    void writeSettings();
};

#endif // LAACAPPLICATION_H

laacapplication.cpp (fragments)

void LAACApplication::onApplicationStateChanged(Qt::ApplicationState state)
{
    qDebug() << "void LAACApplication::onApplicationStateChanged(Qt::ApplicationState state =" << state << ")";
    if (Qt::ApplicationSuspended == state)
       writeSettings();
}

bool LAACApplication::event(QEvent *e)
{
    qDebug() << "void LAACApplication::event(QEvent *e =" << e << ")";
    return QApplication::event(e);
}

main.cpp

int main(int argc, char *argv[])
{
    LAACApplication app(argc, argv);

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

    QObject::connect(&app, SIGNAL(applicationStateChanged(Qt::ApplicationState)), &app, SLOT(onApplicationStateChanged(Qt::ApplicationState)));

    return app.exec();
}

顺便说一下,我没有成功地使用自动连接来连接我的信号和槽,因此需要显式调用 QObject::connect()


这里的惯例是在句子结尾和相应的问号之间不加空格。我改进了你的编辑,去掉了这些空格,认为让你知道这个原因可能会有用。 - jaggedSpire
1个回答

3
定义“应用程序状态”。在桌面平台上,状态表示您的应用程序是否具有焦点,请参见Qt::ApplicationState了解详情(例如,如果选择另一个窗口,它将失去焦点)。这些状态更改应该有效,至少对于我来说是如此。它们与应用程序“生命周期”无关(例如,在Android上)。如果您想要在程序退出时立即执行某些操作,请在您的main中执行或使用QCoreApplication::aboutToQuit信号。
对于桌面应用程序,在大多数情况下,您可以忽略状态。例如,可以使用上述方法之一在应用程序退出之前保存设置。但是在Android上,情况不同(请参见Android Activity了解更多详细信息。即使您创建了一个C++-Qt应用程序,生命周期仍然适用)。据我所知,活动状态中的这些更改不会传递给应用程序,但我实际上从未测试过。如果需要,您始终可以使用本机Java代码自己实现。请注意,即使您没有收到这些更改的通知,它们仍将发生,即您的应用程序将停止执行,并在应用程序重新获得焦点时恢复到停止的位置。
长话短说:在桌面平台上,您的应用程序将启动、运行并最终终止,而从未真正暂停(在正常情况下)。只有在程序结束时需要保存设置。
在Android上,“最小化”应用程序会将其暂停,但这是自动完成的。
您是否正在使用QSettings?尝试在进行更改时立即将其存储在其中,这样就不必担心数据丢失了。
关于连接问题:连接不会自动完成。有一个名为QMetaObject::connectSlotsByName的函数尝试创建基于名称的连接。如果您在setupUi函数中使用基于UI的Widget类,则会自动调用它。

谢谢。我的问题是关于正确使用Qt框架解释应用程序状态生命周期。我猜Qt旨在方便地解决现实生活中的问题,包括我不知道的问题。为了从这项工作中受益,我必须正确使用Qt框架。例如,我已经使用Java在Android上编写了一个小型原型,并且我必须处理应用程序状态。在计算期间,我的瞬态数据会自动完成什么?对于同时针对桌面和Android的应用程序,我应该捕获哪些消息? - SR_
嗯,这并不容易 - 要么你让Qt处理应用程序状态(你只需要关心数据发生了什么 - 因为它可以工作),要么你自己实现平台特定的解决方案。我建议在你明确需要特殊行为之前先采用第一种方法。 - Felix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接