Qt: Item Delegate With Different Height And Width
-
wrote on 4 Feb 2022, 18:39 last edited by
I'm currently working with listview and delegates. For better understanding, please look at the illustration below.
I'm trying to recreate this by using the paint method of the delegate, but I'm stuck at how to size the rectangles in accordance to the texts. The shorter the text is, the rectangle's width will become smaller and vice versa. The same applies with the text's number of lines.
The texts are retrieved from MYSQL database. How do I input the data to the DB? I'm using QTextEdit for that and pass the content (textEdit->toPlainText()) to the DB. In short, it's a QString. However, here comes another problem. I don't know how to determine the number of lines the QString has and if the text is split into three lines as in rectangle 3 (the one which says "Hello Oh Yeah! Great!"), how can I determine the longest sentence/phrase as the point of reference for the rectangle width to be calculated later on?
BTW, I'm still new to Qt's delegates and stuff, so I sincerely ask for the earnest guidance. Thanks.
-
Hi,
The QFontMetrics class comes to mind for that.
See here for a discussion about its use with multi-line text.
-
Hi,
The QFontMetrics class comes to mind for that.
See here for a discussion about its use with multi-line text.
wrote on 5 Feb 2022, 06:28 last edited by@SGaist It doesn't help since I don't know where to implement it. I'm using the
paint
and thesizeHint
method. I don't know where should I use theQFontMetrics
and how to calculate for the width and height. It'll be helpful if you can give me the code example. Thx. -
@SGaist It doesn't help since I don't know where to implement it. I'm using the
paint
and thesizeHint
method. I don't know where should I use theQFontMetrics
and how to calculate for the width and height. It'll be helpful if you can give me the code example. Thx.wrote on 5 Feb 2022, 07:29 last edited by Riko 2 May 2022, 15:18@Riko Ok, I did it somehow with the
paint
method. Here's my code.void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { const QStandardItemModel* model = static_cast<const QStandardItemModel*>(index.model()); QStandardItem* item = model->item(index.row()); QString text = item->text(); QRect rect = option.rect; rect.center(); QColor gray(Qt::gray); QColor white(Qt::white); painter->setRenderHint(QPainter::Antialiasing); painter->setBrush(gray); painter->setPen(white); painter->setFont(font); QRect rectNew = painter->boundingRect(rect, int(Qt::AlignLeft), text).marginsAdded(QMargins(10,10,10,10)); painter->drawRoundedRect(rectNew, 10, 10, Qt::AbsoluteSize); QRect rectNew2 = rectNew.marginsRemoved(QMargins(10,10,10,10)); painter->drawText(rectNew2, int(Qt::AlignLeft), text);} //I don't know why, but to "center" the text to the box drawn, I have to make it like this. } QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { const QStandardItemModel* model = static_cast<const QStandardItemModel*>(index.model()); QStandardItem* item = model->item(index.row()); QString text = item->text(); QRect rect = option.rect; rect.center(); QRect rectNew = option.fontMetrics.boundingRect(rect, 0, text); QSize size = rectNew.size(); return QSize(size); //I think the code here is absurd since I'm just testing things out. }
Now, it's all working quite fine except for something. I don't know where it comes from, but I guess it's from the
sizeHint
method. I don't know how to determine its height, so I just 'yolo-ed' it. Take a look at the screenshot below.The longer the lines, the shorter the spacing becomes. Another thing to consider is that whenever texts of different number of lines are inserted, the spacing becomes "broken" or to say that it becomes overlapping. Where does the problem lay do you think? Thx.
-
There's not need to go through the model, you already have the index and can retrieve the data from it.
You can set the spacing QListView::setSpacing.
1/5