Python 向QTreeView/QFileSystemModel中的项添加其他信息
我希望根据数据库中存储的许多属性以及项目是文件夹还是文件,以不同的方式呈现QTreeView中的每个项目。但是,我不理解QTreeView或QFileSystemModel如何与委托通信。无论何时必须绘制项目,包括在初始化期间,我都希望为委托提供它所需的所有参数,然后在委托中使用一系列Python 向QTreeView/QFileSystemModel中的项添加其他信息,python,qt,pyside,qtreeview,qfilesystemmodel,Python,Qt,Pyside,Qtreeview,Qfilesystemmodel,我希望根据数据库中存储的许多属性以及项目是文件夹还是文件,以不同的方式呈现QTreeView中的每个项目。但是,我不理解QTreeView或QFileSystemModel如何与委托通信。无论何时必须绘制项目,包括在初始化期间,我都希望为委托提供它所需的所有参数,然后在委托中使用一系列if语句来设置特定项目的绘制方式。我只找到了.setItemDelegate方法,不知道何时或如何实际调用委托,也不知道它如何循环遍历模型中的所有项。下面是一个基于在线材料的示例。有两个问题: 我把代码放在我无法工
if
语句来设置特定项目的绘制方式。我只找到了.setItemDelegate
方法,不知道何时或如何实际调用委托,也不知道它如何循环遍历模型中的所有项。下面是一个基于在线材料的示例。有两个问题:
C:\Program Files\Internet Explorer\
时,会打印到终端。但是,它只显示目录,而不向终端打印任何内容。我想知道:
if
语句在绘制时为显示中的每个项目触发import sys
from PySide.QtCore import *
from PySide.QtGui import *
database = {'C:\Program Files\Internet Explorer\ExtExport.exe':(1,3), 'C:\Program Files\Internet Explorer\iexplore.exe':(0,0)}
class newFileModel(QFileSystemModel):
def __init__(self, parent=None):
QFileSystemModel.__init__(self, parent)
#self.elements = [[Do I need this? What should go here?]]
def data(self, index, role=Qt.DisplayRole):
if index.isValid():
path = self.filePath(index)
if self.isDir(index):
if database.get(path) != None:
if database[path][0] > 0:
print("Acting on custom data 0.") # I can add code here for different color text, etc.
if database[path][1] > 0:
print("Acting on custom data 1.") # I'll add code later
#return self.data(index, role) # Do I need this about here?
class fileSystemBrowser(QTreeView):
def __init__(self, parent=None):
super().__init__(parent)
self.fileSystemModel = newFileModel()
self.fileSystemModel.setRootPath(QDir.currentPath())
self.setModel(self.fileSystemModel)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = fileSystemBrowser()
window.show()
sys.exit(app.exec_())
下面是一个基本演示,演示如何添加带有图标和其他格式的额外列。请注意,尝试规范化文件路径,以便比较和字典查找更可靠:
import sys
from PySide.QtCore import *
from PySide.QtGui import *
database = {
QFileInfo('C:\Program Files\Internet Explorer\ExtExport.exe').absoluteFilePath(): (1, 3),
QFileInfo('C:\Program Files\Internet Explorer\iexplore.exe').absoluteFilePath(): (0, 0),
}
class FileSystemModel(QFileSystemModel):
def __init__(self, parent=None):
super().__init__(parent)
style = qApp.style()
self.icons = [
style.standardIcon(QStyle.SP_MessageBoxInformation),
style.standardIcon(QStyle.SP_MessageBoxWarning),
]
def columnCount(self, parent=QModelIndex()):
return super().columnCount(parent) + 1
def data(self, index, role=Qt.DisplayRole):
extra = False
if index.isValid():
extra = index.column() == self.columnCount(index.parent()) - 1
info = self.fileInfo(index)
path = info.absoluteFilePath()
if path in database:
major, minor = database[path]
print('found:', (major, minor), path)
if extra:
if role == Qt.DecorationRole:
if major > 0:
return self.icons[0]
else:
return self.icons[1]
elif role == Qt.DisplayRole:
return '%s/%s' % (major, minor)
elif role == Qt.ForegroundRole:
if minor > 2:
return QColor('red')
if not extra:
return super().data(index, role)
def headerData(self, section, orientation, role=Qt.DisplayRole):
if (orientation == Qt.Horizontal and
role == Qt.DisplayRole and
section == self.columnCount() - 1):
return 'Extra'
return super().headerData(section, orientation, role)
class FileSystemBrowser(QTreeView):
def __init__(self, parent=None):
super().__init__(parent)
self.fileSystemModel = FileSystemModel()
self.fileSystemModel.setRootPath(QDir.currentPath())
self.setModel(self.fileSystemModel)
self.header().moveSection(self.fileSystemModel.columnCount() - 1, 1)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = FileSystemBrowser()
window.show()
sys.exit(app.exec_())
编辑:
data
方法中使用的角色都记录在下,介绍如下:
模型中的每个项都有一组与其关联的数据元素,
每个人都有自己的角色。视图使用这些角色来指示
模型需要哪种类型的数据。自定义模型应该返回
这些类型的数据
对于已添加的额外列,必须提供所有内容,因为它是一个虚拟列,不属于基础模型的一部分。但对于其他列,我们只需调用基类实现即可获得默认值(当然,如果需要,我们还可以为这些列返回自定义值以修改现有行为)。根据您想要做的具体操作,项委托可能会有些过分。你确定你想自己画所有的东西吗?这可能是一项艰巨的工作。您希望更改哪些特定属性?子类化文件模型并重新实现
数据
方法看起来更容易实现。我想根据fileSystemBrowser类实例(最终)可用的参数更改视图中的背景颜色、文本颜色、文本字体以及可能的图标。是文件模型子类化和重写数据方法的示例吗?如果是这样的话,很遗憾,我不理解这一点。我熟悉像ggplot2 for R这样的图形系统。对于Qt委托,我正在寻找但没有找到任何熟悉的东西。您需要对模型进行子类化,而不是树视图。除了为它们创建额外的列之外,我看不到任何添加多个图标的简单方法。在文件图标之后插入附加图标的想法对我来说似乎很奇怪-它肯定会产生一个非常混乱和丑陋的界面。额外的列将更加用户友好,并且更易于实现。函数必须返回所请求的数据,在您的情况下,它不会返回任何内容,如果您只想知道它是否正在调用,我建议返回QFileSystemModel.data(self、index、role)
在本例中,我在Linux中使用了没有空格的路径,如果在输入数据库中的路径时打印了该函数,则该函数可以完美地工作。我要花一天或更多的时间来研究你是如何完成的。(对我来说)有很多新方法。@davideps。很高兴你觉得它有用。请随意询问我使用的方法是否有什么让您困惑的地方。QFileInfo
上的文档非常清晰,看起来非常有用。谢谢你的介绍。使用style=qApp.style()
可以获得应用程序“样式对象”的副本,然后设置两个图标以适应该样式?这里的尾随逗号是否只是为了让括号位于下一行?从Python教程中,我学会了在打印时始终使用占位符,并将print('found:',(major,minor),path)
写成print('found:(%d,%d),%s%%(major,minor,path))
。我没有意识到您的语法是有效的。数据库中的if路径:
比我的if数据库更直观。get(path)!=无:
。我没有意识到中的会以键为目标。
import sys
from PySide.QtCore import *
from PySide.QtGui import *
database = {'C:\Program Files\Internet Explorer\ExtExport.exe':(1,3), 'C:\Program Files\Internet Explorer\iexplore.exe':(0,0)}
class newFileModel(QFileSystemModel):
def __init__(self, parent=None):
QFileSystemModel.__init__(self, parent)
#self.elements = [[Do I need this? What should go here?]]
def data(self, index, role=Qt.DisplayRole):
if index.isValid():
path = self.filePath(index)
if self.isDir(index):
if database.get(path) != None:
if database[path][0] > 0:
print("Acting on custom data 0.") # I can add code here for different color text, etc.
if database[path][1] > 0:
print("Acting on custom data 1.") # I'll add code later
#return self.data(index, role) # Do I need this about here?
class fileSystemBrowser(QTreeView):
def __init__(self, parent=None):
super().__init__(parent)
self.fileSystemModel = newFileModel()
self.fileSystemModel.setRootPath(QDir.currentPath())
self.setModel(self.fileSystemModel)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = fileSystemBrowser()
window.show()
sys.exit(app.exec_())
import sys
from PySide.QtCore import *
from PySide.QtGui import *
database = {
QFileInfo('C:\Program Files\Internet Explorer\ExtExport.exe').absoluteFilePath(): (1, 3),
QFileInfo('C:\Program Files\Internet Explorer\iexplore.exe').absoluteFilePath(): (0, 0),
}
class FileSystemModel(QFileSystemModel):
def __init__(self, parent=None):
super().__init__(parent)
style = qApp.style()
self.icons = [
style.standardIcon(QStyle.SP_MessageBoxInformation),
style.standardIcon(QStyle.SP_MessageBoxWarning),
]
def columnCount(self, parent=QModelIndex()):
return super().columnCount(parent) + 1
def data(self, index, role=Qt.DisplayRole):
extra = False
if index.isValid():
extra = index.column() == self.columnCount(index.parent()) - 1
info = self.fileInfo(index)
path = info.absoluteFilePath()
if path in database:
major, minor = database[path]
print('found:', (major, minor), path)
if extra:
if role == Qt.DecorationRole:
if major > 0:
return self.icons[0]
else:
return self.icons[1]
elif role == Qt.DisplayRole:
return '%s/%s' % (major, minor)
elif role == Qt.ForegroundRole:
if minor > 2:
return QColor('red')
if not extra:
return super().data(index, role)
def headerData(self, section, orientation, role=Qt.DisplayRole):
if (orientation == Qt.Horizontal and
role == Qt.DisplayRole and
section == self.columnCount() - 1):
return 'Extra'
return super().headerData(section, orientation, role)
class FileSystemBrowser(QTreeView):
def __init__(self, parent=None):
super().__init__(parent)
self.fileSystemModel = FileSystemModel()
self.fileSystemModel.setRootPath(QDir.currentPath())
self.setModel(self.fileSystemModel)
self.header().moveSection(self.fileSystemModel.columnCount() - 1, 1)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = FileSystemBrowser()
window.show()
sys.exit(app.exec_())