【发布时间】:2011-03-03 18:32:58
【问题描述】:
问题:我想在视图中显示一个简单的 QStringListModel。但是,我希望视图中的每个项目都是我创建的自定义 QWidget。我不明白为什么这是一个如此困难的问题!我已经在互联网上搜索了解决方案,虽然我在这里和那里找到了一些零碎的东西,但没有一个好的解决方案可以满足我的所有需求。
设置我的模型/视图的基本代码:
QStringList strings;
// add some strings to the model
QStringListModel* model = new QStringListModel(strings);
QListView* view = new QListView;
view->setModel(model);
我已经尝试了各种尝试,但都无济于事。
尝试 #1
我尝试子类化一个新的 QItemDelegate 对象。在这个对象中,我覆盖了创建编辑器的方法。我遵循了设置该委托的所有步骤。问题是当视图填充模型时,它会在 Qt::DisplayRole 中抓取模型中的每个项目,而我需要它来抓取 Qt::EditRole 中的每个项目。
尝试 #2
我尝试的另一种方法是继承 QListView,并覆盖 setModel 方法以为模型中的每个项目调用 setIndexWidget。我的代码看起来像这样:
void CustomListView::setModel(QAbstractItemModel* model)
{
QListView::setModel(model);
for (int i = 0; i rowCount(); ++i)
{
QModelIndex index = model->index(i, 0);
CustomWidget* widget = new CustomWidget;
setIndexWidget(index, widget);
}
}
这可以将我的 CustomWidget 对象添加到列表视图中的每一行。为了确保常规模型数据也不会显示在我的 CustomWidget 对象下方,我还覆盖了 CustomListView::paintEvent(QPaintEvent* event) 什么都不做。再次,这奏效了。
但我现在的主要问题是,当列表显示时,虽然我的 CustomWidgets 显示正确,但列表的背景是纯白色。我尝试在 CustomListView 上调用 setAutoFillBackground(false) 但什么也没做。我希望我的列表视图具有透明背景。
我们将非常感谢对此问题的任何反馈。我花了很多时间试图让它工作!谢谢!
【问题讨论】:
-
所以,关于尝试 #2,我修复了背景问题。在我的 CustomListView 构造函数中,我调用了 viewport()->setAutoFillBackground(false)。对于这些方法或其他可能解决此问题的想法,我仍然很乐意提供更多反馈。
-
我认为你应该坚持代表。您还应该发布 setEditorData() 和 setModelData() 函数的来源。
-
不幸的是,我无法使列表中的所有项目都处于 EditMode 并使用委托中的 createEditor() 返回的 QWidget。似乎一次只能有一个项目处于该模式。
-
关于您对尝试 #2 的第一条评论,setItemWidget 的 qt 文档说:
The given widget's autoFillBackground property must be set to true, otherwise the widget's background will be transparent, showing both the model data and the item at the given index.所以您可能想尝试一下,而不是您所做的,这似乎是相反的。使用自定义委托似乎更自然。但是,当您已经有一个可以完成这项工作的自定义小部件时,必须重新实现 paint() 有点痛苦。能否以某种方式“劫持”您的小部件的绘制方法并在委托中使用它?