Spectacle源码及分析2 —— Main.cpp解析1

这段代码展示了Spectacle截图工具的主程序流程,包括Qt应用初始化、设置翻译域、关于信息、窗口图标、单例模式实现、DBUS服务注册等。核心功能涉及QCoreApplication属性设置、QApplication构造、KLocalizedString翻译、KAboutData信息以及QDBus服务的交互。

Main.cpp位于src/目录中,完整源码如下:

/*
 *  SPDX-FileCopyrightText: 2019 David Redondo <kde@david-redondo.de>
 *  SPDX-FileCopyrightText: 2015 Boudhayan Gupta <bgupta@kde.org>
 *
 *  SPDX-License-Identifier: LGPL-2.0-or-later
 */

#include "Config.h"
#include "SpectacleCommon.h"
#include "SpectacleCore.h"
#include "SpectacleDBusAdapter.h"
#include "settings.h"

#ifdef KIMAGEANNOTATOR_CAN_LOAD_TRANSLATIONS
#include <kImageAnnotator/KImageAnnotator.h>
#endif

#include <QApplication>
#include <QCommandLineParser>
#include <QDBusConnection>
#include <QSessionManager>

#include <KAboutData>
#include <KDBusService>
#include <KLocalizedString>

int main(int argc, char **argv)
{
    // set up the application

    QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
    QApplication app(argc, argv);

    KLocalizedString::setApplicationDomain("spectacle");
    QCoreApplication::setOrganizationDomain(QStringLiteral("org.kde"));

    KAboutData aboutData(QStringLiteral("spectacle"),
                         i18n("Spectacle"),
                         QStringLiteral(SPECTACLE_VERSION),
                         i18n("KDE Screenshot Utility"),
                         KAboutLicense::GPL_V2,
                         i18n("(C) 2015 Boudhayan Gupta"));
    aboutData.addAuthor(QStringLiteral("Boudhayan Gupta"), QString(), QStringLiteral("bgupta@kde.org"));
    aboutData.addAuthor(QStringLiteral("David Redondo"), QString(), QStringLiteral("kde@david-redondo.de"));
    aboutData.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
    KAboutData::setApplicationData(aboutData);
    app.setWindowIcon(QIcon::fromTheme(QStringLiteral("spectacle")));

    SpectacleCore lCore;

    QCommandLineParser lCmdLineParser;
    aboutData.setupCommandLine(&lCmdLineParser);
    lCore.populateCommandLineParser(&lCmdLineParser);

    // first parsing for help-about
    lCmdLineParser.process(app.arguments());
    aboutData.processCommandLine(&lCmdLineParser);

    QGuiApplication::setFallbackSessionManagementEnabled(false);

    auto disableSessionManagement = [](QSessionManager &sm) {
        sm.setRestartHint(QSessionManager::RestartNever);
    };
    QObject::connect(&app, &QGuiApplication::commitDataRequest, disableSessionManagement);
    QObject::connect(&app, &QGuiApplication::saveStateRequest, disableSessionManagement);

    // and new-instance
    if (lCmdLineParser.isSet(QStringLiteral("new-instance"))) {
        lCore.init();

        QObject::connect(&lCore, &SpectacleCore::allDone, &app, &QCoreApplication::quit, Qt::QueuedConnection);

        // fire it up
        lCore.onActivateRequested(app.arguments(), QStringLiteral());

        return app.exec();
    }

    // Ensure that we only launch a new instance if we need to
    // If there is already an instance running, we will quit here
    // and activateRequested signal is triggered
    // For some reason this does not work properly if behind an if
    KDBusService service(KDBusService::Unique, &lCore);

#ifdef KIMAGEANNOTATOR_CAN_LOAD_TRANSLATIONS
    kImageAnnotator::loadTranslations();
#endif

    // Delay initialisation after we now we are in the single instance or new-instance was passed, to avoid doing it each time spectacle executable is called
    lCore.init();

    // set up the KDBusService activateRequested slot
    QObject::connect(&service, &KDBusService::activateRequested, &lCore, &SpectacleCore::onActivateRequested);
    QObject::connect(&lCore, &SpectacleCore::allDone, &app, &QCoreApplication::quit, Qt::QueuedConnection);
    QObject::connect(qApp, &QApplication::aboutToQuit, Settings::self(), &Settings::save);

    // create the dbus connections
    SpectacleDBusAdapter *lDBusAdapter = new SpectacleDBusAdapter(&lCore);
    QObject::connect(&lCore, &SpectacleCore::grabFailed, lDBusAdapter, &SpectacleDBusAdapter::ScreenshotFailed);
    QObject::connect(ExportManager::instance(), &ExportManager::imageSaved, &lCore, [&](const QUrl &savedAt) {
        lDBusAdapter->ScreenshotTaken(savedAt.toLocalFile());
    });
    QDBusConnection::sessionBus().registerObject(QStringLiteral("/"), &lCore);
    QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.Spectacle"));

    // fire it up
    lCore.onActivateRequested(app.arguments(), QStringLiteral());

    return app.exec();
}

