2
votes

I'm not familiar how to connect Python with QML, so I'd be glad if I can get some directions...

I want to call a QML method manipulatePieSeries() in order to manipulate some UI fields. This is the code I have. What I have to add in main.py in order to make it happen?

main.py

import os
import sys

from PyQt5 import QtCore, QtGui, QtWidgets, QtQuick, QtChart

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    view = QtQuick.QQuickView()

    filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), "main.qml")

    view.setSource(QtCore.QUrl.fromLocalFile(filename))
    view.show()

    sys.exit(app.exec_())

main.qml

import QtQuick 2.7
import QtQuick.Window 2.0
import QtQuick.Controls 1.4
import QtCharts 2.1

Grid {
    id: grid1
    width: 1024
    height: 600
    spacing: 10
    rows: 1
    columns: 2

    VPieModelMapper {
        id: mapper0
        series: serie0
        labelsColumn: 0
        valuesColumn: 1
        firstRow: 0
        rowCount: 100
    }

    ChartView {
        id: chart
        width: 600
        height: 600
        antialiasing: true
        animationDuration: 1000
        animationOptions: ChartView.AllAnimations
        title: "MyTitle"
        legend.visible: false

        PieSeries {
            id: serie0
            name: "Outer Ring"
            size: 0.75
            holeSize: 0.7
            function manipulatePieSeries(param1, param2, param3) {
                console.log("Params: ", param1, param2, param3)
            }
        }
    }
}
1

1 Answers

1
votes

If you want to manipulate some QML information from python, the logic is to create a QObject where a signal is emitted with the parameters that you want to send to QML and make connections in QML using Connections:

import os
import random
import sys

from PyQt5 import QtCore, QtGui, QtWidgets, QtQuick


class Helper(QtCore.QObject):
    customSignal = QtCore.pyqtSignal(float, float, float, arguments=['param1', 'param2', 'param3'])

    def call_manipulatePieSeries(self, param1, param2, param3):
        self.customSignal.emit(param1, param2, param3)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    helper = Helper()

    view = QtQuick.QQuickView()
    view.rootContext().setContextProperty("helper", helper)
    filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), "main.qml")
    view.setSource(QtCore.QUrl.fromLocalFile(filename))
    view.show()

    def on_timeout():
        helper.call_manipulatePieSeries(
            random.uniform(10, 100), random.uniform(10, 100), random.uniform(10, 100)
        )

    timer = QtCore.QTimer(interval=1000, timeout=on_timeout)
    timer.start()

    sys.exit(app.exec_())
import QtQuick 2.7
import QtQuick.Window 2.0
import QtQuick.Controls 1.4
import QtCharts 2.1

Grid {
    id: grid1
    width: 1024
    height: 600
    spacing: 10
    rows: 1
    columns: 2

    VPieModelMapper {
        id: mapper0
        series: serie0
        labelsColumn: 0
        valuesColumn: 1
        firstRow: 0
        rowCount: 100
    }

    ChartView {
        id: chart
        width: 600
        height: 600
        antialiasing: true
        animationDuration: 1000
        animationOptions: ChartView.AllAnimations
        title: "MyTitle"
        legend.visible: false

        PieSeries {
            id: serie0
            name: "Outer Ring"
            size: 0.75
            holeSize: 0.7
            function manipulatePieSeries(param1, param2, param3) {
                console.log("Params: ", param1, param2, param3)
            }
        }
    }
    Connections{
        target: helper
        onCustomSignal: serie0.manipulatePieSeries(param1, param2, param3)
    }
}