Verwendung von Shiboken2 zum Erstellen von Python-Bindungen für eine Qt-Bibliothek

Inhalt

Qt für PythonMit der Veröffentlichung von Qt 5.12, Qt für Python wird offiziell unterstützt und kann dazu verwendet werden, vollwertige Qt-Anwendungen mit Python als Hauptprogrammiersprache zu schreiben (https://blog.qt.io/blog/2018/12/18/qt-python-5-12-released/).

Dies hat uns veranlasst, auch die Bindungen genauer zu betrachten (das Python-Modul heißt PySide2) und auch die zugrundeliegende Technologie, nämlich der Bindungsgenerator namens Shiboken2.

Dieser Beitrag zeigt Ihnen, wie Sie einen Satz von Python-Bindungen für eine kleine Qt-Bibliothek von Grund auf neu erstellen können.

PySide2
Die Qt-Bindungen selbst sind einfach zu installieren und zu verwenden.

Wenn Sie einen Python-Interpreter haben und die
pip Paketmanager auf Ihrem System eingerichtet haben, egal ob es sich um Windows oder Linux handelt, können Sie das Modul über pip installieren PySide2 und sind bereit zu gehen.

Shiboken2

Es ist zwar schön, das Qt-Framework von Python zu verwenden, aber noch besser ist es, wenn man schnell Python-Bindings für die eigenen Qt-Bibliotheken erstellen und deren API aus Python mit relativ wenig Aufwand nutzen kann.

Einrichtung

Alle Beispiele in diesem Artikel wurden unter Ubuntu 18.04 ausgeführt, die Einrichtungsschritte für andere Plattformen können variieren.

Da die neueste Dokumentation empfiehlt, Shiboken2 aus den Quellen zu bauen, um eigene Bindungen zu erstellen, werden wir das jetzt tun.

Qt 5.12 installieren

Dieser Beitrag setzt voraus, dass Sie eine Qt 5.12-Installation bereit haben unter $HOME/Qt/5.12.0/gcc_64/, das der Standardspeicherort ist, wenn Sie das Online-Installationsprogramm von qt.io.

Wenn Sie Qt von einem anderen Ort aus verwenden, passen Sie die Pfade entsprechend an.

Installieren Sie alle erforderlichen Tools und Bibliotheken

Die folgende apt Befehlszeile funktioniert für Ubuntu 18.04 und sollte ein guter Ausgangspunkt für andere Distributionen sein.

sudo apt update sudo apt install llvm-6.0 virtualenvwrapper python3 python3-dev cmake build-essential git clang-6.0 libclang-6.0-dev libxslt-dev mesa-common-dev libgl1-mesa-glx libglib2.0-0 wget # Wir benötigen CMake >= 3.12 aufgrund der verbesserten Python-Unterstützung wget https://github.com/Kitware/CMake/releases/download/v3.13.2/cmake-3.13.2-Linux-x86_64.tar.gz tar xvf cmake-3.13.2-Linux-x86_64.tar.gz export PATH=$PWD/cmake-3.13.2-Linux-x86_64/bin/:$PATH

Holen Sie sich den Sourcecode

Der schnellste Weg, an den PySide2- und Shiboken2-Quellcode zu gelangen, ist das Klonen des Git-Repositoriums.

git-Klon git://code.qt.io/pyside/pyside-setup.git cd pyside-setup git checkout 5.12.0 git-Update des Untermoduls --init

Eine Python virtualenv aufstellen

Wir raten Ihnen, in virtuellen Python-Umgebungen zu arbeiten, da dies Ihre Systeminstallation sauber hält und Sie sollten in der Lage sein, alles andere in diesem Beitrag zu tun, ohne Root-Rechte zu benötigen.

Quelle /etc/bash_completion.d/virtualenvwrapper mkvirtualenv -p `which python3` pyside2build

Dadurch wird eine virtuelle Python3-Umgebung in Ihrem Home-Verzeichnis eingerichtet (~/.local/share/virtualenvs/pyside2buildIhre Shell sollte ein Präfix haben, das dies anzeigt. Um die Virtualenv in Zukunft zu aktivieren, verwenden Sie workon pyside2build.

Einrichten der Umgebung

Der API-Extraktor von Shiboken2 erfordert eine Clang/LVM-Version, die neuer ist als die Standardversion in Ubuntu 18.04, und wir müssen dem Buildsystem mitteilen, wo es zu finden ist.

export LLVM_INSTALL_DIR=`llvm-config-6.0 --prefix` # Export des Qt-Bibliothekspfades, so dass die korrekten icu-Bibliotheken gefunden werden export LD_LIBRARY_PATH=$HOME/Qt/5.12.0/gcc_64/lib/ # Korrektur der Qt-Binärdateien im PATH export PATH=$HOME/Qt/5.12.0/gcc_64/bin/:$PATH

Bauen Sie

Jetzt, wo wir alles vorbereitet haben, ist der eigentliche Aufbau einfach.

# Wechseln Sie in Ihren Klon von pyside-setup.git cd pyside-setup # Passen Sie den Job-Parameter für die Anzahl der Kerne auf Ihrem System an python setup.py install --qmake=$HOME/Qt/5.12.0/gcc_64/bin/qmake --jobs=8

Nachdem der Bau abgeschlossen ist, was einige Zeit dauern kann, sollten Sie eine vollständig funktionierende und korrekt verknüpfte PySide2- und Shiboken2-Installation in Ihrer Virtualenv haben.

Versuchen Sie es, indem Sie das Befehlszeilen-Tool shiboken2 ausführen:

(pyside2build) swid@spica:~/src/pyside-setup (5.12)$ shiboken2 shiboken: Benötigte Argument-Header-Datei fehlt.command line:

Wenn Sie eine ähnliche Ausgabe sehen, sind Sie bereit.

Eine Bibliothek einwickeln

Anmerkung: Alle in diesem Abschnitt erwähnten Dateien können als Tarball heruntergeladen werden.

Der Shiboken2-Beitrag auf qt.io stellt den Prozess recht gut vor, so dass Sie dort auch einen Blick darauf werfen können, um den Prozess besser zu verstehen: https://blog.qt.io/blog/2018/05/31/write-python-bindings/

Shiboken2-Eingabe

Shiboken erfordert hauptsächlich drei Dinge, um zu funktionieren

  1. Die Bibliothek zur Erzeugung von Bindungen für
  2. Ein 'EinstiegspunktHeader-Datei, die alle anderen Header von Klassen enthält, für die Bindungen generiert werden
  3. Eine XML-Datei zur Typbeschreibung, die (mindestens) angibt, welche Typen umgebrochen werden sollen

Beachten Sie, dass die Typsystem-Beschreibung viel mehr tun kann, als zu beschreiben, welche Typen mit welcher Semantik zu belichten sind: https://doc.qt.io/qtforpython/shiboken2/contents.html

Die Bibliothek

Unsere triviale Bibliothek enthält nur ein einziges QObjekt mit Signalen, Slots und einer Q_ENUM, die in der API verwendet wird.

qobjectwithenum.h

#pragma einmal #include class QObjectWithEnum : public QObject { Q_OBJECT public: enum class MyEnum { Some, Values, For, The, Enum, }; Q_ENUM(MyEnum) explicit QObjectWithEnum(QObject *parent = nullptr); QString nonSlotFunction(const MyEnum value) const; signals: void someSignal(QString stringArg); public slots: void aSlot(); };

qobjectwithenum.cpp

#include "qobjectwithenum.h" #include #include #include QObjectWithEnum::QObjectWithEnum(QObject *parent) : QObject(parent) { } QString QObjectWithEnum::nonSlotFunction(const QObjectWithEnum::MyEnum value) const { const auto ret = metaObject()->enumerator(0).valueToKey(int(value)); qDebug() <<< __FUNCTION__ << "return:" <<< ret; return ret; } void QObjectWithEnum::aSlot() { qDebug() <<< __FUNCTION__ << "slot called"; emit someSignal("from aSlot"); }

Einzelheiten zur Implementierung finden Sie im beigefügten Projekt.

Der Leimkopf

Unser Glue-Header zieht die erforderlichen Bibliotheksheader ein, was in unserem Fall ziemlich einfach ist, und richtet auch eine Definition ein, die für die Generierung von Code für die Qt-Spezialitäten erforderlich ist.

bindings.h:

#definieren Sie QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a)))) #include "qobjectwithenum.h".

Die Typsystem-Beschreibung

In unserem Fall ist das auch ziemlich einfach:

bindungen.xml:

Wie ich bereits geschrieben habe, ist die Typsystem-Beschreibung ein mächtiges Werkzeug, das jedoch nicht in den Rahmen dieses speziellen Beitrags fällt.

Aufbau der Bindungen

Anmerkung: Aufgrund der stark verbesserten Python-Integration wird hier CMake >= 3.12 benötigt.

Um den Aufbau und die Verbindung aller Teile zu vereinfachen, passen wir eine CMakeLists.txt Datei aus dem Beispiel der Beispielbindung.

Das Beispiel CMakeLists.txt installiert die resultierende Bibliothek in den Quellordner und fügt alle relevanten Pfade als RPATHS für die gebauten Bibliotheken hinzu, was die lokale Nutzung bequem macht.

Dies ist nicht das Richtige für Produktionsprojekte, wenden Sie sich an Ihren lokalen Systemintegrator :-).

CMakeLists.txt

Die CMake-Build-Datei wurde von der offiziellen Musterbindung angepasst. Der Inhalt ist für diesen Artikel nicht relevant und befindet sich im herunterladbaren Zip.

Erstellen und installieren Sie einen Schatten

mkdir build cd build cmake .. make install

Verwendung des Moduls

Sobald die Bindungen generiert und gebaut sind, können wir nun ein Python-Skript schreiben, das das Bindungsmodul verwendet.

aus Shiboken2QtBeispielimport * a = QObjectWithEnum() a.someSignal.connect(lambda x: print("Signal ausgegeben: %s" % x)) a.aSlot() print("int(QObjectWithEnum.MyEnum.Values) =", int(QObjectWithEnum.MyEnum.Values)) a.nonSlotFunktion(QObjectWithEnum.MyEnum.Some)

Der einfachste Weg, die gewickelte Bibliothek zu verwenden, ist die Aktivierung der virtuellen Umgebung, die die korrekte PySide2-Version enthält, und deren Ausführung.

swid@spica:~/pyside-example/$ workon pyside2build (pyside2build) swid@spica:~/pyside-example/$ python main.py aSlot slot called Signal emitted: from aSlot int(QObjectWithEnum.MyEnum.Values) = 1 nonSlotFunction returning: Some

Das war's. Null-zu-Qt-Bibliotheksbindung in einem Blog-Beitrag.

basysKom bietet Beratungs-, Trainings- und Entwicklungsdienstleistungen für Qt an. Wir haben vor kurzem ein Qt für Python Modul zu unserem Training hinzugefügt. Wenn Sie Interesse haben, nehmen Sie bitte Kontakt mit info@basyskom.com auf.

2 Antworten

  1. Hallo, ich kann Ihr Beispiel nicht unter Windows 10 64bit bauen. Meine Toolkits sind: MSVC 2017, Qt 5.12.3 msvc 2017 64bit, Python 2.7.3 64bit. Der Fehler ist: fataler Fehler LNK1107: Datei ungültig: kann nicht bei 0x320 lesen
    Könnten Sie mir irgendwelche Hinweise geben?

    • Hallo,

      der Fehler, den Sie gepostet haben, ist leider nicht genug Information und ich habe im Moment kein ähnliches Setup zur Verfügung, um das Problem zu reproduzieren. Können Sie die gesamte Build-Ausgabe irgendwo einfügen?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Sumedha Widyadharma

Sumedha Widyadharma

Sumedha Widyadharma ist leitender Softwareentwickler und Berater für die basysKom GmbH und erstellt Softwarelösungen für und mit Kunden, in der Regel auf Basis von Qt. 2011 kam er als Systemintegrator zu basysKom, um Kundenlösungen auf ihren Embedded Linux-Plattformen zum Leben zu erwecken. Diese Wurzeln sind immer noch sichtbar als ein besonderes Interesse an Softwareentwicklungspraktiken, die helfen, die Entwicklungsfreundlichkeit und Produktqualität zu erhöhen, wie z.B. automatisiertes Testen, kontinuierliche Integration/Einsatz und Entwicklungswerkzeuge.
Aktie auf facebook
Aktie auf twitter
Aktie auf linkedin
Aktie auf reddit
Aktie auf xing
Aktie auf email
Aktie auf stumbleupon
Aktie auf whatsapp
Aktie auf pocket