Skip to main content
Salta al contingut

El Kirigami amb Python

Creeu la vostra primera aplicació Kirigami amb PySide

Prerequisits

Abans de començar, haurem d'instal·lar el Kirigami i el PySide a la nostra màquina.

logo of Linux operating system ManjaroManjarologo of Linux operating system Arch LinuxArch
sudo pacman -S python-pipx python-pyqt6 pyside6 kirigami flatpak-builder qqc2-desktop-style appstream
logo of Linux operating system openSUSEOpenSUSE
sudo zypper install python3-pipx python3-qt6 python3-pyside6 kf6-kirigami-devel flatpak-builder qqc2-desktop-style AppStream-compose
logo of Linux operating system FedoraFedora
sudo dnf install pipx python3-pyqt6 python3-pyside6 kf6-kirigami-devel flatpak-builder qqc2-desktop-style appstream-compose

Si teniu en una distribució amb paquets antics de PySide6 o PyQt6, aquesta guia d'aprenentatge funciona amb Construir programari amb distrobox.

Estructura del projecte

Primer crearem la nostra carpeta de projecte (podeu utilitzar les ordres de sota). L'anomenarem kirigami_python/.

kirigami_python/
├── README.md
├── LICENSE.txt
├── MANIFEST.in                        # Per a afegir els nostres fitxers QML
├── pyproject.toml                     # El fitxer principal per a gestionar el projecte
├── org.kde.kirigami_python.desktop
└── src/
    ├── __init__.py                    # Per a importar el directori src/ com a paquet

    ├── __main__.py                    # Per a assenyalar l'aplicació com a punt d'entrada

    ├── app.py
    └── qml/
        └── Main.qml

El nom del paquet serà kirigami_python, l'«executable» (script de consola) s'anomenarà kirigami_hello i el punt d'entrada serà app.

Per a un projecte més complet que entri en més detalls sobre aquesta estructura de fitxers, vegeu Projecte complet en Python + Kirigami.

pyproject.toml

Les aplicacions Python modernes només necessiten un sol fitxer TOML per a especificar totes les metadades, la informació del paquet i les dependències a partir del PEP 621. El següent serveix com un bon iniciador per a una aplicació i es pot ampliar més tard.

La major part del contingut d'aquest fitxer és estàndard, i es pot veure una versió més completa d'ell a Python amb el Kirigami: Estructura general.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "kirigami_python"
version = "0.1"
authors = [
    {name = "Konqi", email = "konqi@example.com"}
]
classifiers = [
    "Development Status :: 5 - Production/Stable",
    "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
    "Intended Audience :: End Users/Desktop",
    "Topic :: Utilities",
    "Programming Language :: Python",
    "Operating System :: POSIX :: Linux",
]

[project.scripts]
kirigami_hello = "kirigami_python.app:main"

[tool.setuptools]
packages = ["kirigami_python"]
package-dir = {kirigami_python = "src"}
include-package-data = true

[tool.setuptools.data-files]
"share/applications" = ["org.kde.kirigami_python.desktop"]

Tingueu en compte les línies ressaltades. Com s'esmenta a estructura del projecte, el nom del paquet és kirigami_python, el nom de l'executable és kirigami_hello, i el nom del punt d'entrada és app. En particular, cal destacar el següent:

  • L'script del projecte consisteix en un script de punt d'entrada que serà generat per «setuptools» de l'aplicació a executar, en aquest cas kirigami_hello.
  • L'script de projecte generat kirigami_hello executa la funció main() a l'script app.py al paquet kirigami_python.
  • El package-dir predeterminat dels projectes Python és normalment el directori arrel. En aquest cas, això se substitueix pel subdirectori src/, de manera que actua com si fos el directori arrel del paquet.
  • El package-dir és per què l'script generat del projecte fa kirigami_python → app en lloc de kirigami_python → src → app.
  • El package-dir també és per què la crida importlib.resources.files() a app.py fa kirigami_python → qml → Main.qml en lloc de kirigami_python → src → qml → Main.qml.

