簡體   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