Qt for Python: 新しいバージョン6.5がリリースされました!

 本稿は「Qt for Python: the new 6.5 version is out!」の抄訳です。

Qt 6.5に搭載された多くの新機能をご覧になったかと思いますが、今回はQt for Pythonチームが開発しているすべてについてお話したいと思います。

qtforpython_thin_banner

新しいモジュールとクラス 

今回、ユーザーからのフィードバックと Qt 6.5 の新機能により、さらにいくつかのモジュールを公開する機会を得ました。QtTextToSpeech、QtSerialBus、QtLocationをリリースしました。

また、既存モジュールのクラスの適応や改良も進めており、今のところ、QtCore.QHashSeed, QWebEngineFileSystemAccessRequest, QOpenGLContext.getProcAddressQSGeometry.vertexDataAsPoint2D, QSGGeometry.setVertexDataAsPoint2D, QAbstractTextDocumentLayout::PaintContext, QRunnable.create および QMetaMethod.fromSignal が含まれています。

さらに、Qt 3Dの共有ポインタ型の多くも含まれています: PropertyReaderInterfaceQTextureImageDataQTextureImageDataGenerator

Qt for Pythonにないモジュールは、使用例がない、あるいはQtのモジュールよりもPythonの対応モジュールがあるため、通常、除外されています。

微調整:__feature__と多重継承 

一方、よく知られている __feature__ スイッチは完全に作り直されました。一方では、切り替えを強力に最適化し、クラスの辞書を5回に1回程度しか変更しなくて済むようにしました。また、切り替えの基準も強化され、式のコンテキスト切り替えが多い複雑なケースに対応できるようになりました。

同時に、今回の改訂では、よくわからない部分のリファクタリングが行われ、見つけにくかったバグがようやく修正されました。

協調的な多重継承も長い間誤解されてきた。実はPySideの多重継承はPythonとは関係ないのですが、ユーザはPySideのクラスでsuper()関数を使ったときに、通常のPythonクラスと同じように動作することを期待しています。他の実装と同様に、私たちも__init__関数を適宜拡張しています。しかし、それで終わりではないのです。実は、多重継承の実装をかなり変えて、すべてのメソッド、メタクラスにおいてさえ、super()が通常のPythonのように動作するようにする必要があるのです。そのためには、super()関数自体を改良して、PySideのクラスで単独で適切に動作するようにする必要があります。  

⭐ 次回のリリースで詳しくご紹介します。ご期待ください! 

バインディング生成ツールShibokenの改良 

マイナーリリースごとに、バインディング生成ツールの現在の実装を少し整理し、新しい機能を追加する機会を得ています。 

生成されるラッパーコードについては、以前はgoto文に頼っていましたが、現在はより良い実装のために安全に削除され置き換えられています。

また、--lean-header という新しいオプションが追加され、モジュールヘッダーのincludeの代わりにforward宣言を生成するようになり、各ラッパーの依存関係を改善することができます。ただし、注入されたコードに対して追加のインクルードが必要になる場合があります。

共有ポインタのサポートをさらに向上させるために、スマートポインタのインスタンスに名前と名前空間を指定できるようになりました。例えば

<smart-pointer-type name="SharedPtr" type="shared"
   getter="data" ref-count-method="useCount"
   null-check-method="isNull"
    instantiations="Integer,Smart::Integer2,Obj"/>

ここで、Smart::Integer2 SmartInteger2Ptr にリネームされていることが確認できます。

不透明なコンテナのための typesystem XML要素が追加され、コンテナ要素の繰り返しが不要になりました。

<opaque-container name="QList"
    opaque-containers="QVector2D:QVector2DList
        QVector3D:QVector3DList;QVector4D:QVector4DList"/>

6.5.0から、Shibokenはstd::array(C++11)をサポートしました。また、std::span (C++20)の実験的なサポートも開始されました。

最後に、図を更新し、いくつかの例を強調することで、ドキュメントを改善しました。

PythonコードのためのモダンなQt QuickアプリケーションUI

