在QTableView中嵌入控件?

2 投票
3 回答
4618 浏览
提问于 2025-04-15 16:04

我正在做一个小的qt应用程序(使用PyQt4),我有一个想法,但不太确定怎么实现。我有一个QTableView,用来展示一些数据,我想在这个QTableView里加一列,里面放一个复选框控件,这个复选框可以和模型中的某个部分连接起来。比如,像这样:

alt text

注意“删除”这一列每一行都有一个复选框(虽然这是一个网页应用,而不是桌面Qt应用,但原理是一样的)。如果我能选择多行,右键点击,然后选择“选中/取消选中选中的项”,那就更好了。

如果有什么不清楚的地方,请在这里留言,我会进一步解释。

3 个回答

1

在Qt/C++中,你可以为某一列的自定义项目创建一个代理。我想在PyQt中也可以做类似的事情。下面是一些例子:

星星代理示例
旋转框代理示例

4

你可以看看QStandardItemModel,它提供了一种方式,让你可以通过“可检查”的状态来与项目进行互动!

你也可以从QAbstractItemModel继承,并使用Qt::CheckStateRole这个角色...

8

自己实现一个表格模型比使用 QStandardItemModel 要麻烦一些(正如 @Andy 所推荐的),但这样可以让你更好地控制你想要做的事情。所以我会给你总结一下该怎么做。我假设你对 Qt 的文档PyQt 的类文档 都很熟悉,并且能查找你需要的类。(如果你已经有了 QTableView,我可能解释得有点多,但我觉得比遗漏什么要好。)

要实现可勾选的状态:

  • 创建一个 QTableModel 的子类。
    • 选择一种数据结构来存储你的行内容。这可以很简单(比如一个大的内部列表),也可以复杂到像 SQL 数据库那样(如果是这样的话,可以看看 QSqlTableModel)。
    • 重写 rowCountcolumnCountdatasetData
      • rowCountcolumnCount 直接对应于你的数据模型。如果你基本上使用的是一个二维数组(或列表的列表),它们可以非常简单,甚至只需要一行代码。
      • data 是比较有趣的地方。项目模型存储多个不同的字段(Qt 称之为 roles),而 data 返回的内容取决于请求的角色。注意,我会提到返回的数据类型,但它总是需要包装在 QVariant 中。
        • Qt.DisplayRole 是表格单元格中显示的文本。这是你的实际数据,通常是最常见的情况(所以这是默认角色)。
        • Qt.CheckStateRole 是一个布尔值。返回 Qt.Checked 会显示一个勾选的复选框,而 Qt.Unchecked 则会返回一个未勾选的复选框。如果你只想让某一列包含复选框,只需处理这个角色即可。
        • 其他角色对于图标、背景颜色以及其他一些功能也很有用。
        • 任何未处理的角色应该返回一个 QVariant
      • setDatadata 是对称的。你应该处理在 data 中处理的角色:Qt.DisplayRole 用于实际数据,Qt.CheckStateRole 用于复选框。

要允许多行、多列和单元格的选择。为此,你需要了解 选择模型。简而言之:

  • 设置你的表格视图的 选择模式view.setSelectionMode( QAbstractItemView.ContiguousSelection)。这将允许你高亮连续的单元格。你也可以高亮任意单元格:请查看 QAbstractView.SelectionMode
  • 要确定哪些单元格在某个操作后被选中,可以询问表格视图的 选择模型(注意这个 'l'):view.selectionModel().selectedIndexes()。你可以用 for 循环遍历这些索引。

要允许右键点击:

  • 重写你的视图的 contextMenuEvent
  • 创建一个 QMenu 并将其连接到你需要的槽。

如果你还没有的话,可以阅读 Qt 的模型/视图指南,以获得更深入的理解。并且一定要看看 Qt 项目视图示例。其中许多示例在 PyQt 中实现的代码要少得多(包括 @Jesse 提到的两个),而树模型的示例也可以应用到表格中,但工作量要少得多(如上所述,你需要实现的内容要少得多)。

撰写回答