如何从任意长度字符串的Python3数组构建QML列表元素
我不熟悉QML、QtQuick和Python。我想使用QML显示文件列表(完整路径)。似乎我应该使用ListView和ListElements。我发现的示例和教程都使用硬编码且非常简单的列表数据。我不明白如何从这些例子发展到更现实的东西 如何使用后端的Python字符串数组填充QML UI显示的列表? 字符串数组的长度是任意的。我希望列表项是可点击的(可能像QML url类型)。他们将为该文件/url类型打开操作系统的默认应用程序 我的后端代码与此类似:如何从任意长度字符串的Python3数组构建QML列表元素,python,pyqt,qml,pyqt5,qtquick2,Python,Pyqt,Qml,Pyqt5,Qtquick2,我不熟悉QML、QtQuick和Python。我想使用QML显示文件列表(完整路径)。似乎我应该使用ListView和ListElements。我发现的示例和教程都使用硬编码且非常简单的列表数据。我不明白如何从这些例子发展到更现实的东西 如何使用后端的Python字符串数组填充QML UI显示的列表? 字符串数组的长度是任意的。我希望列表项是可点击的(可能像QML url类型)。他们将为该文件/url类型打开操作系统的默认应用程序 我的后端代码与此类似: import sys from subp
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_())
现在我只是将文件列表
字符串数组从后端打印到控制台,但目标是使用该字符串数组填充UI中的QML列表
文件列表的内容示例如下:
['/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', '']
(我需要弄清楚如何处理该数组末尾的空字符串。)
我的QML(尽我目前所能)大致如下:
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)
}
}
我发现的最相关的问题是这些,但它们并没有解决我的问题:
qt-动态创建QML ListElement和内容堆栈溢出
qt-QML ListElement字符串传递列表-堆栈溢出您不需要使用ListModel来填充ListView,因为正如所指出的,模型可以是列表:
型号:型号
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
width: 640
height: 480
TabView {
anchors.fill: parent
Tab {
title: "Files"
ListView {
id: mListViewId
clip: true
anchors.fill: parent
model: backend.files
delegate: Text{
text: model.modelData
}
ScrollBar.vertical: ScrollBar {}
}
}
}
Component.onCompleted: backend.findFiles("/path/to/files")
}
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
width: 640
height: 480
TabView {
anchors.fill: parent
Tab {
title: "Files"
ListView {
id: mListViewId
clip: true
anchors.fill: parent
model: backend.model
delegate: Text{
text: model.display
}
ScrollBar.vertical: ScrollBar {}
}
}
}
Component.onCompleted: backend.findFiles("/path/to/files")
}
此属性保存为列表提供数据的模型
模型提供用于在中创建项的数据集
景色。可以使用ListModel在QML中直接创建模型,
XMListMLoad或ObjutToMead,或由C++模型类< /Stult>提供。如果
使用C++模型类,必须是强> >子模型的子类
或者一个简单的列表
(强调矿山)
我也推荐
在这种情况下,可以通过pyqtProperty
显示列表。另一方面,不要使用subprocess.Popen()
,因为它会阻塞导致GUI冻结,而应使用QProcess
导入操作系统
导入系统
从PyQt5.QtCore导入(
pyqtProperty,
PyQT信号,
pyqtSlot,
qcore应用程序,
QObject,
QProcess,
Qt,
库尔,
)
从PyQt5.QtWidgets导入QApplication
从PyQt5.QtQml导入QQmlApplicationEngine
类后端(QObject):
filesChanged=pyqtSignal()
def uuu init uuu(self,parent=None):
super()。\uuuu init\uuuu(父级)
self.\u文件=[]
self.\u进程=q进程(self)
self.\u进程.readyReadStandardOutput.connect(self.\u在\u readyReadStandardOutput上)
self._process.setProgram(“查找”)
@pyqtProperty(列表,通知=文件更改)
def文件(自):
返回self.\u文件
@pyqtSlot(str)
def FindFile(自、基本路径):
self.\u文件=[]
self.filesChanged.emit()
self._process.setArguments([basepath,“-type”,“f”,“-readable”]))
self.\u进程启动()
def_on_readyReadStandardOutput(自):
new_files=self._process.readAllStandardOutput().data().decode().splitlines()
self.\u files.extend(新的\u文件)
self.filesChanged.emit()
如果名称=“\uuuuu main\uuuuuuuu”:
QCoreApplication.setAttribute(Qt.AA_enableHighdDiscaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app=QApplication(sys.argv)
backend=backend()
引擎=QQmlApplicationEngine()
engine.rootContext().setContextProperty(“后端”,后端)
current_dir=os.path.dirname(os.path.realpath(uu文件_uu))
filename=os.path.join(当前目录“view.qml”)
engine.load(QUrl.fromLocalFile(文件名))
如果不是engine.rootObjects():
系统出口(-1)
sys.exit(app.exec_())
查看.qml
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
width: 640
height: 480
TabView {
anchors.fill: parent
Tab {
title: "Files"
ListView {
id: mListViewId
clip: true
anchors.fill: parent
model: backend.files
delegate: Text{
text: model.modelData
}
ScrollBar.vertical: ScrollBar {}
}
}
}
Component.onCompleted: backend.findFiles("/path/to/files")
}
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
width: 640
height: 480
TabView {
anchors.fill: parent
Tab {
title: "Files"
ListView {
id: mListViewId
clip: true
anchors.fill: parent
model: backend.model
delegate: Text{
text: model.display
}
ScrollBar.vertical: ScrollBar {}
}
}
}
Component.onCompleted: backend.findFiles("/path/to/files")
}
您还可以使用QStringListModel
导入操作系统
导入系统
从PyQt5.QtCore导入(
pyqtProperty,
PyQT信号,
pyqtSlot,
qcore应用程序,
QObject,
QProcess,
QStringListModel,
Qt,
库尔,
)
从PyQt5.QtWidgets导入QApplication
从PyQt5.QtQml导入QQmlApplicationEngine
类后端(QObject):
def uuu init uuu(self,parent=None):
super()。\uuuu init\uuuu(父级)
self.\u model=QStringListModel()
self.\u进程=q进程(self)
self.\u进程.readyReadStandardOutput.connect(self.\u在\u readyReadStandardOutput上)
self._process.setProgram(“查找”)
@pyqtProperty(QObject,常数=True)
def型号(自):
返回自.\u模型
@pyqtSlot(str)
def FindFile(自、基本路径):
self._model.setStringList([])
self._process.setArguments([basepath,“-type”,“f”,“-readable”]))
self.\u进程启动()
def_on_readyReadStandardOutput(自):
new_files=self._process.readAllStandardOutput().data().decode().splitlines()
self.\u model.setStringList(self.\u model.stringList()+新文件)
如果名称=“\uuuuu main\uuuuuuuu”:
QCoreApplication.setAttribute(Qt.AA_enableHighdDiscaling)
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app=QApplication(sys.argv)
backend=backend()
引擎=QQmlApplicationEngine()
engine.rootContext().setContextProperty(“后端”,后端)
current_dir=os.path.dirname(os.path.realpath(uu文件_uu))
filename=os.path.join(当前目录“view.qml”)
engine.load(QUrl.fromLocalFile(文件名))
如果不是engine.rootObjects():
系统出口(-1)
sys.exit(app.exec_())
查看.qml
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
width: 640
height: 480
TabView {
anchors.fill: parent
Tab {
title: "Files"
ListView {
id: mListViewId
clip: true
anchors.fill: parent
model: backend.files
delegate: Text{
text: model.modelData
}
ScrollBar.vertical: ScrollBar {}
}
}
}
Component.onCompleted: backend.findFiles("/path/to/files")
}
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
width: 640
height: 480
TabView {
anchors.fill: parent
Tab {
title: "Files"
ListView {
id: mListViewId
clip: true
anchors.fill: parent
model: backend.model
delegate: Text{
text: model.display
}
ScrollBar.vertical: ScrollBar {}
}
}
}
Component.onCompleted: backend.findFiles("/path/to/files")
}
您不需要使用ListModel来填充ListView,因为正如所指出的,模型可以是列表:
型号:型号
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
width: 640
height: 480
TabView {
anchors.fill: parent
Tab {
title: "Files"
ListView {
id: mListViewId
clip: true
anchors.fill: parent
model: backend.files
delegate: Text{
text: model.modelData
}
ScrollBar.vertical: ScrollBar {}
}
}
}
Component.onCompleted: backend.findFiles("/path/to/files")
}
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
width: 640
height: 480
TabView {
anchors.fill: parent
Tab {
title: "Files"
ListView {
id: mListViewId
clip: true
anchors.fill: parent
model: backend.model
delegate: Text{
text: model.display
}
ScrollBar.vertical: ScrollBar {}
}
}
}
Component.onCompleted: backend.findFiles("/path/to/files")
}
此属性保存为列表提供数据的模型
模型提供用于在中创建项的数据集
景色。可以直接创建模型