是否可以在QListView中添加自定义窗口小部件?

时间:2018-11-01 16:24:21

标签: qt qlistview

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

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

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

1 个答案:

答案 0 :(得分:1)

  

是否可以在QListView中添加自定义窗口小部件?

请阅读以下内容:

How to display a scrollable list with a substantial amount of widgets as items in a Qt C++ app?


  

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

解决方案

要获得理想的结果并避免性能问题,即使数据日志很长,请使用带有自定义委托的QListView

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

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

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

  4. 通过调用QAbstractItemView::setItemDelegate

  5. 在视图中使用自定义委托

示例

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

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

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

结果

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

Window with a message logger