QListWidgetItem - 调整宽度和高度以适应内容

6

我有一个 QListWidgetItem,其中包含一个 QWidget 和一些 QLabel。标签的高度(imageLabeltitleLabeldescriptionLabel)根据文本长度而异。这也会导致 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的方式,使其与QWidget中使用的显示内容的宽度和高度相对应?
例如,第一个QListWidgetItem可能具有300个字符的descriptionLabel,而第二个QListWidgetItem可能具有1000个字符的descriptionLabel。到目前为止,这两个QListWidgetItems将具有相同的大小(200px宽度和180px高度)。尽管第一个QListWidgetItem可能适合,因为它只有300个字符,但由于1000个字符,第二个QListWidgetItem可能不适合。因此,我希望能够根据需要的空间动态调整QListWidgetItem的大小(第一个将需要比第二个更少)。

你到底想要实现什么?你知道在 QListWidgetItem 上设置 sizeHint 直到你配置视图的标题栏以实际使用该大小提示时才会生效吗?你需要发布一个自包含的示例,演示问题,并解释你期望发生什么。到目前为止,我不知道还缺少哪些其他代码,以及你真正想要发生什么。你的问题措辞似乎希望所有项目的大小都相同(你抱怨它们不同)。 - Kuba hasn't forgotten Monica
@KubaOber,我已经编辑了我的问题。我希望在“QListWidgetItems”上有不同的大小。 - Niklas
尝试手动设置两个或三个项目的不同大小提示,看看是否有任何影响。然后你就会知道是否需要先做其他事情。 - Kuba hasn't forgotten Monica
当然会受到影响,如果我例如使用listWidgetItem->setSizeHint(200, index % 2 == 0 ? 180 : 360));。我只是不知道每个QLabel需要多少高度/宽度来显示其内容。 - Niklas
很好,因为这不是默认情况 :) - Kuba hasn't forgotten Monica
1个回答

0
在我看来,除非您知道标签的未来宽度以便计算所需显示内容的行数,否则您将无法获得正确的边界矩形。而在其他小部件的布局计算之前,您无法获得宽度。
另一种方法可能是使用项目委托。其sizeHint方法具有一个选项参数和一个初步矩形,您可以从中使用宽度并使用字体度量计算高度。
关于您的其他小部件,您可以切换到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());
    }
};

希望它有所帮助,
约翰内斯

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接