PDA

View Full Version : HTML and QStandardItem ?



alexandernst
28th July 2009, 19:27
I have a QStandardItemModel and some QStandardItems.
I use item.setText(QString("......")) to set the text of the item that I wont.
The problem I have is that I can't set text with html tags. I mean, something like item.setText(QString("<b>" + string + "</b>")).

Is that possible? Thanks

wysota
28th July 2009, 19:43
Not directly. Search the forum for "rich text" and "delegate" for possible solutions.

alexandernst
29th July 2009, 03:43
I should write a delegate for the QTreeView, right? It's the only one with paintEvent. The QStandardItem doesn't have it.

I have searched some things, but without much luck. Maybe this could help me? http://doc.trolltech.com/qq/qq24-delegates.html (it's c++ & qt4) Can you give me some more examples? Thanks

wysota
29th July 2009, 07:39
If you open the search box of the forum and enter "rich text delegate", you'll get some meaningful answers.

alexandernst
30th July 2009, 00:07
Ok, I got the basic. I inherit from QItemDelegate (I want to be able to use icons and so on).
I have one more question. What should I implement? drawDisplay? paint? something more?

edit: What should I inherit from? QItemDelegate or QStyledItemDelegate ? (http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qstyleditemdelegate.html)

I only want to be able to use colored text and icons like this one > :) < in a QStandardItem in a QTreeView.
Something like:

qtv = QTreeView()
d = MyCustomDelegate()
qtv.setDelegate(d)

string = "<b>bold text</b> with image <img src=..........>"
a = QStandardItem()
a.setText(string)

numbat
30th July 2009, 10:39
Learning delegates was on my to-do list so here is a simple implementation.


class Delegate : public QStyledItemDelegate
{
Q_OBJECT

protected:
void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
};


void Delegate::paint(QPainter* painter, const QStyleOptionViewItem & option, const QModelIndex &index) const
{
QStyleOptionViewItemV4 options = option;
initStyleOption(&options, index);

painter->save();

QTextDocument doc;
doc.setHtml(options.text);

/* Call this to get the focus rect and selection background. */
options.text = "";
options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);

/* Draw using our rich text document. */
painter->translate(options.rect.left(), options.rect.top());
QRect clip(0, 0, options.rect.width(), options.rect.height());
doc.drawContents(painter, clip);

painter->restore();
}

QSize Delegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
QStyleOptionViewItemV4 options = option;
initStyleOption(&options, index);

QTextDocument doc;
doc.setHtml(options.text);
doc.setTextWidth(options.rect.width());
return QSize(doc.idealWidth(), doc.size().height());
}


/* Demonstration. */
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QStandardItemModel * model = new QStandardItemModel(2, 1);
model->setData(model->index(0, 0), "<b>Test</b><br />i<img src=\"img.png\" />ng123", Qt::DisplayRole);
model->setData(model->index(1, 0), "<b>Test</b>ing234", Qt::DisplayRole);

QListView * lv = new QListView;
Delegate * delegate = new Delegate;
lv->setModel(model);
lv->setItemDelegate(delegate);

setCentralWidget(lv);
}

alexandernst
31st July 2009, 00:21
Really cool!!! I translated this to python:



class itemDelegate(QStyledItemDelegate):

def paint(self, painter, option, index):
options = QStyleOptionViewItemV4()
options.__init__(option)
self.initStyleOption(options, index)

painter.save()

doc = QTextDocument()
doc.setHtml(options.text)

#get focus rect and selection background
options.text = ""
options.widget.style().drawControl(QStyle.CE_ItemV iewItem, options, painter)

#draw using our rich text document
painter.translate(options.rect.left(), options.rect.top())
rect = QRectF()
rect.__init__(0, 0, options.rect.width(), options.rect.height())
doc.drawContents(painter, rect)

painter.restore()

def sizeHint(self, option, index):
options = QStyleOptionViewItemV4()
options.__init__(option)
self.initStyleOption(options, index)

doc = QTextDocument()
doc.setHtml(options.text)
doc.setTextWidth(options.rect.width())
size = QSize()
size.__init__(doc.idealWidth(), doc.size().height())
return size


