我有一个大的日志数据(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, say Delegate
重新实现 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
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中添加自定义窗口小部件?
发布评论