On Monday 15 December 2008, Witteveen, Arnt wrote: > > The recommended way to do any extensive customization of > > items is to create a custom delegate and set it on a > > QListView widget. For simple datasets, you could use a > > QStandardItemModel object to hold the information about the items. > > > > See "An Introduction to Model/View Programming" to get started: > > > > http://doc.trolltech.com/4.4/model-view-introduction.html > > Hi, thanks for that hint, I completely missed that bit somehow at first. > However, implementing a paint function that draws the contents of a > normal QWidget is not as simple as I imagined. And after I get painting > to work, I'd like the widgets to actually *work* as well (I'm looking > for a progress bar, text and a web link and some icons).
Right. That might make things more difficult. It suddenly occurred to me that you could use QListWidget for your view and call setItemWidget() for each item, but you may encounter problems depending on how many widgets you have and how dynamic they are: http://doc.trolltech.com/4.4/qlistwidget.html#setItemWidget > I currently have this (as a test, just draw the same 2 widgets for each > item) put in a QListView: > > GTestDelegate::GTestDelegate() > { > mWidget = new QWidget(); > QHBoxLayout* theLayout = new QHBoxLayout(mWidget); > theLayout->addWidget( new QLabel(tr("a"))); > theLayout->addWidget( new QLabel(tr("b"))); > mWidget->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); > mWidget->adjustSize(); > } > > void > GTestDelegate::paint( QPainter *painter, > const QStyleOptionViewItem &option, > const QModelIndex &index) const > { > mWidget->render(painter, QPoint(), option.rect); > } > > This draws only one line (all on top of eachother?). I'm guessing the > widget render call expects targetOffset and sourceRegion to contain > certain values, but the docs here > http://doc.trolltech.com/4.4/qwidget.html#render-2 don't say anything on > what they expect in these parameters. I'm trying to guess them, but I > don't understand why you would have a separate offset and a drawing > rectangle. I think you would leave sourceRegion as an empty region, which presumably means that the whole widget is rendered, while the targetOffset is the position at which you want to draw the widget in your delegate. > The offset info, if it means what I'm guessing it does, an > offset from some base point, could just as well be in the rectangle, I > would think? It seems to be in the rectangle I get in the 'option' > parameter. Yes, I think that's correct. It's interesting that you are using QWidget::render() to draw widgets in delegates because the "classic" way to do this is to render certain kinds of controls using the QStyle API. > So, even after I get this to work (with some help from this list, I > hope!) a feature request: why can't I draw an item by using QT widgets > out of the box (like I could do for editors, if I read the examples > correctly)? That would be a nice feature. > I'm clearly not the first to do this, see > http://lists.trolltech.com/qt-interest/2006-12/thread00210-0.html . That > thread hints at too many widgets, but since only so may can be on screen > due to screen size, I don't really see the problem. And I'm not quite > sure what the conclusion of that thread was. The attachment to the last > messge doesn't download. I can't access it, either, but the author seemed to conclude that using QStylePainter might be easier. Here's some code snippets for a progress delegate I wrote some time ago - hastily converted to C++ for your benefit: void ProgressDelegate::paint(QPainter *painter, const QStyleOptionViewItem & option, const QModelIndex & index) { QVariant value = index.data(Qt::UserRole); bool ok = false; double percentage = value.toDouble(&ok); QStylePainter stylePainter; stylePainter.begin(painter->device(), parent()); QStyleOptionProgressBarV2 progressOption; progressOption.initFrom(parent()); progressOption.rect = option.rect; progressOption.minimum = 0; progressOption.maximum = 100; progressOption.progress = int(percentage); progressOption.text = index.data(Qt::DisplayRole).toString(); progressOption.textAlignment = Qt::AlignCenter; progressOption.textVisible = true; stylePainter.drawControl(QStyle::CE_ProgressBar, progressOption); stylePainter.end(); } I've removed lots of code, so that's just a basic sketch. You should see http://www.qt-apps.org/content/show.php/?content=52389 for some context. I hope that helps show you how the QStyle API can be used to "draw widgets", though I realise that some experimentation may be necessary to get the desired look and feel. David -- David Boddie Senior Technical Writer Nokia, Qt Software _______________________________________________ Qt4-preview-feedback mailing list [email protected] http://lists.trolltech.com/mailman/listinfo/qt4-preview-feedback
