PyQt 开始移除行

3 投票
3 回答
3205 浏览
提问于 2025-04-15 19:07

在下面的例子中:

from PyQt4 import QtCore, QtGui

class Ui_Dialog(QtGui.QDialog):

    def __init__(self,parent=None):
        QtGui.QDialog.__init__(self,parent)
        self.setObjectName("Dialog")
        self.resize(600, 500)

        self.model = QtGui.QDirModel()
        self.tree = QtGui.QTreeView()
        self.tree.setModel(self.model)
        print(self.model.flags(self.model.index("c:\Program Files")))
        self.model.setFilter(QtCore.QDir.Dirs|QtCore.QDir.NoDotAndDotDot)

        self.tree.setSortingEnabled(True)

        self.tree.setRootIndex(self.model.index("c:\Program Files"))

        #self.tree.hideColumn(1)
        #self.tree.hideColumn(2)
        #self.tree.hideColumn(3)
        self.tree.setWindowTitle("Dir View")
        self.tree.resize(400, 480)
        self.tree.setColumnWidth(0,200)

        self.tree.show()
        QtCore.QObject.connect(self.tree, QtCore.SIGNAL("clicked(QModelIndex)"), self.test)
        QtCore.QMetaObject.connectSlotsByName(self)

        self.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))

    def test(self,index):

        print(self.model.filePath(index))

        print(self.model.rowCount(index))
         #self.model.beginRemoveRows(index.parent(),index.row(),self.model.rowCount(index))
        #self.model.endRemoveRows()

        print("Row of the index =",index.row())

        print("Parent = ",self.model.data(index.parent()))

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    ui = Ui_Dialog()
    #ui.show()
    sys.exit(app.exec_())

我想在点击某一行的时候,把这一行和它的子项(如果有的话)都删除掉。
(也就是说,点击的文件夹和它下面的内容都要被删除。)

我知道我在这一行代码上犯了错误:

self.model.beginRemoveRows(index.parent(),index.row(),self.model.rowCount(index))

谢谢你的时间。

3 个回答

0

谢谢 jcoon 和 kaleb.. 我已经用 setRowHidden() 这个函数把树形视图中的一行隐藏起来了..

0

Jebagnanadas - 我建议你稍微调整一下设计;不要把用户界面(UI)当作你的模型和视图,而是创建一些独立的对象来表示你在树形视图(TreeView)中的内容,然后更新这些对象,并重新构建或刷新你的树形视图。

你的 test() 方法应该只是从一个成员变量中移除选中的对象,然后调用一个 refresh() 方法(你需要自己写这个方法),这个方法会清空树形视图,并使用更新后的成员变量重新构建它。

这样的设计更好,因为它把用户界面和模型分开了,你不需要担心处理太多的QT方法。

4

我知道我在这一行出错了:

self.model.beginRemoveRows(index.parent(),index.row(),self.model.rowCount(index))

没错,你说得对。我们来看看你传入的内容:

index.parent() - the parent of index
index.row() - the row number of index, the row you want deleted
self.model.rowCount(index) - the number of total children had by index

现在,看看文档中关于 beginRemoveRows 的图片:

你告诉它你想要从 index.row() 开始删除,直到与索引的子项数量相等的行。你搞错了父子索引的对应关系。

你真正想要的是:

beginRemoveRows(index.parent(), index.row(), index.row())

如果你删除 index.row() 这一行,它的所有子项会自动被删除

但是,还有一个更大的问题:beginRemoveRows() 并不会 实际删除任何行。它只是通知你的模型你将要删除行。当你调用 endRemoveRows() 时,模型会通知所有在监听的人,让他们可以正确地重新绘制。

在 C++ 中,你是不能调用 beginRemoveRows() 的,因为这是受保护的方法,只有模型本身可以调用。

要实现你想要的过滤功能,你需要创建一个自定义的代理模型(比如 QSortFilterProxyModel),来完成你想要的过滤。然后你可以在信号处理器中操作这个 QSortFilterProxy 模型。

撰写回答