ご存知のように、Qt for PythonはQt WidgetsやQt Quickとうまく連動しています。しかし、多くの人から、Qt Quick のアプリケーションのサンプルを作ってほしいという要望があり、その詳細を説明するチュートリアルも用意しています。Qt Quickの性質上、バックエンドはC++やPythonで、グラフィックはQMLで書かれています。

Qt Quickコントロールの柔軟性と適応性を示す新しいQt Quickサンプルである Filesystem Explorer を紹介します。このサンプルは、ファイルシステムを閲覧・表示するための使いやすいインターフェイスを提供し、ユーザーがローカルのテキストファイルを簡単に開くことができるようにします。

extendedexplorer

このプロジェクトでは、Qt Quickアプリケーションをカスタマイズし、必要なコンポーネントを配置することで、視覚的に魅力的でモダンな外観に仕上げる方法を紹介します。UI要素を工夫し、アプリケーションのさまざまな部分を整理して、使いやすさとユーザーエクスペリエンスを向上させる方法を探っていきます。主な目的は、アプリケーションのカスタマイズとレイアウトの技術を実証することです。具体的には、カラースキームやフレームレスウィンドウを使用して、アプリケーションに特徴的で視覚的に魅力的なインターフェイスを作成する方法を探ります。私たちの目標は、開発者がアプリケーションのために高度にパーソナライズされた特定の外観を作成し、システム設定に依存することを避け、完全にカスタマイズされた外観を達成することができるようにすることです。

さらに、オリジナルの例を拡張して、Extended Explorer チュートリアルを作成しました。このチュートリアルでは、実行時に動的に配色を変更できるスキームマネージャーの実装方法を紹介し、機能を拡張しています。この機能では、QMLバインディングとJSON形式のスキームのパースにより、アプリケーションの外観を随時変更する方法を示しています。その結果、開発者はアプリケーションを設計する際に、より柔軟でカスタマイズ性の高いオプションを手に入れることができます。

C++の対応に興味がある方は、こちらでご確認ください

qtpip: 商用wheelをインストール用より良い方法 (進行中) 

商用顧客の多くは、Qt for Pythonの商用パッケージの入手に苦労しています。主に、単純な pip install pyside6 よりも少し複雑な追加ステップが必要なためです。そこで、商用wheelのインストールを可能にするシンプルなpipラッパーに取り組んできました。

このリリースには含まれていませんが、このツールは独自の開発サイクルを持ち、6.5で利用可能になる予定です。人々はこのツールを独自に入手し、Qtアカウントと対話するために使用することができるようになる予定です。

⭐ このツールの準備が完全に整った時点で、専用のブログ記事を投稿する予定です。

非同期サポート

Qt for Pythonは、単なるQtでもなく、単なるPythonでもない。両方の良さを兼ね備えているのです!しかし、Pythonは単なる言語ではなく、Pythonユーザーは広大なPythonエコシステムからお気に入りのライブラリやモジュールの間で幅広い相互運用性を期待しています。

現在、非同期I/Oを使ったアプリケーションを書きたいPython開発者は、asyncioライブラリやtrioライブラリなどの中から選ぶことができます。ご存知の通り、この2つと同様に、Qtはイベントループをベースにしています。このため、Qt for Pythonは、Pythonエコシステムで確立されたライブラリの1つと組み合わせて非同期プログラムロジックを実現するのに適した選択肢と位置付けられ、開発者はそれぞれの強みを生かすことができます。 

現在、Qtと非同期フレームワークをうまく連携させる方法を模索しています。ここ数カ月で、Qt for PythonとTrioのguest run機構を組み合わせる方法を示す2つの例と、asyncioを使った類似の実装の2つの探索的な例が追加されました。 

6.5のリリースサイクルでは、asyncioの抽象的なイベントループをQt for Pythonが独自に実装し、asyncioライブラリをQtのイベントループの下で使用できるようにするなど、さらなる進展を期待することができます。

今後、より多くのPySide6非同期サポートに期待してください!😉 

Androidデプロイメントに初期対応 

