Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.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
Python 如何使用QFileSystemModel的索引来跟踪项目的子集?_Python_Qt_Pyqt - Fatal编程技术网

Python 如何使用QFileSystemModel的索引来跟踪项目的子集?

Python 如何使用QFileSystemModel的索引来跟踪项目的子集?,python,qt,pyqt,Python,Qt,Pyqt,我正在尝试创建一个文件选择器对话框,该对话框使用复选框允许选择多个文件。另外,我想用一个对话框从一些已经选择的项目开始。我在网上找到了一些使用QTreeView和QFileSystemModel的子类来实现这一点的示例。对话框完全呈现后,如何将要初始检查的文件路径列表与模型中描述这些路径的QModelIndex项连接起来 我看到的示例保留了一个列表,其中应检查QModelIndex项,并覆盖QFileSystemModel子类的一些方法,如data()方法,以便在检查或取消检查项时更新此列表。为

我正在尝试创建一个文件选择器对话框,该对话框使用复选框允许选择多个文件。另外,我想用一个对话框从一些已经选择的项目开始。我在网上找到了一些使用
QTreeView
QFileSystemModel
的子类来实现这一点的示例。对话框完全呈现后,如何将要初始检查的文件路径列表与模型中描述这些路径的
QModelIndex
项连接起来

我看到的示例保留了一个列表,其中应检查
QModelIndex
项,并覆盖
QFileSystemModel
子类的一些方法,如
data()
方法,以便在检查或取消检查项时更新此列表。为了支持在首次创建对话框时检查某些项目,我尝试使用第二个应该预先检查的文件路径列表。在my
QFileSystemModel
子类的
data()
方法中,我检查
QModelIndex
输入的文件路径,如果它在我的预检查列表中,我从预检查列表中删除文件路径,并将该
QModelIndex
放入其他检查项列表中。我遇到的问题是,模型似乎在创建过程中多次自我再生。对于具有特定路径的索引,第一次调用
data()
,该路径将从预检查列表中删除,并将
QModelIndex
添加到另一个列表中。但是,对话框完全显示后,该文件路径的
QModelIndex
实例与放入预检查列表的实例不同,因此我的代码不知道应该检查它

下面是一个例子来说明我的意思:

import os
import sys

from PyQt5 import QtWidgets

all_entries = list()


class MyFileSystemModel(QtWidgets.QFileSystemModel):

    def data(self, index, role):
        if index not in all_entries:
            all_entries.append(index)
        return super().data(index, role)


class Ui_Dialog(QtWidgets.QDialog):
    def __init__(self, parent=None):
        QtWidgets.QDialog.__init__(self, parent)

        self.model = MyFileSystemModel()
        self.model.setRootPath(os.path.abspath('.'))

        self.tree = QtWidgets.QTreeView()
        self.tree.setModel(self.model)
        self.tree.setRootIndex(self.model.index(os.path.abspath('.')))

        self.llayout = QtWidgets.QVBoxLayout(parent)
        self.but = QtWidgets.QPushButton("OK")

        self.llayout.addWidget(self.tree)
        self.llayout.addWidget(self.but)

        self.setLayout(self.llayout)

        self.but.clicked.connect(self.print_entries)

    def print_entries(self):
        print('*'*80)
        for index in all_entries:
            print(index, os.path.relpath(self.model.filePath(index),
                                         os.path.abspath('.')))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ui = Ui_Dialog()
    ui.show()

    sys.exit(app.exec_())
在名为
test
的目录中运行此脚本,然后单击
OK
按钮,我明白了

********************************************************************************
<PyQt5.QtCore.QModelIndex object at 0x7ff46b991f28> test
<PyQt5.QtCore.QModelIndex object at 0x7ff46b991f98> test
<PyQt5.QtCore.QModelIndex object at 0x7ff46b910048> test
<PyQt5.QtCore.QModelIndex object at 0x7ff46b9100b8> test
********************************************************************************
测验
测验
测验
测验

因此,
test
文件路径的
QModelIndex
项以四个不同的
QModelIndex
项结束。在我更复杂的可检查对话框中,我将在检查项列表中的
0x7ff46b991f28
处使用
QModelIndex
实例,但似乎一旦显示对话框,我就需要使用
0x7ff46b9100b8
处的实例。我可以处理我自己的路径列表中的所有内容,而不用
QModelIndex
对象,但是使用它们的好处是
QFileSystemModel
使用文件系统监视程序跟踪文件系统的更改,我想利用它跟踪所选文件的属性,而无需查询文件系统来判断文件是否已更改。

此问题有以下原因:

  • QModelIndex不应用于区分模型的项目,根据:
注意:应立即使用模型索引,然后丢弃。你 调用模型后不应依赖索引保持有效 更改模型结构或删除项的函数。如果 您需要随时间保留模型索引,请使用QPersistentModelIndex

  • 一个文件在QFileSystemModel中有几个相关列,保存第一列的索引是合适的

考虑到这两方面,代码应如下所示:

all_entries = list()


class MyFileSystemModel(QtWidgets.QFileSystemModel):
    def data(self, index, role):
        if index.column() == 0:
            if QPersistentModelIndex(index) not in all_entries:
                all_entries.append(QPersistentModelIndex(index))
        return super().data(index, role)

[...]

def print_entries(self):
    print('*'*80)
    for index in all_entries:
        ix = QModelIndex(index) # get QModelIndex from QPersistentModelIndex
        print(index, os.path.relpath(self.model.filePath(ix),os.path.abspath('.')))