PyQt et QML : transtypage ?
Bonjour à tous,
J'essaye de traduire un bout de code C++ en PyQT + QML. C'est fonctionnel mais je me pose une question quant à un problème de transtypage.
Donc l'idée en gros est de cliquer sur un item QML (ici la fenêtre, ça pourrait être un bouton, mais l'idée est la même) et d'appeler une fonction python. De là obtenir une propriété QML et sa valeur.
Le code C++ :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
class MyClass : public QObject
{
Q_OBJECT
public slots:
void cppSlot(const QVariant &v) {
qDebug() << "Called the C++ slot with value:" << v;
QQuickItem *item = qobject_cast<QQuickItem*>(v.value<QObject*>());
qDebug() << "Item dimensions:" << item->width() << item->height();
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QQuickView view(QUrl::fromLocalFile("MyItem.qml"));
QObject *item = view.rootObject();
MyClass myClass;
QObject::connect(item, SIGNAL(qmlSignal(QVariant)),
&myClass, SLOT(cppSlot(QVariant)));
view.show();
return app.exec();
} |
Le code QML (de fait, le même pour les deux langages) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
// MyItem.qml
import QtQuick 2.0
Item {
id: item
width: 100; height: 100
signal qmlSignal(var anObject)
MouseArea {
anchors.fill: parent
onClicked: item.qmlSignal(item)
}
} |
Le code Python (Python 3 + PyQT5) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#! /usr/bin/env python3
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQuick import QQuickView
from PyQt5.QtCore import QUrl, QObject, pyqtSlot, QVariant
class MyClass(QObject):
def __init__(self, parent = None):
super().__init__(parent)
@pyqtSlot(QVariant)
def pySlot(self, v):
print("slot called with value: {}".format(v))
print(v.hasProperty("enabled"))
print(v.hasProperty("rotation"))
print(v.hasProperty("grabMouse"))
if v.hasProperty("width"):
print("v has prop width!")
width = v.property("width")
print("width: {}".format(width.toInt()))
else:
print("v has no prop width :(")
def main(argv):
app = QApplication(argv)
view = QQuickView(QUrl.fromLocalFile("MyItem.qml"))
item = view.rootObject()
myclass = MyClass()
item.qmlSignal.connect(myclass.pySlot)
view.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main(sys.argv) |
Sortie du programme :
Citation:
> python main.py
slot called with value: <PyQt5.QtQml.QJSValue object at 0x0000000003535EB8>
True
True
False
v has prop width!
width: 100
Bizarrement alors que je suis sensé obtenir un QVariant, j'obtiens un objet QJSValue en paramètre du slot (alors que mon slot est bien déclaré avec un QVariant)... Soit,...
Dans le code C++ l'objet QVariant est casté (transtypé) en QQuickItem.
Si j'interroge l'objet je vois qu'il dispose des propriétés d'un QQuickItem (enabled, rotation) mais, par exemple je ne peux pas accéder à ses fonctions (exemple avec "grabMouse' ou alors je n'ai pas compris comment faire).
Question:
:arrow: Sachant que l'objet que j'obtiens est un QJSValue (et non un QVariant) et que Python/PyQt ne dispose pas, comme en C++, d'un qobject_cast pour le transtypage, comment puis-je accéder aux fonctions de mon objet comme s'il s'agissait d'un QQuickITem (ou d'un QVariant mais je retombe sur le même problème) ?
Merci :!: