Skip to main content
Gå till innehåll

Kirigami med Python

Skapa ditt första Kirigami-program med PySide

Förutsättningar

Innan vi börjar måste vi installera Kirigami och PySide på datorn.

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

Om du använder en distribution med gamla PySide6- eller PyQt6-paket, fungerar den här handledningen med Bygga programvara med distrobox.

Projektstruktur

Först skapar vi vår projektkatalog (du kan använda kommandona nedan). Vi kallar vår kirigami_python/.

kirigami_python/
├── README.md
├── LICENSE.txt
├── MANIFEST.in                        # För att lägga till våra QML-filer
├── pyproject.toml                     # Huvudfilen för att hantera projektet
├── org.kde.kirigami_python.desktop
└── src/
    ├── __init__.py                    # För att importera katalogen src/ som ett paket

    ├── __main__.py                    # För att signalera app som startpunkten

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

Paketnamnet blir kirigami_python, det "körbara" (terminalskriptet) kallas kirigami_hello, och startpunkten blir app.

För ett mer omfattande projekt som går in mer i detalj på filstrukturen, se Fullständigt projekt i Python + Kirigami.

pyproject.toml

Moderna Python-program behöver bara en enda TOML-fil för att specificera all metadata, paketinformation och beroenden från och med PEP 621. Följande fungerar som en bra start för ett program och kan utökas senare.

Det mesta av innehållet i filen är fördefinierade, och en mer komplett version av den kan ses i Python med Kirigami: Allmän struktur.

 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"]

Observera de markerade linjerna. Som nämnts under Projektstruktur, är namnet på paketet kirigami_python, namnet på den körbara filen kirigami_hello, och namnet på startpunkten är app. I synnerhet bör följande observeras:

  • Projektskriptet består av ett startpunktsskript som genereras av setuptools för programmet att köra, i det här fallet kirigami_hello.
  • Det genererade projektskriptet kirigami_hello kör funktionen main() i skriptet app.py i paketet kirigami_python.
  • Standardvärdet på package-dir för Python-projekt är vanligtvis rotkatalogen. I det här fallet överskrids det av underkatalogen src/ så det fungerar som om den är paketets rotkatalog.
  • package-dir är anledningen till att det genererade projektskriptet använder kirigami_python → app istället för kirigami_python → src → app.
  • package-dir är också anledningen till att anropet importlib.resources.files() i app.py använder kirigami_python → qml → Main.qml istället för kirigami_python → src → qml → Main.qml.

Se Köra direkt, som en modul och som ett terminalskript för detaljerad information.

org.kde.kirigami_python.desktop

Det primära syftet med Desktop Entry-filer är att visa programmet i programstart på Linux. En annan anledning att ha dem är att ha fönsterikoner på Wayland, eftersom de måste tala om för sammansättningen att "det här fönstret hör ihop med den här ikonen".

Det måste följa ett omvänt domännamnsschema följt av tillägget .desktop såsom 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

Filen är helt enkelt en deklaration av ytterligare källkodsfiler som ska finnas i paketet när programmet körs. Python inkluderar normalt inte QML-filer i paket, och de måste vara tillgängliga för att programmet ska kunna köras.

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()

Eftersom det är ett grafiskt användargränssnittsprogram vill vi att huvudfunktionen endast ska köras när skriptet körs, inte när det importeras, så vi behöver villkoret if __name__ == "__main__" i slutet av filen. Se Köra direkt, som en modul och som ett terminalskript för detaljerad information.

Vi skapar en QGuiApplication och initierar QML-gränssnittet, och programmet fortsätter köra till det stängs med QGuiApplication.exec(). Sedan tar importlib.resources.files() sökvägen till en fil som finns i paketet, nämligen vår Main.qml. Med den sökvägen läser vi in ​​QML-filen i QML-gränssnittet som den huvudsakliga startpunkten för programgränssnittet.

src/__init__.py