But I have one little problem. I dont get the same colors when selected/mouse_over when I'm using my custom delegate and whem I'm using the "default" one. See those 2 pictures if you cant understandme.

Mouse over an item:
http://img82.imageshack.us/img82/1563/notselected.jpg

Item selected:
http://img390.imageshack.us/img390/1056/selectedw.jpg

Do you see the diference between the colors? Why is that happening? Maybe I translated something wrong? Something related with the "options" maybe?


EDIT:

Ok, I have been looking at this and I think that this is a pallete problem. Maybe I should manually set the backgroundBrush ? Something like this:



if option.state & QStyle.MouseOver
if option.state & QStyle.Selected
options.backgroundBrush = DARK-BLUE
else
options.backgroundBrush = LIGHT-BLUE


The problem is that the background color is not the same on every style/SO, so, I cant just force it to use "blue" (the default in qt4 on kde).

Maybe I'm on the wrong way :/ ?

spirit
31st July 2009, 06:39
offtop: I wold create QTextDocument in the heap. :)

alexandernst
1st August 2009, 10:40
Nobody? .

wysota
1st August 2009, 15:28
Will it change anything if you get rid of this line?
self.initStyleOption(options, index)

alexandernst
1st August 2009, 15:40
It wont draw the text, but it will draw the background (with the messed colors).
So, commenting that line is making it worse.

alexandernst
1st August 2009, 20:51
Ok, I know where the problem is! It's here:


QStyleOptionViewItemV4 options = option;

And I translated it this way:



options = QStyleOptionViewItemV4()
options.__init__(option)


So, here is the problem! It's just that I'm doing it wrong. I still don't know how exactly has to be done. I know that the problem is here because if I change the second line of the translated code to this "options = option" then I wont get the text and when I click on the item I wont get the dark-blue color. I'll keep thinking...

alexandernst
2nd August 2009, 02:01
Ok, I got here:



options = QStyleOptionViewItemV4(option)
options.state &= ~QStyle.State_Selected
options.state &= ~QStyle.State_MouseOver


This will make it *almost* work. When mouse is over an item, colors show perfectly, but when I click an item, the left small half of the item (look at pictures in my last post) will be filled with a dark-blue and if the mouse is over the item (once selected) the right big half will be filled with the same color as when mouse is over the item. If the mouse is not over the item once selected, the left half will be filled with the same color as if the mouse is over the item, while the right halft will be white.

This is the stylesheet of the qtreeview:



QTreeView::item:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);
}


QTreeView::item:selected:active{
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6ea1f1, stop: 1 #567dbc);
}

QTreeView::item:selected:!active {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6b9be8, stop: 1 #577fbf);
}

alexandernst
3rd August 2009, 02:01
Could be this the problem:



doc = QTextDocument()
doc.setHtml(options.text)


This will create a QTextDocument, but that element doesnt support StyleSheet, so, it gets colored with the default QStyle.palette colors.

numbat
3rd August 2009, 10:56
It turns out that I left out the last (supposedly optional) argument to drawControl. The line should be:


options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter, options.widget);

which fixes everything on my computer.

alexandernst
3rd August 2009, 11:25
ROFL! xD
This was sooooo annoying :/ I'm really glad that we finally made it =P.
That code was dryving me insane uff...

One more thing, could you tell me if style sheet works for you? I'm trying to draw the items with custom background his way:



QTreeView::item:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);
}

QTreeView::item:selected:active{
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6ea1f1, stop: 1 #567dbc);
}

QTreeView::item:selected:!active {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6b9be8, stop: 1 #577fbf);
}


But I get the default blue/dark-blue when selected or mouse-over.

numbat
4th August 2009, 10:36
I get the following, which is not the default on my machine.

alexandernst
4th August 2009, 10:51
Yeah, I get that too! But I have my own stylesheet and it's not like that, so... What's the problem? Why is not rendering my stylesheet?

alexandernst
4th August 2009, 12:07
Ok, nm... I'm stupid. It was actually showing the stylesheet, but I had the stylesheet almost exactly the same colors as the default (+I'm a little bit daltonic) ...

Really thanks :D I can finally rip xD