Skip to main content
Перейти до вмісту

Робота у Windows

Приготування вашої програми на C++ до Windows

Вступ

У Qt передбачено чудову підтримку Windows, тому програми, що використовують Qt та модулі [extra-cmake-modules] (https://api.kde.org/ecm/) KDE, не потребуватимуть значних модифікацій для належної роботи у Windows.

Потрібно три речі:

План Craft потрібен для пов'язування усіх залежностей з програмою для створення виконуваного файла.

Директива препроцесора #ifdef Q_OS_WIN може бути використана для написання коду, який застосовуватиметься лише тоді, коли програма зібрана на Windows. Це потрібно принаймні один раз для примусового застосування стилю Breeze до програми, щоб вона добре виглядала на Windows, але залежно від програми може знадобитися більше разів.

Дописування до пакета необхідних піктограм для роботи програми у Windows є найскладнішим кроком, але як модулі extra-cmake (ECM) KDE, так і Qt надають засоби для спрощення цієї роботи.

План Craft

Для початку вам слід спочатку ознайомитися з інструкцією щодо збирання програмного забезпечення KDE для Windows за допомогою Craft, щоб отримати функціональний план Craft і мати змогу принаймні зібрати свою програму для Windows.

Після того, як ви зможете спробувати зібрати проект, ви отримаєте повідомлення про помилки компіляції та виконання, які допоможуть вам виправити будь-які проблеми сумісності з Windows.

Стиль Breeze

Підручник з Kirigami вже здебільшого сумісний з Windows, але кроки, необхідні для досягнення цієї мети, мають бути чітко описані.

Дві зміни, які слід зробити, щоб забезпечити використання стилю Breeze, це встановити QStyle у значення breeze та встановити стиль швидкого керування Qt на org.kde.desktop.

A QStyle is what controls the majority of the appearance of a QtWidgets application. This is needed in our QtQuick application because we initialize the application with QApplication (traditionally used with QtWidgets).

A Qt Quick Controls style on the other hand controls the majority of the appearance of a QtQuick application. This affects how QML controls will look like. KDE's org.kde.desktop style (otherwise known as qqc2-desktop-style) is special and attempts to remove duplication by deriving styling elements from the application's QStyle (hence why a QApplication is used). This way, QtWidgets and QtQuick applications can mostly look the same and reuse style components.

QtQuick / Kirigami applications need to set both in C++ code. To set the QStyle, it needs to be added in two places.

In Craft:

def setDependencies(self):
    self.runtimeDependencies["kde/plasma/breeze"] = None

And in C++:

QApplication::setStyle("breeze");

This is what is used in the Kirigami tutorial. You may otherwise load the Breeze style only on Windows where this is most relevant using an ifdef:

#ifdef Q_OS_WIN
    QApplication::setStyle("breeze");
#endif

The Qt Quick Controls style needs to be added in three places.

In Craft:

def setDependencies(self):
    self.runtimeDependencies["kde/frameworks/tier3/qqc2-desktop-style"] = None

In C++, where it needs to be conditional:

if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE"))
{
    QQuickStyle::setStyle("org.kde.desktop");
}

And optionally in CMake, in one of two ways:

find_package(KF6 REQUIRED COMPONENTS QQC2DesktopStyle)
# or
ecm_find_qmlmodule(org.kde.desktop REQUIRED)

Since it is a runtime dependency, it is not required to be set in CMake which is used at compile time. However, this can signal to yourself and to others whether the environment is correct and will be able to run the resulting application, allowing you to find missing packages or misconfigurations more easily.

The command find_package() specifically searches for the CMake configuration files for qqc2-desktop-style, whereas ecm_find_qmlmodule() is less strict and only searches for the QML module. The latter requires that you include ECMFindQmlModule:

include(ECMFindQmlModule)

Shipping icons

The first thing that is needed to make the application use Breeze icons is to include KIconThemes in your project.

After this, some CMake commands are needed to bundle your application icon with the app.

KIconThemes

This can be done with the following three steps:

  • Adding it as a dependency in Craft:
def setDependencies(self):
    self.runtimeDependencies["kde/frameworks/tier3/kiconthemes"] = None
  • Adding it as a dependency in CMake:
find_package(KF6 REQUIRED COMPONENTS IconThemes)

# ...

target_link_libraries(myapp
    PRIVATE
    # ...
    KF6::IconThemes
)
  • Using it in C++ code, in the main.cpp file:
#include <KIconTheme>

// ...
int main(int argc, char* argv[])
{
    KIconTheme::initTheme();
    QApplication app(argc, argv);
    // ...
}

Note that although the project name and CMake call uses plural (KIconThemes, KF6IconThemes), the C++ call uses singular (KIconTheme).

KIconThemes needs to be initialized before the application.

Піктограма програми

If your application has an icon, it needs to be added to your project both as a QML resource and as a part of icon installation.

Ordinarily on Linux the application icon can simply be installed to the correct directory, and the icon will be fetched by the application when needed. Usually the application icon consists of a primary SVG icon, paired with multiple PNG icon sizes.

Installing the SVG icon is done like this in CMake:

install(FILES ${PROJECT_SOURCE_DIR}/icons/org.kde.myapp.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/hicolor/scalable/apps)

And installing the PNG icons is done like this:

ecm_install_icons(ICONS
    16-apps-myapp.png
    24-apps-myapp.png
    32-apps-myapp.png
    48-apps-myapp.png
    64-apps-myapp.png
    128-apps-myapp.png
    256-apps-myapp.png
    512-apps-myapp.png    
    DESTINATION share/icons)

When the application icon is installed on Linux, a PNG icon such as 48-apps-myapp.png goes to ${INSTALL_PREFIX}/share/icons/hicolor/48x48/apps/myapp.png, and an SVG icon goes to ${INSTALL_PREFIX}/share/icons/hicolor/scalable/apps/org.kde.myapp.svg, where ${INSTALL_PREFIX} usually stands for /usr, /usr/local or ~/.local. Note how in the PNGs' case the icon name translates into the path it will have in the filesystem.

Дізнатися більше про встановлення файлів можна з підручника Збирання програмного забезпечення KDE вручну: крок встановлення.

Once the icon is installed in this way, in QML code, it can be called simply with myapp or org.kde.myapp, as would be called from QIcon::fromTheme(). This can be used with any QML control that has an icon.name property.

Windows has no such standard directory, and installing the icon has no effect; it has to be bundled with the application. To do so, the PNG can be sent to its own installation directory using ecm_add_app_icon() and a PNG or SVG file can be embedded into the app as a Qt resource file in ecm_add_qml_module() or ecm_target_qml_sources().

Піктограма програми PNG встановлюється за допомогою такого коду:

ecm_add_app_icon(myapp ICONS ${PROJECT_SOURCE_DIR}/icons/256-apps-myapp.png)

And the main application icon is bundled as a Qt resource with:

ecm_add_qml_module(myapp URI org.kde.myapp)
ecm_target_qml_sources(myapp SOURCES Main.qml RESOURCES ../icons/org.kde.myapp.svg)

This will make the application icon available as a Qt resource under qrc:/qt/qml/org/kde/myapp/org.kde.myapp.svg. This can be used with any QML control that has an icon.source property.

The RESOURCES path depends on the place where the icons are located. Traditionally, an icons/ folder is created at the root of the project for storing all icons, as they don't really count as source files.

After the icons are installed (for Linux) and bundled (for Windows and Android), you can set it in code. In QML code, for compatibility with both Windows and Android, you should use the bundled icon; in C++ code, notably when setting the window icon, you can use the theme icon by default and the bundled icon as a fallback with QIcon::fromTheme() in the call to QGuiApplication::setWindowIcon():

QGuiApplication::setWindowIcon(QIcon::fromTheme("org.kde.myapp", QIcon(":/qt/qml/org/kde/myapp/org.kde.myapp.svg")));

Піктограми Kirigami

While Windows does not have a standard directory where to install icons from an icon theme, it is possible to bundle the necessary Breeze icons together with your Windows application.

This is performed by Craft automatically when KIconThemes is correctly set up for the project and Breeze icons are included as a dependency in your project.

To set up KIconThemes, see the above section KIconThemes.

To add Breeze icons as a dependency for your project, add this to your Craft blueprint:

def setDependencies(self):
    # ...
    self.runtimeDependencies["kde/frameworks/tier1/breeze-icons"] = None

This way, you won't need to manually bundle any Breeze icons into your application as a resource: you can just use a QIcon::fromTheme() name, such as kde or application-exit-symbolic.

Збирання

To build your application on Windows, follow Building KDE software on Windows with Craft: Building your own projects on Windows.

Збирання у CI

If the project has been properly configured to build on Windows and is using KDE infrastructure for its code hosting (KDE Invent), it is possible to configure Windows CI/CD jobs.

To do this, you will need to add the relevant CI templates for Windows with a .gitlab-ci.yaml file and list your dependencies in a .kde-ci.yaml file as mentioned in Continuous Integration System.

Усування проблем

If you have problems adapting your application to Windows, you can visit the following rooms on Matrix: