2011-03-03 40 views
4

问题:我想在视图中显示一个简单的QStringListModel。但是,我希望视图中的每个项目都是我创建的自定义QWidget。我不明白为什么这是一个很难的问题!我已经在互联网上寻找解决方案,尽管我在这里和那里发现了点点滴滴,但没有一个好的解决方案可以满足我的所有需求。在Qt视图中使用QWidget

设立我的模型/视图的基本代码:

 

QStringList strings; 
// add some strings to the model 

QStringListModel* model = new QStringListModel(strings); 
QListView* view = new QListView; 

view->setModel(model); 

 

我已经在这样做无济于事尝试过各种尝试。

尝试#1

我试着子类新QItemDelegate对象。在这个对象中,我重写了创建编辑器的方法。我遵循了设置该代表的所有步骤。问题是,当模型填充视图时,当我需要抓取Qt :: EditRole中的每个项目时,它会抓取模型中的每个项目在Qt :: DisplayRole中。

尝试#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),但是什么也没做。我希望我的列表视图具有透明背景。

对此问题的任何反馈意见将大大大大赞赏。我花了很多时间试图让这个工作!谢谢!

+1

的涂料代码因此,关于尝试#2,我修复了背景问题。在我的CustomListView构造函数中,我调用了viewport() - > setAutoFillBackground(false)。我仍然喜欢这些方法或其他可能适用于这个问题的想法。 – Chris 2011-03-03 19:04:44

+0

我认为你应该坚持代表。你也应该发布你的setEditorData()和setModelData()函数的源代码。 – zkunov 2011-03-03 19:43:38

+0

不幸的是,我不能让我的列表中的所有项目都处于EditMode中,并使用委托中的createEditor()返回的QWidget。似乎一次只能有一个项目处于该模式。 – Chris 2011-03-03 21:14:53

回答

0

我想我在QStandardItemModel中呈现自定义数据的问题类似。我所做的解决它是创建一个自定义的QStyledItemDelegate。 在createEditor方法,你可以测试:

if(qVariantCanConvert<YourObject>(index.data(Qt::YourRole))) 

然后创建您的编辑器,实际上是你想要的自定义部件。并用您的模型中的数据设置其值。 要定制我的小部件,我使用了像CustomWidget.setStylesheet(“background:blue”);

在委托的绘制方法中,如果您想要使用相同的窗口小部件,您完全可以像编辑器一样进行绘制。

CustomWidget renderer; 
renderer.setText(index.data(Qt::DisplayRole).toString()); 
renderer.resize(option.rect.size()); 
painter->save(); 
painter->translate(option.rect.topLeft()); 
renderer.render(painter); 
painter->restore(); 

你必须自己处理openPersistentEditor和closePersistentEditor。

希望它会有所帮助。

0

我的建议是坚持使用自定义绘画的代表。

请参阅Star Delegate Example像这样,您可以按照自己想要的方式绘制(请参见下文),然后在获得焦点时使用createEditor进行编辑。

void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, 
          const QModelIndex &index) const 
{ 
    if (qVariantCanConvert<StarRating>(index.data())) { 
     StarRating starRating = qVariantValue<StarRating>(index.data()); 

     if (option.state & QStyle::State_Selected) 
      painter->fillRect(option.rect, option.palette.highlight()); 

     starRating.paint(painter, option.rect, option.palette, 
          StarRating::ReadOnly); 
    } else { 
     QStyledItemDelegate::paint(painter, option, index); 
    } 
} 

渔获或欺骗是,你可以画你的小部件,而无需创建一个编辑器实例或使用drawControl()具有编辑模式你的widget。请参阅this question.