在QWidgetDelegate的paint()方法中为QListView渲染QWidget
我在 QListView 中实现自定义小部件渲染时遇到困难。 我目前有一个 QListView
,显示基于 QAbstractListModel
的名为 PlayQueue
的自定义模型。
这对于简单的文本工作得很好,但现在我想为每个元素显示一个自定义小部件。 因此,我子类化了 QStyledItemDelegate
来实现 paint
方法,如下所示:
void QueueableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
QWidget *widget = new QPushButton("bonjour");
widget->render(painter);
}
选择背景已正确呈现,但没有显示任何小部件。我尝试使用简单的 QPainter 命令(如 Qt 示例中的命令),效果很好:
void QueueableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
if (option.state & QStyle::State_Selected)
painter->setPen(option.palette.highlightedText().color());
painter->setFont(QFont("Arial", 10));
painter->drawText(option.rect, Qt::AlignCenter, "Custom drawing");
}
所以我尝试了一些更改,例如:
- 将
QStyledItemDelegate
更改为QItemDelegate
- 添加
painter->save()
和painter->restore()
围绕渲染 - 将小部件几何形状设置为可用大小
但我现在有点卡住了,我搜索了对于一个在互联网上,但找不到任何执行我想要的操作的示例,他们都谈论编辑小部件(这更容易)或自定义绘制控件(预定义的控件,例如进度条)。 但在这里我真的需要一个我创建的自定义小部件,其中包含一些布局、标签和内容。像素图。 感谢您的帮助!
我在 Ubuntu 11.04 上使用 Qt 4.7.3 for GCC。
i'm having difficulties implementing custom widget rendering in a QListView
.
I currently have a QListView
displaying my custom model called PlayQueue
based on QAbstractListModel
.
This is working fine with simple text, but now I would like to display a custom widget for each element.
So I subclassed a QStyledItemDelegate
to implement the paint
method like this:
void QueueableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
QWidget *widget = new QPushButton("bonjour");
widget->render(painter);
}
The selection background is properly rendered but no widget is displayed. I tried with simple QPainter
commands like in Qt examples, and this is working fine:
void QueueableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
if (option.state & QStyle::State_Selected)
painter->setPen(option.palette.highlightedText().color());
painter->setFont(QFont("Arial", 10));
painter->drawText(option.rect, Qt::AlignCenter, "Custom drawing");
}
So I tried some changes like:
- Changing
QStyledItemDelegate
toQItemDelegate
- Adding
painter->save()
andpainter->restore()
around rendering - Setting the widget geometry to the available size
But i'm a bit stuck now, i searched for a while on the internet, but can't find any example doing what i want, they all talk about editing widget (which is a lot easier) or custom drawn control (predefined ones, like progress bars).
But here I really need a custom widget I created, containing some layout, labels & pixmaps.
Thanks for your help!
I'm using Qt 4.7.3 for GCC on Ubuntu 11.04.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只是为了完成整个图片:进一步可以找到使用委托将 QWidget 作为 QListView 项进行管理的代码。
我终于找到了如何使用其 Paint(...) 方法使其在 QStyledItemDelegate 的子类中工作。
它似乎比以前的解决方案对性能更有效,但是这个语句需要通过调查 setIndexWidget() 对创建的 QWidget 做了什么来验证=)。
最后,这是代码
......
:
Just to complete the whole picture: further one can find the code to manage the QWidget as QListView item using delegates.
I finally found out how to make it work within the subclass of QStyledItemDelegate using its paint(...) method.
It seems more effective for performance than previous solution, but this statement one needs to verify =) by investigation what does setIndexWidget() do with created QWidget.
So finally, here is the code:
.....
.....
好吧,我终于知道如何做我想做的事了。这就是我所做的:
data()
方法中调用QListView::setIndexWidget()
来设置小部件QListView::indexWidget()
进行设置时Qt::SizeHintRole
角色以返回小部件的大小提示Qt::DisplayRole
角色这样我就可以在 QListView 中显示自定义小部件,并且它们可以正确地延迟加载(这就是我使用模型/视图模式的原因)。但我不知道如何在不显示时卸载它们,这是另一个问题。
Ok I finally figured out how to do what I wanted. Here is what I did:
QListView::setIndexWidget()
in thedata()
method of my model to set the widgetQListView::indexWidget()
Qt::SizeHintRole
role to return the widget's size hintQt::DisplayRole
roleThis way I have my custom widgets displayed in the QListView, and they are properly lazy-loaded (that's why i used the model/view pattern). But I don't see how can I unload them when not beeing displayed, well that's another problem.
这里是一个示例。
看来您需要使用 QStylePainter,但这只是为了绘图,据我所知,它的作用并不像真正的按钮。
Here is an example for you.
It seems that you need to use QStylePainter but this is just for drawing as far as I understand it does not act like a real button.