Vegeu els detalls a Executar directament, com a mòdul i com a script de consola.

org.kde.kirigami_python.desktop

El propòsit principal dels fitxers Desktop Entry és mostrar la vostra aplicació al llançador d'aplicacions en el Linux. Una altra raó per a tenir-los és tenir icones de finestra al Wayland, ja que es requereixen per a dir al compositor «aquesta finestra va amb aquesta icona».

Ha de seguir un esquema de noms DNS invers seguit de l'extensió .desktop com ara org.kde.kirigami_python.desktop:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Desktop Entry]
Name=Kirigami Tutorial in Python
Name[ca]=Guia d'aprenentatge del Kirigami en Python
Name[eo]=Lernilo pri Kirigami en Python
Name[es]=Tutorial de Kirigami en Python
Name[nl]=Kirigami handleiding in Python
Name[sl]=Učbenik Kirigami v Pythonu
Name[sv]=Kirigami-handledning i Python
Name[uk]=Підручник з Kirigami для Python
Name[x-test]=xxKirigami Tutorial in Pythonxx
Exec=kirigami_hello
Icon=kde
Type=Application
Terminal=false
Categories=Utility

MANIFEST.in

Aquest fitxer és senzillament una declaració de fitxers de codi font addicionals que haurien d'estar presents en el paquet quan s'executi l'aplicació. El Python no inclou fitxers QML als paquets de manera predeterminada, i han d'estar disponibles perquè l'aplicació s'executi.

