QML信号をPythonのスロットに接続する方法と、QML GUIとのやりとりの仕方を理解するのにかなり時間を費やしました。しかし、私はどのように複数のGUIの入力を同じスロット/関数にPythonで送るかを理解することはできません。PyQtとQML:1つのスロットまたは関数で複数の信号を処理する方法
ここには何が起きるべきかの基本的な例があります: ユーザーはGUIのスピンボックスを操作し、それらの合計が再びGUIに表示されます。 これは、いくつかのシグナルを1つのスロットにルーティングすることによって、または各シグナルを個々のスロットにルーティングして、何らかの形でpythonに結合させることによって行われると想定しています。しかし、明らかにpyqtスロットは "復帰"も許されません。
大変助かりました!
QML: (コメント行は私が働くかもしれないと思ったものですが、そうでない信号線がコメントされていない場合には、「期待トークン `識別子」」になります。)
import QtQuick 2.6
import QtQuick.Controls 2.0
ApplicationWindow{
visible:true
width:200
height:300
id:window
title: "Signal/Slot Test"
Rectangle{
//signal somethingChanged(int, int)
//function exportSignals() {
// somethingChanged(spin1.value, spin2.value)
//}
Column {
spacing: 20
width: parent.width
SpinBox {
id: spin1
signal sig_spin1(int spin1_int)
objectName: "spin1"
value: 50
width: 120
editable: true
Component.onCompleted: {
console.log("Spin1: " + spin1.value)
sig_spin1(spin1.value)
//exportSignals()
}
onValueChanged: {
console.log("Spin1: " + spin1.value)
sig_spin1(spin1.value)
//exportSignals()
}
}
SpinBox {
id: spin2
signal sig_spin2(int spin2_int)
objectName: "spin2"
value: 50
width: 120
editable: true
Component.onCompleted: {
console.log("Spin2: " + spin2.value)
sig_spin2(spin2.value)
//exportSignals()
}
onValueChanged: {
console.log("Spin2: " + spin2.value)
sig_spin2(spin2.value)
//exportSignals()
}
}
Label {
id: label_spin1
objectName: "label_spin1"
text: "Start Value"
}
Label {
id: label_spin2
objectName: "label_spin2"
text: "Start Value"
}
Label {
id: label_result
objectName: "label_result"
text: "Sum"
}
}
}
}
とPythonコード:
import sys
from PyQt5.QtCore import QObject, QUrl, Qt, pyqtSlot
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine
def spin1_update(spin1_int):
print("Spin 1 updated")
label_spin1 = win.findChild(QObject, "label_spin1")
label_spin1.setProperty("text", spin1_int)
def spin2_update(spin2_int):
print("Spin 2 updated")
label_spin2 = win.findChild(QObject, "label_spin2")
label_spin2.setProperty("text", spin2_int)
def spin_sum(spin1_int, spin2_int):
my_sum = spin1_int + spin2_int
label_result = win.findChild(QObject, "label_result")
label_result.setProperty("text", my_sum)
if __name__ == "__main__":
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load('main.qml')
win = engine.rootObjects()[0]
spin1 = win.findChild(QObject, "spin1")
spin1.sig_spin1.connect(spin1_update)
spin2 = win.findChild(QObject, "spin2")
spin2.sig_spin2.connect(spin2_update)
#win.exportSignals.connect()
win.show()
sys.exit(app.exec_())
UPDATE完全を期すため、作業例: main.py:
import sys
from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, QCoreApplication, QObject, QUrl
from PyQt5.QtQml import QQmlEngine, QQmlApplicationEngine
from PyQt5.QtWidgets import QApplication
class GuiInteraction(QObject):
def __init__(self, parent=None):
super().__init__(parent)
@pyqtSlot(int, int, result=int)
def get_sum(self, spin1, spin2):
print("Spin1 from python: ", spin1)
print("Spin2 from the same python slot: ", spin2)
my_sum = spin1 + spin2
print(my_sum)
print()
return my_sum
if __name__ == "__main__":
app = QApplication(sys.argv)
guiInteraction = GuiInteraction()
engine = QQmlApplicationEngine()
ctx = engine.rootContext()
ctx.setContextProperty("guiInteraction", guiInteraction)
engine.load('main.qml')
win = engine.rootObjects()[0]
win.show()
sys.exit(app.exec_())
そしてmain.qml:
import QtQuick 2.6
import QtQuick.Controls 2.0
ApplicationWindow{
visible:true
width:200
height:300
id:window
title: "Signal/Slot Test"
Rectangle{
Column {
spacing: 20
width: parent.width
SpinBox {
id: spin1
value: 50
width: 120
editable: true
Component.onCompleted: {
console.log("Spin1: " + spin1.value)
}
onValueChanged: {
console.log("Spin1: " + spin1.value)
label_result.text = guiInteraction.get_sum(spin1.value, spin2.value)
}
}
SpinBox {
id: spin2
value: 50
width: 120
editable: true
Component.onCompleted: {
console.log("Spin2: " + spin2.value)
}
onValueChanged: {
console.log("Spin2: " + spin2.value)
label_result.text = guiInteraction.get_sum(spin1.value, spin2.value)
}
}
Label {
id: label_result
objectName: "label_result"
text: "Nothing yet."
}
}
}
}
なぜPythonを使ってラベルの値を設定したいのですか? C++から値を設定できるC++と同じように、あなたはそうするように勧められませんが、PyQtでそれを行うのは良いスタイルだとは思っていません。 – derM
これはどうやって動作するのか誤解するかもしれません。私はC++については分かりませんが、Pythonについて知っています。当然、私はPythonでqml guiに設定できる値からいくつかの計算を実行してから、それらをguiに送り返したいと思います。これはPyQtの範囲外ですか?私はそれが非常に自然な使用事例だと思うだろう。 – user1412286
私が意味したのは、ケビン・クラマーが答えたところです。プロパティバインディングを使用して値をQML-Sideに取得する必要があります。したがって、Pythonを使ってQML-Sideに書き込むのではなく、QMLを使ってPython-Sideから読み込みます。 – derM