[PyQt] Python3.4 + PyQt5 QML ListView - Cannot add entries

Sylvie iamsylvie at openmailbox.org
Mon Dec 21 16:08:40 GMT 2015


Hello everyone,

I started a PyQt5 project a few days ago, but am currently stuck at
trying to populate a QML ListView from my Python code.

Right now, I use findChild to get the ListView with the objectName
"resultList" from my QML and pass it along to a function, which works
fine. However, the list remains empty after trying to add entries to it.
Nothing is displayed, and the count remains 0.

I have added some debug print statements to the relevant part my code,
in the function which updates the resultList ListView:
    def updateResultList(self, resultListObject):
        print(QQmlProperty.read(resultListObject, "count"))

        print(self.filteredPasswordList)

        print(QQmlProperty.read(resultListObject, "model"))
        print(QQmlProperty.write(resultListObject, "model",
QStringListModel(self.filteredPasswordList)))
        print(QQmlProperty.read(resultListObject, "count"))


This prints the following:
0
['School/GitHub', 'Personal/FreePost', 'Personal/NotABug',
'Personal/Mail/List/RiverbankComputing']
None
True
0

Currently, I feel that my mistake probably lies in writing to "model",
but the Qt5 documentation says that "model" contains the list, and this
is also what is used in the QML. Should I be writing to another property
instead?

For the sake of completion, my complete code is as follows:

main.py:

#!/usr/bin/python3
import sys
import os
from os.path import expanduser

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.Qt import *
from PyQt5.QtQuick import *

class ViewModel():
    passwordList = [];
    filteredPasswordList = [];

    def __init__(self, resultListObject):
        self.getPasswords()
        self.filteredPasswordList = self.passwordList
        self.updateResultList(resultListObject)
   
    def getPasswords(self):
        self.passwordList = []

        passDir = expanduser("~") + "/.password-store/"
        for root, dirs, files in os.walk(passDir):
            for name in files:
                if name[0] == ".":
                    continue

                self.passwordList.append(os.path.join(root,
name)[len(passDir):-4])

    def search(self, text, resultListObject):
        self.filteredPasswordList = [];
        searchString = text.lower()
        for password in self.passwordList:
            if searchString in password.lower():
                self.filteredPasswordList.append(password)

        self.updateResultList(resultListObject)

    def updateResultList(self, resultListObject):
        print(QQmlProperty.read(resultListObject, "count"))

        print(self.filteredPasswordList)

        print(QQmlProperty.read(resultListObject, "model"))
        print(QQmlProperty.write(resultListObject, "model",
QStringListModel(self.filteredPasswordList)))
        print(QQmlProperty.read(resultListObject, "count"))

class Window(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.engine = QQmlApplicationEngine(self)
        self.engine.load(QUrl.fromLocalFile("main.qml"))

        self.window = self.engine.rootObjects()[0]

        searchInput = self.window.findChild(QObject, "searchInput")
        resultList = self.window.findChild(QObject, "resultList")

        self.vm = ViewModel(resultList)

        searchInput.textChanged.connect(lambda:
self.vm.search(QQmlProperty.read(searchInput, "text"), resultList))

    def show(self):
        self.window.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())

main.qml:

import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2
import QtQuick.Window 2.1

ApplicationWindow {
    title: 'PyPass'
    property int margin: 10
    width: 500

    x: (Screen.width - width) / 2

    flags: Qt.FramelessWindowHint | Qt.Window

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: margin
        RowLayout {
            Layout.fillWidth: true
            TextField {
                objectName: "searchInput"
                font.pixelSize: 24
                focus: true
                Layout.fillWidth: true
            }
        }
        ScrollView {
            Layout.fillHeight: true
            Layout.fillWidth: true
            ListView {
                objectName: "resultList"
                Layout.fillHeight: true
                Layout.fillWidth: true
            }
        }
    }
}

Thank you in advance for your help!


More information about the PyQt mailing list