1 parent
1943996608
commit
f10b654953
34 files changed
+2099
-4576
No files matched your search
+28
-89
@@ -1,96 +1,35 @@
|
||||
# main.cpp — точка входа
|
||||
# main.cpp
|
||||
|
||||
## Обзор
|
||||
Точка входа. Объектов предметной области здесь нет: `LauncherBackend` создаёт сам
|
||||
[Main.qml](../qml/Main.md), а `main()` только готовит приложение и загружает QML.
|
||||
|
||||
`Minecraft_launcher` — десктопный лаунчер Minecraft на Qt 6 Quick. Интерфейс написан на QML,
|
||||
вся работа — авторизация, скачивание версий, установка модлоадеров и Java, запуск игры — лежит в
|
||||
C++-классе [LauncherBackend](LauncherBackend.md) и его сервисах.
|
||||
## По порядку
|
||||
|
||||
`main.cpp` — стартовая последовательность приложения: здесь при необходимости инициализируется
|
||||
Qt WebEngine, создаётся объект приложения, читается каталог переводов, выбирается стиль
|
||||
Qt Quick Controls, загружается QML-модуль и запускается цикл событий. Файл намеренно короткий:
|
||||
ни одного объекта предметной области он не создаёт — всё, что нужно, QML заводит сам.
|
||||
1. **WebEngine.** Если лаунчер собран с Qt WebEngine (`LAUNCHER_HAS_WEBENGINE`),
|
||||
`QtWebEngineQuick::initialize()` вызывается до создания `QGuiApplication`. После создания
|
||||
приложения общий контекст OpenGL уже не выставить.
|
||||
2. **`QGuiApplication`**, а не `QApplication`: виджетов в проекте нет.
|
||||
3. **Имя и версия.** `applicationName` = `BiLauncher`, `applicationVersion` = `LAUNCHER_VERSION`
|
||||
(берётся из `project(... VERSION)` в CMake), организация `GaleonDev`, домен `galeonworx.com`. На
|
||||
пути к данным лаунчера это не влияет, см. [launcherpaths.h](launcherpaths.md).
|
||||
4. **Иконка окна.** На Windows и Linux в `QIcon` складываются все PNG из ресурса `:/icons/`
|
||||
(16–512 и `@2x`). На macOS этот шаг пропущен: там иконку берут из `icon.icns` внутри бандла.
|
||||
5. **`setDesktopFileName("bilauncher")`.** По этому имени окружения рабочего стола в Linux
|
||||
связывают окно с `bilauncher.desktop` и показывают правильную иконку в панели.
|
||||
6. **Тексты.** `Localization::instance().load()` читает `i18n/translations.json` и язык из
|
||||
`settings.json`. Это нужно сделать до создания движка: язык должен быть известен до первой
|
||||
привязки. Если каталог не загрузился, `main()` возвращает `-1` (см.
|
||||
[Localization](Localization.md)).
|
||||
7. **Стиль `Basic`.** Окна оформлены вручную, а нативный стиль Windows игнорирует свои
|
||||
`contentItem` и `background` и засыпает журнал предупреждениями.
|
||||
8. **Движок.** `QQmlApplicationEngine`. Если корневой объект не создался, приложение
|
||||
завершается с `-1`. Соединение отложенное (`Qt::QueuedConnection`), чтобы выход произошёл уже в
|
||||
цикле событий, а не посреди загрузки.
|
||||
9. `engine.loadFromModule("BiLauncher", "Main")` — загрузка по URI модуля и имени типа.
|
||||
10. `app.exec()`.
|
||||
|
||||
## Настройка приложения Qt
|
||||
|
||||
Создаётся `QGuiApplication` — не `QApplication`: интерфейс целиком на Qt Quick, виджеты не
|
||||
используются, и модуль Qt Widgets в проект не подключён.
|
||||
|
||||
До создания приложения, при сборке с Qt WebEngine, вызывается `QtWebEngineQuick::initialize()`.
|
||||
Порядок здесь принципиален: инициализация выставляет общий контекст OpenGL, а после создания
|
||||
объекта приложения это уже не действует. Вызов обёрнут в условную компиляцию по макросу
|
||||
`LAUNCHER_HAS_WEBENGINE`.
|
||||
|
||||
## Каталог переводов
|
||||
|
||||
Сразу после создания приложения вызывается `Localization::instance().load()` — он читает
|
||||
`i18n/translations.json` из ресурсов и определяет язык интерфейса. Порядок важен: язык нужно
|
||||
знать до того, как QML вычислит первую привязку, а [LauncherBackend](LauncherBackend.md),
|
||||
который ведёт `settings.json`, появляется только вместе с движком — поэтому ключ `language`
|
||||
[Localization](Localization.md) читает из файла сам.
|
||||
|
||||
Неудача — не повод продолжать: каталог вкомпилирован в бинарник, значит его отсутствие или
|
||||
поломка означают ошибку сборки. `main()` пишет причину и возвращает `-1`.
|
||||
|
||||
## Стиль Qt Quick Controls
|
||||
|
||||
Стиль Qt Quick Controls принудительно выставляется в `Basic`
|
||||
вызовом `QQuickStyle::setStyle()`. Причина в оформлении: всё окно лаунчера стилизовано вручную, а
|
||||
нативный стиль Windows игнорирует пользовательские `contentItem` и `background` и сыплет
|
||||
предупреждениями.
|
||||
|
||||
## Обработка командной строки
|
||||
|
||||
Аргументы командной строки не разбираются: `argc` и `argv` передаются в конструктор
|
||||
`QGuiApplication` и дальше не используются. Ни `QCommandLineParser`, ни собственного разбора в
|
||||
файле нет.
|
||||
|
||||
## Создание объектов верхнего уровня
|
||||
|
||||
В `main()` создаётся ровно два объекта.
|
||||
|
||||
| Объект | Тип | Роль |
|
||||
|--------|-----|------|
|
||||
| `app` | `QGuiApplication` | объект приложения и цикл событий |
|
||||
| `engine` | `QQmlApplicationEngine` | загружает и исполняет QML-модуль лаунчера |
|
||||
|
||||
Экземпляр `LauncherBackend` здесь не создаётся: тип зарегистрирован через `QML_ELEMENT`, и главное
|
||||
окно объявляет его само декларативно. Поэтому в `main.cpp` нет ни одного `#include` классов
|
||||
предметной области.
|
||||
|
||||
## Связывание и подключения
|
||||
|
||||
Единственное подключение — обработка неудачи создания корневого объекта: сигнал
|
||||
`QQmlApplicationEngine::objectCreationFailed` замыкается на лямбду, которая завершает приложение
|
||||
с кодом `-1`. Соединение создаётся с типом `Qt::QueuedConnection` и с объектом `app` в роли
|
||||
контекста, чтобы выход из приложения происходил уже внутри цикла событий, а не в разгар загрузки
|
||||
QML.
|
||||
|
||||
Контекстные свойства не задаются, начальные свойства корневому объекту не передаются: связь между
|
||||
QML и C++ идёт исключительно через зарегистрированный тип.
|
||||
|
||||
## Цикл событий
|
||||
|
||||
QML загружается вызовом `engine.loadFromModule("Minecraft_launcher", "Main")` — по URI модуля и
|
||||
имени типа, а не по пути к файлу. Модуль объявлен в `CMakeLists.txt` через `qt_add_qml_module`, а
|
||||
`Main` — это [Main.qml](../qml/Main.md), корневой элемент которого `Window` с `visible: true`,
|
||||
поэтому окно показывается само.
|
||||
|
||||
Цикл событий запускается `app.exec()`, его результат возвращается из `main()` как код завершения
|
||||
процесса.
|
||||
|
||||
## Зависимости
|
||||
|
||||
| Заголовок | Что даёт |
|
||||
|-----------|----------|
|
||||
| `QGuiApplication` | объект приложения и цикл событий для приложения без виджетов |
|
||||
| `QQmlApplicationEngine` | загрузка QML-модуля и создание корневого объекта |
|
||||
| `QQuickStyle` | выбор стиля Qt Quick Controls до загрузки QML |
|
||||
| `QtWebEngineQuick` | инициализация WebEngine; подключается только при сборке с Qt WebEngine |
|
||||
|
||||
Модули сборки: `Qt6::Quick`, `Qt6::QuickControls2`, `Qt6::Core`, `Qt6::CorePrivate`, `Qt6::Gui`,
|
||||
`Qt6::Network` и опционально `Qt6::WebEngineQuick`. Макрос `LAUNCHER_HAS_WEBENGINE` определяется в
|
||||
`CMakeLists.txt` только тогда, когда `find_package` нашёл `Qt6WebEngineQuick`.
|
||||
Аргументы командной строки не разбираются. Контекстных свойств нет: QML общается с C++ только
|
||||
через зарегистрированные типы `LauncherBackend` и `Loc`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in new issue
Block a user