QListWidgetItem — настроить ширину и высоту для содержимого

у меня есть QListWidgetItem, который имеет QWidget и немного QLabels, Высота надписей (imageLabel, titleLabel а также descriptionLabel) варьируется в зависимости от длины текста. Так же как и высота QWidget, которая приводит к различным размерам в QListWidgetItem, Пока что параметры для setSizeHint статичны:

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);

Есть ли способ правильно установить sizeHint относительно ширины и высоты отображаемого содержимого, используемого в QLabels из QWidget?

Например первый QListWidgetItem может иметь descriptionLabel с длиной текста 300 символов и второй QListWidgetItem может иметь descriptionLabel с длиной текста 1000 символов. Пока что оба QListWidgetItems будет иметь одинаковый размер (ширина 200 пикселей и высота 180 пикселей). В то время как это может соответствовать первому QListWidgetItem, потому что он имеет только 300 символов, он может не уместиться на втором QListWidgetItemиз-за 1000 символов. Поэтому я хотел бы как-то динамически регулировать размер QListWidgetItem относительно необходимого места (первому понадобится меньше, чем второму).

5

Решение

На мой взгляд, вы не сможете получить правильный ограничительный прямоугольник для метки, если не будете знать, какая это ширина в будущем, чтобы можно было рассчитать количество строк, необходимое для отображения содержимого. И вы не получите ширину, пока не будет рассчитан макет с другими виджетами.

Альтернативный подход может заключаться в использовании делегата элемента. Его метод sizeHint имеет параметр option с предварительным прямоугольником, из которого вы можете использовать ширину и вычислять высоту с помощью метрик шрифта.

Что касается других ваших виджетов, вы можете переключиться на QTableWidget и поместить их в другие столбцы.

Следующий код не является рабочим примером … просто некоторые подсказки, чтобы вы начали ..

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());
}
};

Надеюсь, поможет,

Johannes

0

Другие решения


По вопросам рекламы [email protected]