Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Change Data of subclassed QAbstractListModel in Python and show in QML ListView
Forum Updated to NodeBB v4.3 + New Features

Change Data of subclassed QAbstractListModel in Python and show in QML ListView

Scheduled Pinned Locked Moved Unsolved Qt for Python
1 Posts 1 Posters 252 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    childOfGod
    wrote on last edited by
    #1

    Hello,
    I try to implement a GUI with QML and Python. For that, I already implemented an own model (subclass of QAbstractListModel) to be displayed in a ListView. Now I want to change some data of the model, in fact, I want to call other functions and then display the result of this functions in my GUI. I already read something about signals and slots in Qt and I tried to implement a setData() method, cause I read that this is necessary for the data of the model to be changed. Now the problem is, that I don't know how to connect the method in the model with the properties of the QML file, e.g. I want to change the text field inside the ListView but I can't get it.
    Here is some of my code.
    The QML File:

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    
    ApplicationWindow {
        id: root
        visible: true
        width: 600
        height: 650
        title: "listview"
    
    
    
        ListView {
            id: listView
            width: 600
            height: 510
            //anchors.fill: parent
            model: _myModel
    
            delegate: Rectangle {
            id: bottleneck_rect
            height: childrenRect.height
            width: parent.width
            property alias label_rect: label_rect
            
    
            Rectangle {
                width: 290
                height: 50
                //color: "green"
                id: label_rect
                Text {
                    id: label
                    text: qsTr(model.label)
                    font.family: "MS Shell Dlg 2"
                    //font.family: "Inconsolata"
                    font.pointSize: 14
                    anchors.verticalCenter: label_rect.verticalCenter;
    
                }
                anchors {
                    left: parent.left; leftMargin: 10
                }
            }
    }
    
    Rectangle {
        width: 600
        height: 50
        id: route_rect
        property alias mi_route_rect: measurement_info_route_rect
       
        Rectangle {
            width: 290
            height: 50
            id: label_route_rect
            Text {
                id: label_route
                text: qsTr("Route via")
                font.family: "Inconsolata"
                font.pointSize: 14
                //color: "red"
                anchors.verticalCenter: label_route_rect.verticalCenter
    
            }
            anchors {
                left: parent.left; leftMargin: 10
            }
        }
    
        Rectangle {
            property alias textroute: measurement_info_route
            width: 190
            height: 50
            id: measurement_info_route_rect
    
            Text {
                id: measurement_info_route
                text: "here"
                font.family: "Inconsolata"
                font.pointSize: 8
                visible: true
                anchors.verticalCenter: measurement_info_route_rect.verticalCenter
    
            }
            anchors {
                left: label_route_rect.right; leftMargin: 15
            }
        }
    
        anchors {
            bottom: listView.bottom;
        }
    }
    
    Button {
        id: details
        text: "Details"
        anchors {
            top: route_rect.bottom; topMargin: 40
        }
        onClicked: {
            route_rect.mi_route_rect.textroute.visible = !route_rect.mi_route_rect.textroute.visible;
        }
    
    }
    
    
    }
    }
    

    The Model mymodelqt.py:

    #!/usr/bin/env python3
    from enum import Enum
    
    from PyQt5.QtCore import QAbstractListModel, QMetaEnum, QTimer, QModelIndex, QVariant, QObject, QThread, pyqtSignal, pyqtSlot
    
    
        
    class Label:
        def __init__(self, label):
            super().__init__()
            
            self.label = label
    
    
    
    class MyModel(QAbstractListModel):
        def __init__(self):
            super().__init__()
            
            self._labels = [
                                 Label("1rstlabel"),
                                 Label("2ndlabel"),
                                 Label("3rdlabel")
                                 ]
                                 
    
    
        class Roles(QMetaEnum):
            LabelRole = 1
                                 
        def rowCount(self, parent):
            if parent.isValid():
                return 0
            return len(self._labels)
            
            
        def data(self, index, role):
            if not index:
                return QVariant
    
            
            if role == self.Roles.LabelRole:
                return self._labels[index.row()].label
                 
            else:
                return QVariant
    
        def roleNames(self):
            _label = "label".encode('utf-8')
            
    
            mapping = {
                       self.Roles.LabelRole: _label
                       }
            return mapping
            
        
    
        def setData(self, index, value, role) -> bool:
            if not index.isValid():
                return False
            
            if role == self.Roles.LabelRole:
                self._labels[index.row()].label = value
            
            return True
        
        
        textReturn = pyqtSignal(str, arguments=['txt'])
        
        @pyqtSlot(str) 
        def details(self, text):
            print("Clicked the button")   
            txt = text + " Jesus loves you"
            self.textReturn.emit(txt)  
    
               
    
    

    and the main Python-file:

    import sys
    
    
    from PyQt5.QtGui import QGuiApplication
    from PyQt5.QtQml import QQmlApplicationEngine
    
    
    from mymodelqt import MyModel
    
    if __name__ =="__main__":
    
       
        app = QGuiApplication(sys.argv)
        myModel = MyModel()
    
        engine = QQmlApplicationEngine()
        engine.rootContext().setContextProperty("_myModel", myModel)
        engine.quit.connect(app.quit)
        engine.load('qt-forum.qml')
        
        
        
        sys.exit(app.exec_())
    

    I want to change the name of label, e.g. from 1rstlabel to 0label, but in QML I can't get the property label of the Text from outside the ListView. I read something about properties and aliases and tried to implement it and it works for things outside the ListView, you can see that if you try to click the button. I got the visible-property of the text to show and hide the text. But as I said I can't reach the properties inside the ListView to be able to modify them.
    I appreciate your help, thanks for reading this long post and thanks in advance for your advice!

    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved