【问题标题】:QTableView item selection based on a QStandardItem data attribute基于 QStandardItem 数据属性的 QTableView 项目选择
【发布时间】:2012-05-12 21:09:55
【问题描述】:

QTableView 中进行任意多选的最有效和技术上(Python/PyQt4)正确的方法是什么,该模型包含@987654321 的层次结构@(图表数据),每个项目都添加了自定义 isSelected 数据属性。

详细信息:除了表格,我还有一个 matplotlib 图,它输出与我的QTableView 数据相对应的范围(isSelected 属性直接来自这些范围),我想在这两个 gui 之间添加一些交互元素。

即 matplotlib 绘图选择反映在 QTableView 中,反之亦然(我通过将选择更改连接到读取相应索引并将它们反馈回图表来获得)。

希望这个解释是有道理的。谢谢。

【问题讨论】:

    标签: python pyqt selection qtableview qstandarditemmodel


    【解决方案1】:

    正如你所说,现在你有你的 QTableView.selectionChanged() 将选择反馈给你的 matplot。最有效的方法是让您的 matplot 发出信号以供其选择,以及相关项目。

    表格视图已经将其选择存储在 QItemSelectionModel 中,因此据我所知,在项目上存储您自己的 isSelected 属性是多余且不必要的。您的 matplot 视图应该知道它正在使用的项目,并且应该能够通知表视图其选择更改。

    您的 matplot 视图可以有一个您发出的信号,例如 selectionChanged(items),并且可以继续不知道表格视图。

    您的表格视图,因为它已经知道 matplot 视图,可以将其selectionChanged(items) 连接到 matplot 并监听选择更改。即使您的表也在发出信号并且不了解 matplot,您也可以在任何父类中都知道它们的任何父类中建立连接。

    这就是我认为不需要该属性的原因:使用该属性的唯一方法是扫描整个模型,检查每个项目。那不是很有效。选择应根据发出的信号进行。

    myMatPlotView.selectionchanged.connect(myTableView.matplotSelected)
    

    并且在您的matPlotSelected() 插槽中,您可以使用选择模型来设置项目选择:

    表格视图

    def matPlotSelected(self, qStandardItems):
    
        selModel = self.selectionModel()
        model = self.model()
    
        for item in qStandardItems:
            idx = model.indexFromItem(item)
            selModel.select(idx, selModel.Select)
    

    更新

    在 cmets 中,您提供了一个代码 sn-p,它确实有助于隔离您想要实现的目标。

    你的例子

    def __init__(self):
        super(myDialog, self).__init__()
        self.t = QtGui.QTreeView()
        self.m = QtGui.QStandardItemModel()
        self.t.setModel(self.m)
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.t)
        self.setLayout(layout)
        self.l = [
            ['one', False], ['two', True], 
            ['three', False], ['four', True], 
            ['five', False]]
        self.populate()
    
    def populate(self):
        self.m.clear()
        root = self.m.invisibleRootItem()
        for item in self.l:
            e = QtGui.QStandardItem()
            e.setText(item[0])
            root.appendRow(e)
    

    如果这是你的实际情况,那么我上面的建议是这样的:

    def populate(self):
        self.m.clear()
        root = self.m.invisibleRootItem()
        selModel = self.t.selectionModel()
        for item in self.l:
            e = QtGui.QStandardItem()
            e.setText(item[0])
            root.appendRow(e)
    
            if item[1]:
                idx = self.m.indexFromItem(e)
                selModel.select(idx, selModel.Select)
    

    【讨论】:

    • 这就是我想澄清的实际问题。据我所知,有两种可能的选择。首先,我为setSelection() 提供了一个QRect 区域(这与我的情况无关),或者,其次,我为我的QTreeView's selectionModel() 提供QModelIndexes,但除非我遍历所有模型,否则我不知道这些索引元素来识别它们。问题是如何仅为我想要选择的那些“标记”项目获取模型索引。
    • @decuman:我们之间可能在您的真正问题上存在分歧。我刚刚更新了我的示例以展示如何将项目转换为索引。这能解决问题吗?您的 matplotview 应该已经知道这些项目并在信号中发送它们。
    • 抱歉混淆:以更简短和抽象的方式:有一个数据数组(一个列表),其中一些元素标记为“已选择”,它填充了一个分层的QStandarItemModel。如何在 QTreeView 初始化时让那些标记为“已选择”的项目被选中?
    • @decuman:在我看来,您似乎在绕开同一个问题。选择是相同的,无论它发生在 TreeView 的 init 内还是在稍后触发的插槽中。无论您在哪里填充模型,您都将拥有这些项目,并且您可以检查它们的“isSelected”属性。您只需使用上面列出的选择方法。您想知道如何过滤该数据列表吗?是的……我很困惑。
    • 是的。可能我的情况与过滤数据有关。这是一个快速代码 sn-p CODE。我想在 QTableView init 上选择一个包含 True/False 选择状态的列表。
    猜你喜欢
    • 2020-10-28
    • 2013-07-24
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 1970-01-01
    相关资源
    最近更新 更多