是否可以在QListView中添加自定义窗口小部件? [英] Is it possible to add a custom widget into a QListView?
问题描述
我有一个大的日志数据(100、1000、100000,...条记录),我想通过以下方式对其进行可视化:
I have a large log data (100, 1000, 100000, ... records) and I want to visualize it in the following manner:
为了避免性能和内存问题,我应该使用哪个小部件(例如QListView
,QListWidget
)?
Which widget (e.g. QListView
, QListWidget
) should I use and how, in order to stay away from performance and memory problems?
推荐答案
是否可以在QListView中添加自定义窗口小部件?
Is it possible to add a custom widget into a QListView?
请阅读以下内容:
如何在Qt C ++应用程序中将包含大量小部件的可滚动列表显示为项目?
我想以上述格式显示每条日志消息
I want to show every log message in the above format
解决方案
要获得理想的结果并避免出现性能问题,即使数据日志很长,也可以使用 QListView
,带有自定义委托:
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:
-
创建
QStyledItemDelegate
的子类,例如
Create a subclass of
QStyledItemDelegate
, sayDelegate
重新实现 QStyledItemDelegate::paint
方法来执行自定义图纸
Reimplement the QStyledItemDelegate::paint
method to do the custom drawing
重新实现 QStyledItemDelegate::sizeHint
以报告正确的内容列表中项目的大小
Reimplement the QStyledItemDelegate::sizeHint
to report the correct size of the items in the list
通过调用 QAbstractItemView::setItemDelegate
<在视图中使用自定义委托/a>
Use the custom delegate in the view by calling 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();
}
该示例的完整代码可在 GitHub 上找到.
The complete code of the example is available on GitHub.
如所写,给定的示例将产生以下结果:
As written, the given example produces the following result:
这篇关于是否可以在QListView中添加自定义窗口小部件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!