简洁版本
我正在尝试显示 aQAbstracctTableModel中的数据QTreeView。当我这样做时,我最终将整个表显示为每个节点的子节点(以及孙节点,等等)。如何显示抽象表模型的树视图?
细节
QAbstractTableModel我正在尝试在a 中显示一些数据QTreeView。在模型-视图教程中,介绍了一个示例后QAbstractTableModel,它看起来就像替换为一样QTableView简单QTreeView:
您可以将上面的示例转换为具有树视图的应用程序。只需将 QTableView 替换为 QTreeView,就会生成一个读/写树。无需对模型进行任何更改。
当我进行此替换时,我最终会显示一棵树,但如果我单击任何图标来展开它(这应该不会执行任何操作,因为没有内置层次结构),Python 会崩溃并显示Python.exe has stopped working. 这个问题之前已经提出过],但没有可行的解决方案。
为了尝试修复此行为,我在子QAbstractTableModel类中重新实现了索引函数(请参阅下面的完整工作示例)。这会导致一种非常不同类型的错误。也就是说,树中的每个节点现在都包含整个表作为数据。无论我点击多少次,整个表格都会显示出来。像这样:

我似乎陷入了某种递归的噩梦中,不知道如何逃脱。下面的相关问题表明我可能必须转到QAbstractItemModel,但上面的教程引用表明不然(其中指出,无需对模型进行任何更改)。
相关问题
完整的工作示例
from PySide import QtGui, QtCore
class Food(object):
def __init__(self, name, shortDescription, note, parent = None):
self.data = (name, shortDescription, note);
self.parentIndex = parent
class FavoritesTableModel(QtCore.QAbstractTableModel):
def __init__(self):
QtCore.QAbstractTableModel.__init__(self)
self.foods = …Run Code Online (Sandbox Code Playgroud) 下面是一些创建单个窗口的代码,只是为了好玩,您可以在窗口中单击以进行打印,self.pos()并且self.mapToGlobal(self.pos()):
from PySide import QtGui, QtCore
class WinPosExplore(QtGui.QWidget):
def __init__(self):
QtGui.QApplication.setStyle(QtGui.QStyleFactory.create("Plastique"))
QtGui.QWidget.__init__(self)
self.show()
def mousePressEvent(self, event):
if event.buttons() == QtCore.Qt.LeftButton:
winPos=self.pos()
globalWinPos = self.mapToGlobal(winPos)
msg1="winPos=self.pos(): <{0}, {1}>\n".format(winPos.x(), winPos.y())
msg2="self.mapToGlobal(winPos): <{0}, {1}>\n\n".format(globalWinPos.x(), globalWinPos.y())
print msg1 + msg2
def main():
import sys
qtApp=QtGui.QApplication(sys.argv)
myWinPos=WinPosExplore()
sys.exit(qtApp.exec_())
if __name__=="__main__":
main()
Run Code Online (Sandbox Code Playgroud)
因为我只使用一个顶级窗口,所以我希望这两组坐标是相同的.也就是说,我希望程序能够意识到,对于应用程序的父窗口,mapToGlobal它只是身份功能.但这不是发生的事情.我以不可解释的方式得到不同的坐标(由我).例如,以下是一个打印输出:
winPos=self.pos(): <86, 101>
self.mapToGlobal(winPos): <176, 225>
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释发生了什么?
注意,我在某种程度上意识到这是一个愚蠢的练习(从技术上讲,我们在主窗口上并不需要mapToGlobal,正如qtforum上的这篇文章所指出的那样).但是我仍然很好奇是否有人能够在这个角落里理解这种行为.
我QStandardItemModel在PySide中有一个,想删除某些行上的文本(这是一个待办事项列表应用程序,当任务完成时,我想删除文本)。鉴于QStandardItem显示的很好,根据文档,我尝试使用以下内容删除文本:
QStandardItem.setFont(QtGui.QFont.setStrikeOut(True))
Run Code Online (Sandbox Code Playgroud)
但是文本没有改变,并且出现错误:
TypeError: descriptor 'setStrikeOut' requires a 'PySide.QtGui.QFont' object but received a 'bool'
Run Code Online (Sandbox Code Playgroud) 我有一个带有自定义委托的树视图,我正在尝试向其中添加自动换行功能。自动换行工作正常,但sizeHint()似乎不起作用,因此当文本换行时,相关行不会扩展以包含它。
我以为我sizeHint()回来照顾它document.size().height()。
def sizeHint(self, option, index):
text = index.model().data(index)
document = QtGui.QTextDocument()
document.setHtml(text)
document.setTextWidth(option.rect.width())
return QtCore.QSize(document.idealWidth(), document.size().height())
Run Code Online (Sandbox Code Playgroud)
但是,当我打印出来document.size().height()时,每个项目都是一样的。
此外,即使我手动设置高度(例如,设置为 75)只是为了检查事情看起来是否合理,树看起来就像是被火箭筒射中的金鱼(也就是说,它是一团糟):
如您所见,每行中的文本在树中没有正确对齐。
类似帖子
之前也出现过类似的问题,但是没有解决我的问题(人们通常说要重新实现 sizeHint(),这就是我正在尝试的):
http://www.qtcentre.org/threads/1289-QT4-QTreeView-and-rows-with-multiple-lines
南昌
def sizeHint(self, option, index):
text = index.model().data(index)
document = QtGui.QTextDocument()
document.setHtml(text)
document.setTextWidth(option.rect.width())
return QtCore.QSize(document.idealWidth(), document.size().height())
Run Code Online (Sandbox Code Playgroud) 我正在重构一些使用旧式信号和插槽的代码,它所做的一件事就是将内置信号作为字符串(例如,signalName ="clicked()")传递给另一个实际连接信号和插槽的函数.例如:
self.connect(widget, QtCore.SIGNAL(signalName), slot)
Run Code Online (Sandbox Code Playgroud)
这很好用.问题是,转换为新式信号和插槽(信号不作为参数传递)会使这变得更加复杂.在新型信号和插槽,上面会的东西,如:
widget.[signalName].connect(slot)
Run Code Online (Sandbox Code Playgroud)
哪里[signalName]有用.:)我有很多东西没有使用不工作eval:
widget.signalName.connect(slot) #AttributeError: widget object has no attribute 'signalName'
Run Code Online (Sandbox Code Playgroud)
根据相关帖子:
signalDict={}
signalDict["clicked"]=QtGui.QAbstractButton.clicked
widget.signalDict["clicked"].connect(slot) #AttributeError: widget object has no attribute 'signalDict'
Run Code Online (Sandbox Code Playgroud)
当然有eval,实际上有效:
fullCommand="widget." + signalName + ".connect(slot)"
eval(fullCommand)
Run Code Online (Sandbox Code Playgroud)
但它使用eval,这有点皱眉.有没有更好的方法将这些代码转换为新式信号和插槽,而不使用eval?
请注意原始代码,我试图转换为新式信号和插槽,请访问:https: //github.com/ghosert/VimProject/blob/master/pyqt/book_samples/chap06/imagechanger.pyw
它来自Summerfield关于Qt编程的书的第6章.
相关问题: