繁体   English   中英

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

[英]Is it possible to add a custom widget into a QListView?

我有一个很大的日志数据(100、1000、100000、...记录),我想以下列方式将其可视化:

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

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

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

请阅读:

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


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

解决方案

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

  1. 创建QStyledItemDelegate的子类,比如Delegate

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

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

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

例子

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

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

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找到

结果

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

带有消息记录器的窗口

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM