QML と Qt for Python の連携

Published Saturday September 8th, 2018
Leave a comment
Posted in Qt for Python | Tags: , ,

この記事は The Qt BlogQML and Qt for Python interaction を翻訳したものです。
執筆: Friedemann Kleint, 2018年05月14日

QtWidgets というデスクトップのアプリケーション向けの UI 技術に加え、Qt は QML という UI 技術も提供しています。

今回は、Qt for Python で QML をどう使うのかを、declarative/extending/chapter3-bindings を基に大まかに説明をしたいと思います。

まず初めに、.qml ファイルをロードするための基本的な型を見てみましょう。QGuiApplicationQQuickView のインスタンスを生成します。

QML のエレメントがビューのサイズに追従するよう、resizeMode プロパティに SizeRootObjectToView を設定します。

app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)

その後、ビューの setSource メソッドを使用して QML のロードを行います。

QML は Python スクリプトと同じ場所に置くことが多いので、os module の機能を利用してフルパス化しています。

current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'app.qml')
view.setSource(QUrl.fromLocalFile(qmlFile))
if view.status() == QQuickView.Error:
    sys.exit(-1)

これでビューが表示されアプリケーションが動作します。終了時は、破棄の順序に注意が必要で、アプリケーション終了前にビューのオブジェクトを del する必要があります。

view.show()
res = app.exec_()
del view
sys.exit(res)

以上で、QML ファイルを表示することができました。最小限の Hello World は以下のような app.qml で実現できます。

import QtQuick 2.0

Text {
    text : 'Hello, world!'
}

Python で書かれたクラスで QML を拡張する

QQuickPaintedItem を利用して少し実装をしてみましょう。

class PieChart (QQuickPaintedItem):
    def __init__(self, parent = None):
        QQuickPaintedItem.__init__(self, parent)
        self.color = QColor()

    def paint(self, painter):
        pen = QPen(self.color, 2)
        painter.setPen(pen);
        painter.setRenderHints(QPainter.Antialiasing, True);
        # From drawPie(const QRect &rect, int startAngle, int spanAngle)
        painter.drawPie(self.boundingRect().adjusted(1,1,-1,-1),
            90 * 16, 290 * 16);

    def getColor(self):
        return self.color

    def setColor(self, value):
        if value != self.color:
            self.color = value
            self.update()
            self.colorChanged.emit()

    colorChanged = Signal()
    color = Property(QColor, getColor, setColor, notify=colorChanged)

QQuickPaintedItem.paint() をオーバーライドし、円グラフを描画しました。color はプロパティとして宣言しているため、Qt 側から見えるようになっています。QML 側に型として登録するには以下のコードが必要です。

qmlRegisterType(PieChart, 'Charts', 1, 0, 'PieChart');

QGuiApplication を生成した直後に追加してください。

app.qml を以下のように変えてみましょう。

import Charts 1.0
import QtQuick 2.0

Item {
    width: 300; height: 200

    PieChart {
        id: chartA
        width: 100; height: 100
        color: "red"
        anchors.centerIn:parent
    }

    MouseArea {
        anchors.fill: parent
        onClicked: { chartA.color = "blue" }
    }

    Text {
        anchors {
            bottom: parent.bottom;
            horizontalCenter: parent.horizontalCenter;
            bottomMargin: 20
        }
        text: "Click anywhere to change the chart color"
    }
}

これで独自型が利用できるようになりました。

ついでに、マウスのクリックで color プロパティが変わるようにしてあります。

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Qt for Python | Tags: , ,

Leave a Reply

Your email address will not be published.

Get started today with Qt Download now