I'm new to QML, QtQuick and Python. I would like to display a list of files (full path) using QML. It seems like I should use a ListView and ListElements. The examples and tutorials I have found all use list data that is hard-coded and very simple. I do not understand how to go from those examples to something more realistic.
How do I use a Python string array from my backend to populate a list displayed by the QML UI?
The length of the string array is arbitrary. I want the list items to be clickable (like a QML url type, possibly). They will open the operating system's default application for that file/url type.
My backend code is similar to this:
import sys
from subprocess import Popen, PIPE
import getpass
from PyQt5.QtWidgets import QApplication, QMessageBox
from PyQt5.QtCore import Qt, QCoreApplication, QObject, pyqtSlot
from PyQt5.QtQml import QQmlApplicationEngine
class Backend(QObject):
basepath = '/path/to/files'
list_files_cmd = "find " + basepath + " -type f -readable"
myfiles = Popen(list_files_cmd, shell=True, stdout=PIPE, stderr=PIPE)
output, err = myfiles.communicate()
# the output is a Byte literal like this: b'/path/to/file1.txt\n/path/to/file2.txt\n'. Transform into a regular string:
newstr = output.decode(encoding='UTF-8')
files_list = newstr.split('\n')
for file in files_list:
print(file)
if __name__ == '__main__':
backend = Backend()
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv)
engine = QQmlApplicationEngine('view.qml')
engine.rootContext().setContextProperty("backend", backend)
sys.exit(app.exec_())
Right now I am just printing the files_list string array from the backend to the console, but the goal is to use that string array to populate the QML list in the UI.
An example of the contents of files_list is:
['/path/to/files/xdgr/todo.txt', '/path/to/files/xdgr/a2hosting.txt', '/path/to/files/xdgr/paypal.txt', '/path/to/files/xdgr/toggle.txt', '/path/to/files/xdgr/from_kty.txt', '/path/to/files/xdgr/feed59.txt', '/path/to/files/one/sharing.txt', '/path/to/files/two/data.dbx', '']
(I will need to figure out how to deal with the null string at the end of that array.)
A rough outline of my QML (to the best of my current ability) is like this:
import QtQml.Models 2.2
import QtQuick.Window 2.2
import QtQuick 2.2
import QtQuick.Controls 1.3
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
ApplicationWindow {
visible: true
TabView {
anchors.fill: parent
Tab {
title: "Files"
anchors.fill: parent
ListView {
id: mListViewId
anchors.fill: parent
model: mListModelId
delegate : delegateId
}
ListModel {
id: mListModelId
// I would like backend.files_list to provide the model data
}
}
}
Component.onCompleted: {
mListModelId.append(backend.files_list)
}
}
The most relevant questions I have found are these, but they did not resolve my issue:
qt - Dynamically create QML ListElement and content - Stack Overflow Dynamically create QML ListElement and content
qt - QML ListElement pass list of strings - Stack Overflow QML ListElement pass list of strings