QApplication学习

对于QCoreApplication,QGuiApplication以及QApplication,我一直分的不是很清楚,今天来梳理一下,并顺便记一些相关的笔记。

以下内容全部是自己的理解,有不正确的地方,欢迎大佬指出!

QCoreApplication

QCoreApplication位于core模块,源码在Src\qtbase\src\corelib\kernel目录下,为应用程序提供了一个非gui的事件循环。

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    return a.exec();
}

在程序中,我们只实例化一个QCoreApplication,然后调用exec()进入事件循环,我们看一下具体做了什么。

int QCoreApplication::exec()
{
    if (!QCoreApplicationPrivate::checkInstance("exec"))
        return -1;

    QThreadData *threadData = self->d_func()->threadData;
    if (threadData != QThreadData::current()) {
        qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
        return -1;
    }
    if (!threadData->eventLoops.isEmpty()) {
        qWarning("QCoreApplication::exec: The event loop is already running");
        return -1;
    }

    threadData->quitNow = false;
    QEventLoop eventLoop;
    self->d_func()->in_exec = true;
    self->d_func()->aboutToQuitEmitted = false;
    int returnCode = eventLoop.exec();
    threadData->quitNow = false;

    if (self)
        self->d_func()->execCleanup();

    return returnCode;
}

从代码中可以看出,我们只能在主线程中调用QCoreApplication的exec()接口。

在ecec()中,创建了一个事件循环eventLoop,调用了eventLoop.exec(),我们来看下做了什么。

    // remove posted quit events when entering a new event loop
    QCoreApplication *app = QCoreApplication::instance();
    if (app && app->thread() == thread())
        QCoreApplication::removePostedEvents(app, QEvent::Quit);

    while (!d->exit.loadAcquire())
        processEvents(flags | WaitForMoreEvents | EventLoopExec);

    ref.exceptionCaught = false;
    return d->returnCode.load();

从代码中可以看出QCoreApplication可以算是个单例类。在这个接口里,调用了processEvents进行事件分发,对于不同的平台有着不同的实现,以满足跨平台的需求。

关于接下来如何进行事件的post和send,留待以后的篇幅,我们再看看QCoreApplication有哪些常用的接口。

static QCoreApplication *instance(),等同于qApp宏,可以获取到QCoreApplication的指针。

void aboutToQuit(QPrivateSignal),是个私有信号,不能主动触发,该信号会在应用程序将要退出事件循环时发出,比如调用了quit()或者exit(0)的时候触发,可以进行一些程序的扫尾工作。

static void exit(int retcode=0),停止事件循环,一般回退出程序,其中quit()就是调用了exit(0)。

static qint64 applicationPid(),获取当前进程的pid。   

static QString applicationDirPath(),获取执行文件所在的目录。

static QString applicationFilePath(),获取执行文件所在的位置。    

static void setApplicationName(const QString &application),static QString applicationName(), 设置和获取应用程序的文件名;    

static void setApplicationVersion(const QString &version),static QString applicationVersion(),设置和获取应用程序的版本号;

 

QGuiApplication

QGuiApplication继承于QCoreApplication,位于gui模块中,其源码位于Src\qtbase\src\gui\kernel下。提供了额外的gui设置,比如桌面设置,风格,字体,调色板,剪切板,光标。QGuiApplication与QApplication的主要区别在于后者是基于QWidget的,如果我们开发程序,只有图形界面比如纯qml开发,并且不使用QWidget,就可以使用QGuiApplication,因为QApplication包含的东西很多,比较笨重。

int QGuiApplication::exec()
{
#ifndef QT_NO_ACCESSIBILITY
    QAccessible::setRootObject(qApp);
#endif
    return QCoreApplication::exec();
}

虽然使用QGuiApplication的时候也调用了exec(),但从源码可以看出它直接调用了QCoreApplication的exec()。

QGuiApplication还提供了会话管理,应用程序可以在用户注销时正常终止,如果无法终止则可以取消关闭进程,甚至可以保留整个应用程序的状态以备将来使用。

下面是常用的一些接口:

static void setApplicationDisplayName(const QString &name); static QString applicationDisplayName();           设置和获取应用程序的可见名称。

static QScreen *primaryScreen();                                获取应用程序的主屏幕。

static void setWindowIcon(const QIcon &icon); static QIcon windowIcon();                 设置和获取应用程序的图标

static QList<QScreen *> screens();                                返回所有的窗口列表

static QObject *focusObject();                              返回当前活动窗口中的QObject,该QObject将是绑定到焦点的事件(如键事件)的最终接收者。

static QWindow *focusWindow();                          返回接收与焦点相关的事件(如键事件)的QWindow。

static QFont font();static void setFont(const QFont &);     获取和设置字体

static QWindow *modalWindow();                     返回最近显示的模态窗口。如果没有可见的模态窗口,这个函数返回0。

关于会话管理下次赘述。

 

QApplication

QApplication继承于QGuiApplication,位于widgets模块中,源码在Src\qtbase\src\widgets\kernel下,在QGuiApplication的基础上,特化了一些功能,主要体现在QWidget及其派生类中。优点是功能模块比较齐全,缺点是很笨重。

从源码上看,QApplication直接调用了QGuiApplication::exec()创建了事件循环。

而且QApplication增加了大量QWidget相关的函数,并且可以设置QT样式表。

由于很多都是QWidget相关的,以后再详细分析QWidget。

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值