Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从任意长度字符串的Python3数组构建QML列表元素_Python_Pyqt_Qml_Pyqt5_Qtquick2 - Fatal编程技术网

如何从任意长度字符串的Python3数组构建QML列表元素

如何从任意长度字符串的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

我不熟悉QML、QtQuick和Python。我想使用QML显示文件列表(完整路径)。似乎我应该使用ListView和ListElements。我发现的示例和教程都使用硬编码且非常简单的列表数据。我不明白如何从这些例子发展到更现实的东西

如何使用后端的Python字符串数组填充QML UI显示的列表?

字符串数组的长度是任意的。我希望列表项是可点击的(可能像QML url类型)。他们将为该文件/url类型打开操作系统的默认应用程序

我的后端代码与此类似:

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")
}
此属性保存为列表提供数据的模型

模型提供用于在中创建项的数据集 景色。可以直接创建模型