分段解析:

(1)代码片段:

QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

 QCoreApplication::setAttribute的介绍如下(引自https://doc.qt.io/qt-6/qcoreapplication.html#setAttribute):

Qt::AA_DontCreateNativeWidgetSiblings含义如下:

Qt::AA_DontCreateNativeWidgetSiblings4Ensures that siblings of native widgets stay non-native unless specifically set by the Qt::WA_NativeWindow attribute.

Qt::AA_UseHighDpiPixmaps在QT6.0.0之前的版本中有定义。

以上代码的意思是:

不创建本地组件的兄弟组件;如果版本低于6.0.0,还要设置使用高分辨率像素图。

(2)代码片段:

QApplication app(argc, argv);

定义一个Qt应用程序对象,其构造函数接收和main函数一样的参数,是Qt图形界面程序的入口,就像main函数是普通C/C++程序的入口一样。

(3)代码片段:

KLocalizedString::setApplicationDomain("spectacle");

在编码中,需要在程序中需要被翻译前的位置,利用如下语句引入自己的翻译文件:

KLocalizedString::setApplicationDomain("yourPO");

(4) 代码片段:

QCoreApplication::setOrganizationDomain(QStringLiteral("org.kde"));

QCoreApplication::setOrganizationDomain的介绍如下(引自https://doc.qt.io/qt-6/qcoreapplication.html#organizationDomain-prop)

organizationDomain : QString

This property holds the Internet domain of the organization that wrote this application

The value is used by the QSettings class when it is constructed using the empty constructor. This saves having to repeat this information each time a QSettings object is created.

On Mac, QSettings uses organizationDomain() as the organization if it's not an empty string; otherwise it uses organizationName(). On all other platforms, QSettings uses organizationName() as the organization.

Access functions:

QStringorganizationDomain()
voidsetOrganizationDomain(const QString &orgDomain)

Notifier signal:

voidorganizationDomainChanged()

(5)代码片段:

KAboutData aboutData(QStringLiteral("spectacle"),
                         i18n("Spectacle"),
                         QStringLiteral(SPECTACLE_VERSION),
                         i18n("KDE Screenshot Utility"),
                         KAboutLicense::GPL_V2,
                         i18n("(C) 2015 Boudhayan Gupta"));
    aboutData.addAuthor(QStringLiteral("Boudhayan Gupta"), QString(), QStringLiteral("bgupta@kde.org"));
    aboutData.addAuthor(QStringLiteral("David Redondo"), QString(), QStringLiteral("kde@david-redondo.de"));
    aboutData.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
KAboutData::setApplicationData(aboutData);

参考说明(Using Actions | Developer):

We are going to install our UI .rc file under the component texteditor, so main.cpp should be changed to reflect that change in name.

// ...
    KLocalizedString::setApplicationDomain("texteditor");
    
    KAboutData aboutData(
                         // The program name used internally. (componentName)
                         QStringLiteral("texteditor"),
// ...

(6)代码片段:

app.setWindowIcon(QIcon::fromTheme(QStringLiteral("spectacle")));

设置窗口图标。

参考说明(设置窗口的图标setWindowIcon_设置窗口的标题setWindowTitle_不透明度setWindowOpacity_窗口状态setWindowState_最大化showMaximized最小化showMinimized_PyQt学习笔记(二十六)-陶小桃Blog):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值