简体   繁体   English

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

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

I have a large log data (100, 1000, 100000, ... records) and I want to visualize it in the following manner:我有一个很大的日志数据(100、1000、100000、...记录),我想以下列方式将其可视化:

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

Which widget (eg QListView , QListWidget ) should I use and how, in order to stay away from performance and memory problems?我应该使用哪个小部件(例如QListViewQListWidget )以及如何使用,以避免性能和内存问题?

Is it possible to add a custom widget into a QListView?是否可以将自定义小部件添加到 QListView 中?

Please, read about:请阅读:

How to display a scrollable list with a substantial amount of widgets as items in a Qt C++ app?如何在 Qt C++ 应用程序中显示包含大量小部件的可滚动列表作为项目?


I want to show every log message in the above format我想以上述格式显示每条日志消息

Solution解决方案

To achieve the desired result and stay away from performance issues, even with a very long data log, use a QListView with a custom delegate:为了达到预期的结果并远离性能问题,即使数据日志很长,也可以使用带有自定义委托的QListView

  1. Create a subclass of QStyledItemDelegate , say Delegate创建QStyledItemDelegate的子类,比如Delegate

  2. Reimplement the QStyledItemDelegate::paint method to do the custom drawing重新实现QStyledItemDelegate::paint方法来进行自定义绘图

  3. Reimplement the QStyledItemDelegate::sizeHint to report the correct size of the items in the list重新实现QStyledItemDelegate::sizeHint以报告列表中项目的正确大小

  4. Use the custom delegate in the view by calling QAbstractItemView::setItemDelegate通过调用QAbstractItemView::setItemDelegate在视图中使用自定义委托

Example例子

I have prepared a working example for you in order to demonstrate how the proposed solution could be implemented and used in an application.我为您准备了一个工作示例,以演示如何在应用程序中实施和使用建议的解决方案。

The essential part of the example is the way the delegate paints the items in the list view:该示例的基本部分是委托在列表视图中绘制项目的方式:

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

The complete code of the example is available on GitHub .该示例的完整代码可在GitHub找到

Result结果

As written, the given example produces the following result:如所写,给定的示例产生以下结果:

带有消息记录器的窗口

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

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