PySide6アプリケーションをAndroidにデプロイするための、要望が多く待望されていた機能が、ほぼ完成しました。6.5では、新しいツール「pyside6-android-deploy」のテクニカルプレビュー(TP)をリリースします。このツールは、LinuxベースのデスクトップOSから様々なAndroidプラットフォームへPySide6アプリケーションをパッケージするためのシンプルで使いやすいソリューションを提供します。以下のように、簡単に実行することができます。

pyside6-android-deploy
    --wheel-pyside=<path_to_pyside6_android_wheel>
    --wheel-shiboken=<path_to_shiboken6_android_wheel>
    --name=<app_name> 

このツールは、Qt用の新しいブートストラップを持つpython-for-androidプロジェクトのカスタムフォークを内部的に使用しています。最終的には、プルリクエストを作成し、このフォークをpython-for-androidプロジェクトにマージしたいと思います。

このツールはPySide6とShiboken6のAndroid wheelへのパスを必要とすることにお気づきかもしれません。では、どこで入手するのでしょうか?私たちは今、公式のAndroid wheelを提供しているのでしょうか?

現時点では、公式のAndroid wheelは提供していませんので、ご自身でビルドしていただく必要があります。しかし、特定のAndroidプラットフォーム向けにQt for Python wheelをクロスコンパイルするツールがありますので、ご安心ください。しかし、このツールはPySide6バージョン6.5のインストール先にはありません。このツールは、将来的に公式のAndroid wheelができるかもしれないという期待から、別に用意しておきました。このツールは、指定されたAndroidプラットフォーム用のCPythonをビルドし、ビルドされたCPythonを使ってPySide6 Android wheelをクロスコンパイルします。

python tools/cross_compile_android/main.py
   --plat-name=<android_platform>
   --ndk-path=<path_to_android_ndk>
   --qt-install-path=<path_to_local_Qt_installation>
   --sdk-path=<path_to_android_sdk>

理想的には、デプロイメントプロセス全体が3つのステップで行われることです。

  1. Android NDKとSDKをダウンロードします。
  2. クロスコンパイルツールを実行し、Qt for Python Android wheelをビルドします。
  3. pyside6-android-deploy」ツールを実行します。

ステップ3の最後には、Androidデバイスに公開またはインストールできるapk/aabが作成されます。

上記の文章で興味を持たれた方は、PySide6アプリケーションをAndroidにデプロイする方法について、より詳細な説明を希望されていることでしょう。

⭐ Androidとの互換性については、今後数週間のうちに、より詳細なブログ記事を掲載する予定ですので、ご期待ください。 

(動画の再生に問題がある場合は、こちらでご確認ください)

Pythonの未来に備える

Python 3.11はPythonのエコシステムに多くの改善をもたらし、私たちはなんとか互換性を保つために内部実装を維持しました。ご存知のように、3.12では同じ方向性を継続し、主にパフォーマンスに焦点を当てます。

互換性を保つためには、内部のCPythonの実装を見直す必要があるため、私たちはできるだけ早く3.12のテストを開始しました。まだ完全な互換性はありませんが、いくつかの変更でビルドプロセスの制限を解除することに成功しました。

これと直交するように、私たちは言語の進化に関するPythonコミュニティの最新の動向、特にインタープリタからGILを削除する最新の試みを追ってきました。また、NoGILプロジェクトとの完全な互換性を提供することも目指しています。

NoGILブランチはまだPythonに含めるには不適切な状態です。そのため、実現可能性が明確な範囲でしか検討してきませんでした。今後の見通しは今のところ明るいようです🥳。PySide自身は、保護されていないオブジェクトが複数回使用されないようにする必要が出てきました。しかし、並列実行による結果的な効率は非常に有望である🎉ので、早くこの道が正式に開かれることを期待しています。

今後は? 

新しい実験的なサポート、機能、Pythonモジュールの統合を試し続けたいです。次は何をすればいいのでしょうか?JIRAで提案をしてください👍。

そして、いつものように、弊社のコミュニティプラットフォームに立ち寄り、何かが正しく動作していない場合は、JIRAでバグレポートを作成してお知らせください。


Blog Topics:

Comments