[英]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?我应该使用哪个小部件(例如
QListView
、 QListWidget
)以及如何使用,以避免性能和内存问题?
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
我想以上述格式显示每条日志消息
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
:
Create a subclass of QStyledItemDelegate
, say Delegate
创建
QStyledItemDelegate
的子类,比如Delegate
Reimplement the QStyledItemDelegate::paint
method to do the custom drawing重新实现
QStyledItemDelegate::paint
方法来进行自定义绘图
Reimplement the QStyledItemDelegate::sizeHint
to report the correct size of the items in the list重新实现
QStyledItemDelegate::sizeHint
以报告列表中项目的正确大小
Use the custom delegate in the view by calling QAbstractItemView::setItemDelegate
通过调用
QAbstractItemView::setItemDelegate
在视图中使用自定义委托
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上找到。
As written, the given example produces the following result:如所写,给定的示例产生以下结果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.