是否可以将自定义小部件添加到 QListView 中?

2023-11-26

我有大量日志数据(100、1000、100000...记录),我想通过以下方式将其可视化:

enter image description here enter image description here enter image description here

哪个小部件(例如QListView, QListWidget)我应该使用以及如何使用,以避免性能和内存问题?


是否可以将自定义小部件添加到 QListView 中?

请阅读以下内容:

如何在 Qt C++ 应用程序中将包含大量小部件的可滚动列表显示为项目?


我想以上述格式显示每条日志消息

Solution

为了达到预期的结果并避免性能问题,即使数据日志很长,也可以使用QListView使用自定义委托:

  1. 创建一个子类QStyledItemDelegate, say Delegate

  2. 重新实施QStyledItemDelegate::paint进行自定义绘图的方法

  3. 重新实施QStyledItemDelegate::sizeHint报告列表中项目的正确大小

  4. 通过调用在视图中使用自定义委托QAbstractItemView::setItemDelegate

Example

我为您准备了一个工作示例,以演示如何在应用程序中实施和使用所提出的解决方案。

该示例的基本部分是委托在列表视图中绘制项目的方式:

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

    const QPalette &palette(opt.palette);
    const QRect &rect(opt.rect);
    const QRect &contentRect(rect.adjusted(m_ptr->margins.left(),
                                               m_ptr->margins.top(),
                                               -m_ptr->margins.right(),
                                               -m_ptr->margins.bottom()));
    const bool lastIndex = (index.model()->rowCount() - 1) == index.row();
    const bool hasIcon = !opt.icon.isNull();
    const int bottomEdge = rect.bottom();
    QFont f(opt.font);

    f.setPointSize(m_ptr->timestampFontPointSize(opt.font));

    painter->save();
    painter->setClipping(true);
    painter->setClipRect(rect);
    painter->setFont(opt.font);

    // Draw background
    painter->fillRect(rect, opt.state & QStyle::State_Selected ?
                          palette.highlight().color() :
                          palette.light().color());

    // Draw bottom line
    painter->setPen(lastIndex ? palette.dark().color()
                              : palette.mid().color());
    painter->drawLine(lastIndex ? rect.left() : m_ptr->margins.left(),
                      bottomEdge, rect.right(), bottomEdge);

    // Draw message icon
    if (hasIcon)
        painter->drawPixmap(contentRect.left(), contentRect.top(),
                            opt.icon.pixmap(m_ptr->iconSize));

    // Draw timestamp
    QRect timeStampRect(m_ptr->timestampBox(opt, index));

    timeStampRect.moveTo(m_ptr->margins.left() + m_ptr->iconSize.width()
                         + m_ptr->spacingHorizontal, contentRect.top());

    painter->setFont(f);
    painter->setPen(palette.text().color());
    painter->drawText(timeStampRect, Qt::TextSingleLine,
                      index.data(Qt::UserRole).toString());

    // Draw message text
    QRect messageRect(m_ptr->messageBox(opt));

    messageRect.moveTo(timeStampRect.left(), timeStampRect.bottom()
                       + m_ptr->spacingVertical);

    painter->setFont(opt.font);
    painter->setPen(palette.windowText().color());
    painter->drawText(messageRect, Qt::TextSingleLine, opt.text);

    painter->restore();
}

该示例的完整代码可在GitHub.

Result

正如所写,给定的示例产生以下结果:

Window with a message logger

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以将自定义小部件添加到 QListView 中? 的相关文章

随机推荐