1
include src/qml/*.qml

src/app.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/env python3

import os
import sys
import signal
from importlib.resources import files

from PySide6.QtGui import QGuiApplication
from PySide6.QtCore import QUrl
from PySide6.QtQml import QQmlApplicationEngine

def main():
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    """Needed to close the app with Ctrl+C"""
    signal.signal(signal.SIGINT, signal.SIG_DFL)

    """Needed to get proper KDE style outside of Plasma"""
    if not os.environ.get("QT_QUICK_CONTROLS_STYLE"):
        os.environ["QT_QUICK_CONTROLS_STYLE"] = "org.kde.desktop"

    base_path = files('kirigami_python').joinpath('qml', 'Main.qml')
    url = QUrl(f"{base_path}")
    engine.load(url)

    app.exec()

if __name__ == "__main__":
    main()

Com que aquesta és una aplicació IGU, volem que la funció principal només s'executi quan s'executa l'script, no quan s'importa, de manera que necessitem la condició if __name__ == "__main__" al final del fitxer. Vegeu els detalls a Executar directament, com a mòdul i com a script de consola.

Creem una QGuiApplication i iniciem el motor QML, i amb QGuiApplication.exec() l'aplicació seguirà funcionant fins que es tanqui. Llavors importlib.resources.files() agafa el camí cap a un fitxer que està present en el paquet, és a dir, al nostre Main.qml. Amb aquest camí, carreguem el fitxer QML al motor QML com a punt d'entrada principal per a la interfície de l'aplicació.

src/__init__.py

Creeu un fitxer kirigami_python/src/__init__.py buit. Aquest fitxer només ha d'estar present per importar un directori com a paquet.

touch __init__.py

src/__main__.py

Creeu un kirigami_python/src/__main__.py amb el contingut següent:

1
2
3
from . import app

app.main()

Això simplement afegeix el contingut del directori actual (src/) i l'importa com un mòdul anomenat app, després immediatament executa la funció main() de l'aplicació.

src/qml/Main.qml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Includes relevant modules used by the QML
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami

// Provides basic features needed for all kirigami applications
Kirigami.ApplicationWindow {
    // Unique identifier to reference this object
    id: root

    width: 400
    height: 300

    // Window title
    title: "Hello World"

    // Set the first page that will be loaded when the app opens
    // This can also be set to an id of a Kirigami.Page
    pageStack.initialPage: Kirigami.Page {
        Controls.Label {
            // Center label horizontally and vertically within parent object
            anchors.centerIn: parent
            text: "Hello World!"
        }
    }
}

Aquí és on manejarem el frontal de la nostra aplicació.

Si coneixeu alguna cosa de JavaScript, gran part de QML us resultarà familiar (encara que té les seves pròpies peculiaritats). Si teniu ganes de provar alguna cosa pel vostre compte, la documentació de les Qt té una gran quantitat de material sobre aquest llenguatge. Al llarg d'aquestes guies d'aprenentatge, centrarem gran part de la nostra atenció en el codi en QML, on podrem emprar el Kirigami per a aprofitar-lo al màxim.

Per ara, centrem-nos en Main.qml. Primer importarem diversos mòduls importants:

  • QtQuick, la biblioteca estàndard utilitzada en les aplicacions QML.
  • QtQuick Controls, que proporciona una sèrie de controls estàndard que podem utilitzar perquè les nostres aplicacions siguin interactives.
  • QtQuick Layouts, que proporciona eines per a col·locar els components dins de la finestra de l'aplicació.
  • El Kirigami, que proporciona una sèrie de components adequats per a crear aplicacions que funcionen en dispositius de formes i mides diferents.

Després arribem al nostre element base, la Kirigami.ApplicationWindow, que proporciona algunes característiques bàsiques necessàries per a totes les aplicacions escrites amb el Kirigami. Aquesta és la finestra que contindrà cadascuna de les nostres pàgines, les seccions principals de la nostra interfície d'usuari.

Després, establim la propietat id de la finestra a "root". Els ID són útils perquè ens permeten fer referència de forma única a un component, fins i tot si en tenim diversos del mateix tipus.

També establim la propietat title de la finestra a "Hola món".

Després establirem la primera pàgina de la nostra pila de pàgines. La majoria de les aplicacions escrites amb el Kirigami estan organitzades com una pila de pàgines, cada pàgina conté els components relacionats adequats per a una tasca específica. Per ara, el mantenim senzill i ens cenyim a una sola pàgina. pageStack és una pila inicialment buida de pàgines proporcionades per Kirigami.ApplicationWindow, i amb pageStack.initialPage: Kirigami.Page{...} establim la primera pàgina presentada en carregar l'aplicació a una Kirigami.Page. Aquesta pàgina contindrà tot el nostre contingut.

Finalment, incloem en la nostra pàgina un Controls.Label que ens permetrà inserir text a la nostra pàgina. Utilitzarem anchors.centerIn: parent per a centrar la nostra etiqueta horitzontalment i verticalment dins de l'element pare. En aquest cas, el component principal de la nostra etiqueta és Kirigami.Page. L'últim que hem de fer és configurar el text: text: "Hello World!".

Executar l'aplicació

Podeu executar l'script de consola kirigami_hello sense necessitat d'instal·lar-lo abans:

pipx run --system-site-packages --spec . kirigami_hello

Es necessita l'indicador --system-site-packages per a fer que el Python tingui accés als paquets Python de la vostra distribució. Això és necessari perquè el Kirigami i el PySide han d'haver estat construïts amb la mateixa versió de les Qt per a funcionar, que és el cas quan tots dos provenen de la distribució.

L'indicador --spec determina el camí al codi font o paquet «wheel» que té el programa, i kirigami_hello és l'script executable que s'ha d'executar.

Per a construir i instal·lar el paquet Python, executeu:

pipx install --force --system-site-packages .

El paquet s'instal·larà a ~/.local/share/pipx/venvs/kirigami-python, i s'instal·larà un script executable a ~/.local/bin/kirigami_hello.

Després d'això, l'aplicació es pot llançar executant:

kirigami_hello

Per a executar la nova aplicació QML en mode de mòbil, podeu utilitzar QT_QUICK_CONTROLS_MOBILE=1:

QT_QUICK_CONTROLS_MOBILE=1 kirigami_hello

Heus aquí! Ara veureu aparèixer la vostra primera aplicació escrita amb el Kirigami.

Captura de pantalla de l'aplicació generada amb el Kirigami