QMLとPython通信
Python 3とQML通信については、実際にはPyQt 5+QML+Python 3のハイブリッドプログラミングが必要です.QMLはグラフィックインタフェースを作るのが簡単ですが、機能実装はPythonのほうがいいです.QMLもJavaScriptコードを埋め込んで実現できますが、Pythonで実現するよりは、コードが簡潔で分かりやすいです.
次の例では、次の接続を参照します.
Connecting QML signals in PySide:
http://qt-project.org/wiki/Connecting_QML_Signals_in_PySide
PyQt 5.1.1 Reference Guide -> Support for Signals and Slots:
http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html?highlight=pyqtslot#PyQt5.QtCore.pyqtSlot
(1)QML明示的な呼び出しPython関数
クラスを定義し、QtCoreを継承します.QObjectオブジェクト、および@修飾子を使用してpyqtSlotを修飾
rootContextオブジェクトを作成し、setContextProperty(string,object)を使用してオブジェクトを登録することで、QMLでこの関数を呼び出すことができます.
以下に完全な例を示します.
この例を実行すると、マウスをクリックすると、コンソールに文字列が印刷されます.
Python 3コード:
QMLコード(ファイル名はtest.qmlとして保存):
実行結果は次のとおりです.
(2)QMLはPython関数を呼び出し,返す.
この例は同じですが、今回Pythonを呼び出す関数には戻り値機能があります.
以下に完全な例を示します.
プログラムを実行したら、マウスをクリックすると左上に数字30が表示されます.
Python 3コード:
QMLコード(ファイル名はtest.qmlとして保存):
実行効果は次のとおりです.
マウスをクリックしていない場合:マウスをクリックした後:
(3)QML接続信号Python
QMLがイベントをトリガすると、Pythonに信号が送信され、Pythonが関数を呼び出す.
まずQMLで信号を定義し、
そしてイベントをキャプチャすると信号が送信され、
最後にPythonでrootObjectオブジェクトを作成し、このオブジェクトに接続します.
以下に完全な例を示します.
この例では、マウスをクリックすると、コンソールが情報を印刷します.
Python 3コード:
QMLコード(ファイル名はtest.qmlとして保存):
実行結果は次のとおりです.
(4)Python呼び出しQML関数
QMLに関数を作成し、
PythonでrootObjectオブジェクトを作成し、この関数に接続します.
以下に完全な例を示します.
例では、1 sおきにポインタが45°回転します.
Python 3コード:
QMLコード(ファイル名はtest.qmlとして保存):
実行結果は次のとおりです.
私のレベルは限られています.もし漏れがあれば、ご指摘を歓迎します.
次の例では、次の接続を参照します.
Connecting QML signals in PySide:
http://qt-project.org/wiki/Connecting_QML_Signals_in_PySide
PyQt 5.1.1 Reference Guide -> Support for Signals and Slots:
http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html?highlight=pyqtslot#PyQt5.QtCore.pyqtSlot
(1)QML明示的な呼び出しPython関数
クラスを定義し、QtCoreを継承します.QObjectオブジェクト、および@修飾子を使用してpyqtSlotを修飾
class MyClass(QObject):
@pyqtSlot(str) #
def outputString(self, string):
"""
:
: string
:
"""
print(string)
rootContextオブジェクトを作成し、setContextProperty(string,object)を使用してオブジェクトを登録することで、QMLでこの関数を呼び出すことができます.
context = view.rootContext()
context.setContextProperty("con", con)
以下に完全な例を示します.
この例を実行すると、マウスをクリックすると、コンソールに文字列が印刷されます.
Python 3コード:
# -*- coding: GBK -*-
from PyQt5.QtCore import QUrl, QObject, pyqtSlot
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView
class MyClass(QObject):
@pyqtSlot(str) # str
def outputString(self, string):
"""
:
: string
:
"""
print(string)
if __name__ == '__main__':
path = 'test.qml' # QML
app = QGuiApplication([])
view = QQuickView()
con = MyClass()
context = view.rootContext()
context.setContextProperty("con", con)
view.engine().quit.connect(app.quit)
view.setSource(QUrl(path))
view.show()
app.exec_()
QMLコード(ファイル名はtest.qmlとして保存):
import QtQuick 2.0
Rectangle {
width: 320; height: 240
color: "lightgray"
Text {
id: txt
text: "Clicked me"
font.pixelSize: 20
anchors.centerIn: parent
}
MouseArea {
id: mouse_area
anchors.fill: parent //
onClicked: {
con.outputString("Hello, Python3")
}
}
}
実行結果は次のとおりです.
(2)QMLはPython関数を呼び出し,返す.
この例は同じですが、今回Pythonを呼び出す関数には戻り値機能があります.
以下に完全な例を示します.
プログラムを実行したら、マウスをクリックすると左上に数字30が表示されます.
Python 3コード:
# -*- coding: GBK -*-
from PyQt5.QtCore import QUrl, QObject, pyqtSlot
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView
class MyClass(QObject):
@pyqtSlot(int, result=str) # , int , str
def returnValue(self, value):
"""
:
: value
:
"""
return str(value+10)
if __name__ == '__main__':
path = 'test.qml' # QML
app = QGuiApplication([])
view = QQuickView()
con = MyClass()
context = view.rootContext()
context.setContextProperty("con", con)
view.engine().quit.connect(app.quit)
view.setSource(QUrl(path))
view.show()
app.exec_()
QMLコード(ファイル名はtest.qmlとして保存):
import QtQuick 2.0
Rectangle {
id: root
width: 320; height: 240
color: "lightgray"
Text {
id: txt
text: "Clicked me"
font.pixelSize: 20
anchors.centerIn: parent
}
Text {
id: txt1
text: "..."
font.pixelSize: 20
}
MouseArea {
id: mouse_area
anchors.fill: parent //
onClicked: {
console.log("test...") //
txt1.text = con.returnValue(20)
}
}
}
実行効果は次のとおりです.
マウスをクリックしていない場合:マウスをクリックした後:
(3)QML接続信号Python
QMLがイベントをトリガすると、Pythonに信号が送信され、Pythonが関数を呼び出す.
まずQMLで信号を定義し、
signal sendClicked(string str) //
そしてイベントをキャプチャすると信号が送信され、
MouseArea {
id: mouse_area
anchors.fill: parent //
onClicked: {
root.sendClicked("Hello, Python3") # Python
}
}
最後にPythonでrootObjectオブジェクトを作成し、このオブジェクトに接続します.
def outputString(string):
"""
:
: string
:
"""
print(string)
context = view.rootObject()
context.sendClicked.connect(outputString) # QML sendCLicked
以下に完全な例を示します.
この例では、マウスをクリックすると、コンソールが情報を印刷します.
Python 3コード:
# -*- coding: GBK -*-
from PyQt5.QtCore import QUrl, pyqtSlot
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView
def outputString(string):
"""
:
: string
:
"""
print(string)
if __name__ == '__main__':
path = 'test.qml' # QML
app = QGuiApplication([])
view = QQuickView()
view.engine().quit.connect(app.quit)
view.setSource(QUrl(path))
view.show()
context = view.rootObject()
context.sendClicked.connect(outputString) # QML sendCLicked
app.exec_()
QMLコード(ファイル名はtest.qmlとして保存):
import QtQuick 2.0
Rectangle {
id: root
width: 320; height: 240
color: "lightgray"
signal sendClicked(string str) //
Text {
id: txt
text: "Clicked me"
font.pixelSize: 20
anchors.centerIn: parent
}
MouseArea {
id: mouse_area
anchors.fill: parent //
onClicked: {
root.sendClicked("Hello, Python3") # Python
}
}
}
実行結果は次のとおりです.
(4)Python呼び出しQML関数
QMLに関数を作成し、
function updateRotater() {
rotater.angle += 45
}
PythonでrootObjectオブジェクトを作成し、この関数に接続します.
root = view.rootObject()
timer.timeout.connect(root.updateRotater)
以下に完全な例を示します.
例では、1 sおきにポインタが45°回転します.
Python 3コード:
# -*- coding: GBK -*-
from PyQt5.QtCore import QUrl, QTimer
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView
if __name__ == '__main__':
path = 'test.qml' # QML
app = QGuiApplication([])
view = QQuickView()
view.engine().quit.connect(app.quit)
view.setSource(QUrl(path))
view.show()
timer = QTimer()
timer.start(2000)
root = view.rootObject()
timer.timeout.connect(root.updateRotater)
app.exec_()
QMLコード(ファイル名はtest.qmlとして保存):
import QtQuick 2.0
Rectangle {
id: page
width: 500; height: 200
color: "lightgray"
function updateRotater() {
rotater.angle += 45
}
Rectangle {
id: rotater
property real angle : 0
x: 240; y: 95
width: 100; height: 5
color: "black"
transform: Rotation {
origin.x: 10; origin.y: 5
angle: rotater.angle
}
}
}
実行結果は次のとおりです.
私のレベルは限られています.もし漏れがあれば、ご指摘を歓迎します.