Skapa en tom fil, kirigami_python/src/__init__.py. Filen behöver bara finnas för att importera en katalog som ett paket.

touch __init__.py

src/__main__.py

Skapa kirigami_python/src/__main__.py med följande innehåll:

1
2
3
from . import app

app.main()

Det lägger helt enkelt till innehållet i den aktuella katalogen (src/) och importerar den som en modul med namnet app och kör sedan omedelbart programmets funktion main().

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!"
        }
    }
}

Här är stället där vi hanterar vårt förgrundsprogram.

Om du kan lite Javascript ser mycket av QML bekant ut (även om det har sina egenheter). Qt:s dokumentation har en omfattande mängd material om språket om du känner för att prova något på egen hand. Genom alla de här handledningarna kommer vi att fokusera mycket av vår uppmärksamhet på vår QML-kod, där vi kan använda Kirigami för att få ut så mycket som möjligt av den.

Låt oss för tillfället fokusera på Main.qml. Först importerar vi ett antal viktiga moduler:

  • QtQuick, standardbiblioteket som används i QML-program.
  • QtQuick Controls, som tillhandahåller ett antal standardkontroller som vi kan använda för att göra vårt program interaktivt.
  • QtQuick Layouts, som tillhandahåller verktyg för att placera komponenter inom programmets fönster.
  • Kirigami, som tillhandahåller ett antal komponenter lämpade för att skapa program som fungerar över apparater av olika form och storlek.

Sedan kommer vi till vårt baselement, Kirigami.ApplicationWindow som tillhandahåller några grundfunktioner nödvändiga för alla Kirigami-program. Det är fönstret som kommer att innehålla alla våra sidor, huvuddelen av vårt användargränssnitt.

Vi ställer sedan in fönstrets egenskap id till 'root'. Identifierare är användbara eftersom de låter oss referera till en komponent unikt, även om vi har flera av samma typ.

Vi ställer också in fönstrets egenskap title till "Hello World".

Därefter anger vi första sidan i vår sidstapel. Del flesta Kirigami-program är organiserade som en stapel av sidor, där varje sida innehåller relaterade komponenter anpassade för en viss uppgift. För närvarande låter vi det vara enkelt, och håller oss till en enda sida. pageStack är en sidstapel som initialt är tom som Kirigami.ApplicationWindow tillhandahåller, och med pageStack.initialPage: Kirigami.Page {...} ställer vi in den första sidan som presenteras när programmet laddas i en Kirigami.Page. Sidan står för allt vårt innehåll.

Slutligen inkluderar vi en Controls.Label på vår sida, som låter oss placera text på den. Vi använder anchors.centerIn: parent för att centrera vår beteckning horisontellt och vertikalt inom vårt överliggande element. I det här fallet är det överliggande elementet för Controls.Label vår Kirigami.Page. Det sista vi behöver göra är att ange texten: text: "Hello World!".

Köra programmet

Du kan köra terminalskriptet kirigami_hello utan att behöva installera det först:

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

Väljaren --system-site-packages behövs för att Python ska få tillgång till Python-paketen från distributionen. Det krävs eftersom Kirigami och PySide måste ha byggts mot samma Qt-version för att fungera, vilket är fallet när båda kommer från distributionen.

Väljaren --spec bestämmer sökvägen till källkoden eller paketet wheel som har programmet, och kirigami_hello är det körbara skriptet som ska köras.

För att bygga och installera Python-paketet, kör:

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

Paketet installeras i ~/.local/share/pipx/venvs/kirigami-python, och ett körbart skript installeras i ~/.local/bin/kirigami_hello.

Därefter kan programmet startas genom att köra:

kirigami_hello

För att köra den nya QML-applikationen i mobilläge kan man använda QT_QUICK_CONTROLS_MOBILE=1:

QT_QUICK_CONTROLS_MOBILE=1 kirigami_hello

Se där! Nu dyker ditt allra första Kirigami-program upp framför dina ögon.

Skärmbild av det genererade Kirigami-programmet