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 c++ : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 python : Sélectionner tout - Visualiser dans une fenêtre à part
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 :
> 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:
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
Partager