如何在不使用大量CPU的情况下将大量的丰富内容(图像,格式)快速添加到控件中?

时间:2020-03-06 14:52:36  来源:igfitidea点击:

我正在使用wxWidgets和Visual C ++创建类似于在GUI中使用具有丰富格式(颜色,字体,图像)的Unix" tail -f"的功能。我的目标是wxMSW和wxMAC。

明显的答案是将wxTextCtrl与wxTE_RICH一起使用,并使用对wxTextCtrl :: SetDefaultStyle()和wxTextCtrl :: WriteText()的调用。

但是,在以发布模式编译的3ghz工作站上,我无法保持记录每行平均增长1毫秒,最终落在后面的日志。对于每一行,我都会招致:

  • 两次调用SetDefaultStyle()
  • 两次调用两个WriteText()
  • 调用Freeze()和Thaw()小部件

运行此程序时,在填满大约20,000行后,使用wxMSW,我的CPU在一个内核上的使用率达到了100%。一旦达到某个阈值,该程序显然会变慢,从而进一步落后。

我愿意使用其他控件(wxListCtrl,wxRichTextCtrl等)。

解决方案

我们是否考虑过限制视图中的行数?当我们遇到类似的问题时,我们只是确保视图中的行数不会超过10,000。如果底部有更多行,我们将在顶部删除行。这不是使用WxWidgets,而是使用Mac上的本机Cocoa UI,但是问题是相同的。如果样式化的文本视图(带有颜色,格式和漂亮的打印效果)变大,则在底部添加更多数据将变得非常缓慢。

听起来好像我们所使用的控件根本不是针对要向其抛出的数据量构建的。我会考虑建立一个自定义控件。我们可以考虑以下几点:

  • 当出现新行时,我们无需重新渲染以前的行...它们不会更改,布局也不会因新数据而更改。
  • 尝试一次只在内存中保留可见部分以及一些回溯屏幕。这样做会减轻一些负担……但是,如果我们希望用户能够向后滚动而不是向后滚动,并使它们看起来都是无缝的,那么我们将必须执行自己的滚动管理。
  • 不必一次更新一行。当有新数据时,全部捕获并更新。如果我们真的很快得到10行,并且一次更新了所有屏幕,则可以节省逐行执行的一些开销。

希望这可以帮助。

从wxVListBox派生。从文档中:

wxVListBox is a listbox-like control with the following two main differences from a regular listbox: it can have an arbitrarily huge number of items because it doesn't store them itself but uses OnDrawItem() callback to draw them (so it is a Virtual listbox) and its items can have variable height as determined by OnMeasureItem() (so it is also a listbox with the lines of Variable height).