Reputation: 25463
I have got a QListWidgetItem
, which has a QWidget
and some QLabels
. The height of the labels (imageLabel
, titleLabel
and descriptionLabel
) varies depending on the text length. So does the height of the QWidget, which leds to different sizes in QListWidgetItem
. So far the parameters for setSizeHint
are static:
QListWidgetItem* listWidgetItem = new QListWidgetItem();
listWidgetItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
listWidgetItem->setSizeHint(200, 180));
QWidget* widget = new QWidget();
QVBoxLayout* rootLayout = new QVBoxLayout();
rootLayout->setAlignment(Qt::AlignTop);
QHBoxLayout* contentLayout = new QHBoxLayout();
contentLayout->setAlignment(Qt::AlignLeft);
QLabel* imageLabel = new QLabel();
imageLabel->setPixmap(pixmap);
contentLayout->addWidget(imageLabel, 0, Qt::AlignTop);
QVBoxLayout* informationLayout = new QVBoxLayout();
informationLayout->setAlignment(Qt::AlignTop);
QLabel* titleLabel = new QLabel("<b>" + title + "</b>");
titleLabel->setWordWrap(true);
informationLayout->addWidget(titleLabel);
QLabel* descriptionLabel = new QLabel(description);
descriptionLabel->setWordWrap(true);
informationLayout->addWidget(descriptionLabel);
QLabel* dateLabel = new QLabel(date.toString());
informationLayout->addWidget(dateLabel);
contentLayout->addLayout(informationLayout);
rootLayout->addLayout(contentLayout);
QHBoxLayout* buttonLayout = new QHBoxLayout();
QPushButton* buttonOne = new QPushButton(tr("Button 1"));
QObject::connect(buttonOne, SIGNAL(clicked()), mButtonOneSignalMapper, SLOT(map()));
mButtonOneSignalMapper->setMapping(buttonOne, index);
buttonLayout->addWidget(buttonOne);
QPushButton* buttonTwo = new QPushButton(tr("Button 2"));
QObject::connect(buttonTwo, SIGNAL(clicked()), mButtonTwoSignalMapper, SLOT(map()));
mButtonTwoSignalMapper->setMapping(buttonTwo, index);
buttonLayout->addWidget(buttonTwo);
rootLayout->addLayout(buttonLayout);
widget->setLayout(rootLayout);
mListWidget->addItem(listWidgetItem);
mListWidget->setItemWidget(listWidgetItem, widget);
Is there any way to properly set the sizeHint
regarding the width and height of the displayed content used in the QLabels
of the QWidget
?
For instance the first QListWidgetItem
may have a descriptionLabel
with a text length of 300 characters and the second QListWidgetItem
may have a descriptionLabel
with a text length of 1000 characters. So far both QListWidgetItems
will have the same size (200px width and 180px height). While it may fit on the first QListWidgetItem
, because it has only 300 characters, it may not fit on the second QListWidgetItem
, because of the 1000 characters. Therefore I would like to somehow dynamically adjust the size of the QListWidgetItem
regarding the needed space (first one will need less than the second one).
Upvotes: 6
Views: 4734
Reputation: 305
The way I see it, you won't be able to get a correct bounding rect for the label, unless you know it's future width, so that you can calculate the number of lines required to display the content. And you won't get the width before the layout with the other widgets is calculated.
An alternate approach might be to use an item delegate. Its sizeHint method has an option parameter with a preliminary rect, from which you can use the width and calculate the height with font metrics.
Concerning your other widgets, you could switch to a QTableWidget and put them in other columns..
The following code is not a working example .. just some clues to get you started..
class ItemDelegate : public QStyledItemDelegate
{
public:
void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
painter->save();
QStyledItemDelegate::paint(painter,option,index);
QString title = index.data(Qt::UserRole).toString();
QFont f = option.font;
painter->setFont(f);
QFontMetrics fm(f);
QRect r = option.rect;
// r = r.adjusted(0, fm.lineSpacing(), 0, 0);
painter->drawText(r.left(), r.top(), r.width(), r.height(), Qt::AlignTop|Qt::AlignLeft|Qt::TextWordWrap, title, &r);
painter->restore();
}
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
QFont f = option.font;
QRect r = option.rect;
QFontMetrics fm(f);
QString title = index.data(Qt::UserRole).toString();
QRect br = fm.boundingRect(r,Qt::AlignTop|Qt::AlignLeft | Qt::TextWordWrap,title);
return QSize(option.rect.width(),br.height());
}
};
Hope it helps,
Johannes
Upvotes: 0