Which methods should be overloaded to modify text format and image postion in cells of QTableView?
-
I got 3 questions while using QTableView.
I'm trying to display text with several colors and fonts in a cell of QTableView. I think just returning DisplayRole's QVarient from TableModel::data() method cannot do that. I tried to draw text in the method paintEvent() but it was not easy because paintEvent() doesn't have enough information to draw text for a specific cell. Is there any easy way to modify text for cells?
I want to draw images at the center of cells but I don't know how to set the alignments of these images.
When scrolling QTableView, the scrolling is not smooth. the view moves by a cell per every movement. I want it to be scrolled smoothly pixel by pixel. Can I do it?
Thanks,
-
-
Write a custom delegate. See the "Model/View programming":http://doc.qt.nokia.com/latest/model-view-programming.html documentation for that.
-
Don't have the answer off the top of my head.
-
This is a cooperation between the scroll bars having a certain step size and the view interpreting the step size in displayed items, rather than pixels. Of course you can do it, but it is a lot of work and I wonder if it would be worth the trouble.
-
-
Is it an option to modify your model to return additional roles? The color of the text, the font and the alignment can all be specified using a role. Otherwise, you might considder creating a proxy model (subclass QSortFilterProxyModel and reimplement the data() function to return the data for the relevant styling roles directly, and return the data from the underlying model for any other roles.) I think that even though this solution is not as nice in terms of separation of concerns, it is much easier to implement than using a custom delegate.
Your third question can be solved by looking at the documentation for QAbstractItemView (the baseclass of QTableView) again. Note that the scrollMode can be set for both the vertical and the horizontal direction separately.
-
[quote author="Andre" date="1304053855"]Your third question can be solved by looking at the documentation for QAbstractItemView (the baseclass of QTableView) again. Note that the scrollMode can be set for both the vertical and the horizontal direction separately.[/quote]The one part of the docs I didn't look into :P.
There was something that hinted me towards using delegates. Even though you can provide the additional roles in your model, they are considered hints. If you really want to change the appearance of the items, you need to implement the delegate.
-
[quote author="Andre" date="1304053855"]Is it an option to modify your model to return additional roles? [/quote]
I think I cannot use additional roles such as Qt::FontRole and Qt::TextColorRole because my cells need to display multi lined string with several colors and fonts in a cell. (Each cell consists with several lines, and each line has unique color and font size). Thus I'll try subclassing QSortFilterProxyModel and re-implementing the data() function.
I'll report my result soon!And, thank you very much for useful informations including "QAbstractItemView::ScrollPerPixel".
-
If you need the functionality above, you're not going to be able do that with the color roles. Sorry, I guess I did not read your opening post very carefully or I would have spotted that earlier.
You will need to implement a delegate that can render rich text. I have made such a delegate, but it is not trivial. Also, I found it was basically impossible to build it on top of QStyledItemDelegate. There is a "wish in the bugtracker":http://bugreports.qt.nokia.com/browse/QTBUG-14200 for supporting rendering rich text in item views, but it is not getting much priority.
-
I've just made my QTableView display html text by subclassing QStyledItemDelegate.
below code works fine.
@void MyItemDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{switch(index.column()) { case HTML_COLUMN: { painter->save(); QTextBrowser browser; browser.setLineWrapMode(QTextBrowser::NoWrap); browser.setHtml(index.data().value<QString>()); QAbstractTextDocumentLayout::PaintContext context; QRect rect = option.rect; browser.document()->setPageSize( rect.size()); painter->translate(rect.x(),rect.y()); browser.document()->documentLayout()->draw(painter, context); painter->restore(); } break; case NORMAL_COLUMN: default: QStyledItemDelegate::paint(painter, option, index); break; }
}@
-
[quote author="Andre" date="1304083699"]I'm sure it does, but:
- Creating a QTextBrowser for each paint operation is not very efficient
- You are not getting a cell to highlight this way.
[/quote]
Yes, to show highlighted background, I added some more code like blow,
@ if (option.state&QStyle::State_Selected)
{
QStyleOptionViewItem style;
style.rect = option.rect;
style.showDecorationSelected = option.showDecorationSelected;
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &style, painter);
}@and for the efficiency, I'm thinking of reusing QTextBrowser object by defining it as a member variable of the class.
Thanks.
-
Sorry, above code has a problem.
The correct code is here.@ if (option.state&QStyle::State_Selected)
{
QStyleOptionViewItemV4 style = option;
initStyleOption(&style, index);
style.text = "";
style.widget->style()->drawControl(QStyle::CE_ItemViewItem, &style, painter);
}
else
{
QBrush brush(index.data(Qt::BackgroundRole).value<QBrush>());
painter->fillRect(rect, brush);
}@