Search code examples
pythonpython-3.xqmlpyside6

Address text element on .qml


I would like to change a text in my gui. I can address the ListView element for which I have found a solution.

I would also like to address the text element arbitrarily and, for example, replace the text.

Also, I can't manage to address another ListView element with different content.

Here is my little program. Please excuse my English too main.py

import sys
import vensoft_main
from time import sleep
import urllib.request
from pathlib import Path
from PySide6 import QtCore, QtWidgets, QtGui
from PySide6.QtQuick import QQuickView
from PySide6.QtCore import QStringListModel, QUrl
from PySide6.QtGui import QGuiApplication
from PySide6.QtWidgets import QApplication
import json
import sys
from typing import Text
import urllib.request
import json
import pandas as pd 
import random

if __name__ == '__main__':
    # get our data
    url = "file:///Users/joerg/Documents/python/Rohertrag/rohertrag_fenster/output_heute.json"
    response = urllib.request.urlopen(url)
    data = json.loads(response.read().decode('utf-8'))
    
    # Format and sort the data
    data_list = list(data.values())
    
    # Set up the application window
    app = QGuiApplication(sys.argv)
    view = QQuickView()
    view.setResizeMode(QQuickView.SizeRootObjectToView)
    view.update()

    # Expose the list to the Qml code
    my_model = QStringListModel()
    my_model.setStringList(data_list)
    view.setInitialProperties({"myModel": my_model}) 


    # Load the QML file
    qml_file = Path(__file__).parent / "view.qml"
    view.setSource(QUrl.fromLocalFile(qml_file.resolve()))
   
    # Show the window
    if view.status() == QQuickView.Error:
        sys.exit(-1)
    view.show()
    view.update()
   
    # execute and cleanup
    app.exec()
    del view

new.qml

import QtQuick
import QtQuick.Controls
Page {
    width: 640
    height: 480

    Rectangle {
        id: root

        anchors.fill: parent

        ListView {
            id: view_1

            anchors.fill: parent
            anchors.margins: 25
            anchors.bottomMargin: 230
            anchors.rightMargin: 375
            model: manager.model

            delegate: Text {
                anchors.leftMargin: 50
                font.pointSize: 15
                horizontalAlignment: Text.AlignHCenter
                text: display
            }

        }

        Text {
            id: text1

            x: 486
            y: 46
            width: 127
            height: 118
            text: manager.text
            font.pixelSize: 12
        }

        ListView {
            id: view_2
            anchors.fill: parent
            anchors.margins: 25
            anchors.leftMargin: 25
            anchors.topMargin: 238
            anchors.rightMargin: 375
            delegate: Text {
                text: display
                horizontalAlignment: Text.AlignHCenter
                anchors.leftMargin: 50
                font.pointSize: 15
            }
            anchors.bottomMargin: 17
            model: manager.model
        }

        Text {
            id: text2
            x: 479
            y: 272
            width: 127
            height: 118
            text: manager.text
            font.pixelSize: 12
        }

    }

    header: Label {
        color: "#15af15"
        text: qsTr("Wie ist den der Umsatz Heute?")
        font.pointSize: 17
        font.bold: true
        font.family: "Arial"
        renderType: Text.NativeRendering
        horizontalAlignment: Text.AlignHCenter
        padding: 10
    }

}

displayed window


Solution

  • Less is more, you don't need to place unnecessary imports, also you don't need data from external resources, a simple list is enough.

    If you want to manipulate the QML view from python then it is better to create a QObject that has data as properties and export it to QML.

    import sys
    from pathlib import Path
    
    from PySide6.QtCore import (
        Property,
        QDateTime,
        QObject,
        QStringListModel,
        QTimer,
        QUrl,
        Signal,
    )
    from PySide6.QtQuick import QQuickView
    from PySide6.QtGui import QGuiApplication
    
    
    class Manager(QObject):
        text_changed = Signal(name="textChanged")
    
        def __init__(self, parent=None):
            super().__init__(parent)
            self._model = QStringListModel()
            self._text = ""
    
        @Property(QObject, constant=True)
        def model(self):
            return self._model
    
        @Property(str, notify=text_changed)
        def text(self):
            return self._text
    
        @text.setter
        def text(self, text):
            if self.text == text:
                return
            self._text = text
            self.text_changed.emit()
    
    
    def main():
        # get our data
        data_list = ["foo", "bar", "baz"]
    
        manager = Manager()
    
        # Set up the application window
        app = QGuiApplication(sys.argv)
        view = QQuickView()
        view.rootContext().setContextProperty("manager", manager)
        view.setResizeMode(QQuickView.SizeRootObjectToView)
    
        manager.model.setStringList(data_list)
        manager.text = "text"
    
        qml_file = Path(__file__).parent / "view.qml"
        view.setSource(QUrl.fromLocalFile(qml_file.resolve()))
    
        if view.status() == QQuickView.Error:
            sys.exit(-1)
    
        view.show()
    
        def handle_timeout():
            text = QDateTime.currentDateTime().toString()
            manager.text = text
    
        timer = QTimer(interval=1000, timeout=handle_timeout)
        timer.start()
    
        app.exec()
        del view
    
    
    if __name__ == "__main__":
        main()
    
    import QtQuick
    import QtQuick.Controls
    
    Page {
        width: 640
        height: 480
    
        Rectangle {
            id: root
    
            anchors.fill: parent
    
            ListView {
                id: view_1
    
                anchors.fill: parent
                anchors.margins: 25
                anchors.rightMargin: 375
                model: manager.model
    
                delegate: Text {
                    anchors.leftMargin: 50
                    font.pointSize: 15
                    horizontalAlignment: Text.AlignHCenter
                    text: display
                }
    
            }
    
            Text {
                id: text1
    
                x: 486
                y: 46
                width: 127
                height: 201
                text: manager.text
                font.pixelSize: 12
            }
    
        }
    
        header: Label {
            color: "#15af15"
            text: qsTr("Wie ist den der Umsatz Heute?")
            font.pointSize: 17
            font.bold: true
            font.family: "Arial"
            renderType: Text.NativeRendering
            horizontalAlignment: Text.AlignHCenter
            padding: 10
        }
    
    }