如何在 Delphi 中显示格式化(颜色、样式等)日志?
我需要在 Delphi 2009 中显示格式化日志。格式化不必实现 html 的所有功能,而是实现一小部分功能,例如颜色、字体样式等。
目前我正在使用 TRichEdit 和我自己的专有标签,例如这是蓝色的。 让它与 TRichEdit 一起工作是相当复杂的,因为无法直接访问 RTF 文本。 例如,要将文本着色为蓝色,我必须:
- 解析附加文本,提取标签,找出需要格式化的文本以及如何格式化。
- 选择文本。
- 应用格式设置。
- 取消选择文本并将所选内容移至文本末尾,为下一次追加做好准备。
所有这些都是很麻烦且缓慢的。 您是否知道使用 TRichEdit 或其他更适合这项工作的控件更好(更快)的方法?
我应该提到我已经考虑过在 TWebBrowser 中使用 HTML。 这种方法的问题是日志的长度可以是 1 到 100000 行。 如果我使用普通的 html 查看器,我每次都需要设置整个文本,而不是简单地附加它。
此外,当我向日志中添加行时,日志需要实时更新。 不仅仅是从文件中读取并显示一次。
I need to display a formatted log in Delphi 2009. The formatting does not have to implement all the features of say html, but a small subset e.g. colour, font style etc.
Currently I am using a TRichEdit and my own proprietry tags e.g. this is blue. It is pretty convoluted to get this to work with a TRichEdit as there is no direct access to the RTF text. For example, to colour the text blue I have to:
- Parse the appended text extracting the tags, figuring out what text needs to be formatted and how.
- Select the text.
- Apply the formatting.
- Deselect the text and move the selection to the end of the text ready for the next append.
All this is hacky and slow. Do you know of a better (faster) way to do this with TRichEdit or another control that is better suited to the job?
I should mention that I have considered using HTML in a TWebBrowser. The problem with this approach is that the log can be anywhere from 1 to 100000 lines long. If I use a normal html viewer I need to set the entire text each time rather than simply appending it.
Additionally, the log needs to be updated in real time as I append lines to it. Not simply read from a file and displayed once.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
简单的解决方案:使用带有自定义绘制方法的 TListBox,并使用仅包含基本信息而不是格式的对象将日志条目放入 TObjectList 中(这将在演示代码中应用)。
或者使用虚拟字符串列表/ VirtualTreeView 组件。 仅渲染需要显示的项目,这将节省资源。
Simple solution: use a TListBox with custom draw methods, and put the log entries in an TObjectList using objects which only contain the basic information, not the formatting (this will be applied in the presentation code).
Or use a Virtual String List / VirtualTreeView component. Only the items which need to be displayed will be rendered, this will save resources.
假设你的日志有 1,000,000 行长,你可以忘记使用 HTML 或 RTF,最干净的解决方案(我处理 100-1,000,000 行)是使用(正如 mjustin 建议的那样)一个 TListBox ,以
因为您一次只会查看几个条目,所以“按需解析”方法明显更好,因为当您尝试解析所有百万行时,加载时不会“减慢”。
不知道您的实际问题,我只能说,根据我的经验,这是一项一旦学习和掌握的技术,在大多数面向数据的应用程序中都是有用的。
增强功能包括在列表框上方附加一个标题控件(我将它们包装在一个面板中),您可以创建一个高级的 TListView 控件。 将一些排序逻辑附加到标题控件上的单击事件,您可以对对象列表进行排序,您所要做的就是调用 ListBox.Invalidate 来刷新视图(如果可以的话)。
++ 用于实时更新。 我现在这样做是为了触发计时器事件来调整 ListBox.Count 因为您不想每秒更新列表框 1000 次..:-)
Assuming your log is 1,000,000 lines long you can forget using HTML or RTF, the cleanest solution (and I handle 100-1,000,000)is to use (as mjustin suggests) a TListBox with
Because you will only be viewing a few entries at a time, the "on demand parsing" approach is significantly better as there is no "slow down" at load time as you try to parse all million lines.
Not knowing your actual problem I can just say that in my experience this is a technique that once learned and mastered is useful in most data oriented application.
Enhancements include attacheing a header control above the list box (I wrap them together in a panel) and you can create a superior TListView Control. Attach a bit of sort logic to the click event on the header control and you can sort your object list and all you have to do is call ListBox.Invalidate to refresh the view (when it can).
++ For realtime updating. I do this at the moment, is to trigger a timer event to adjust the ListBox.Count as you don't want to update the listbox 1000 times a second.. :-)
如果您决定按照建议使用 TListbox,请确保允许您的用户将他们正在查看的行的详细信息复制到剪贴板。 没有什么比无法从日志中复制行更糟糕的了。
if you decide to use a TListbox as suggested, please make sure you allow your users to copy details of line they are viewing to clipboard. There is nothing worse than not being able to copy lines from a log.
您可能想要购买 Delphi 的词法扫描器或源代码/语法突出显示组件。 有很多可供选择,而且大多数都不是很贵。 就您的情况而言,您需要测试一些并找到一个足以满足您需求的有效方法。
一些示例是:
MBLabSoft 的源代码扫描仪
语法高亮组件 - 列出SynEdit(打开源)、Scintilla、Tsyncontrol 和其他一些
Serhiy Perevoznyk 的 RichEdit 语法荧光笔
为了提高突出显示非常大的日志文件的效率,请查看专门的内容突出显示文本文件。 他们应该非常快。 但 RichEdit 也确实不逊色。
You might want to purchase a lexical scanner or source code / syntax highlighter component for Delphi. There are many available and most are not very expensive. In your case, you'll want to test a few and find one that's efficient enough for your needs.
A few examples are:
Source Code Scanners by MBLabSoft
Syntax Highlighting components - listing SynEdit (open source), Scintilla, Tsyncontrol and a few others
RichEdit Syntax Highlighter by Serhiy Perevoznyk
For efficiency in highlighting a very large log file, look at the ones that specialize in highlighting text files. They should be extremely fast. But RichEdit is really no slouch either.
对于那些感兴趣的人,这是我最终使用的代码。 如果将其附加到 TVirtualStringTree 的 OnAfterCellPaint 事件,它将给出所需的结果。
For those that are interested, here's the code that I ended up using. If you attach this to the OnAfterCellPaint event of a TVirtualStringTree it gives the desired results.
我猜您想显示现有的纯文本日志,但要对其应用颜色?
我能想到的有以下几种选择:
如果您是自己编写日志,您也可以首先使用 TRichEdit 生成 RTF 格式的日志。 或者,您可以生成 HTML 或 XML 格式的日志(然后可以使用 XSLT 将其转换为您喜欢的任何内容)。
I gather you want to show an existing plain-text log, but apply colours to it?
Here's a few options I can think of:
If you're writing the log yourself, you could also use a TRichEdit to generate the log in RTF in the first place. Or you can generate the log in HTML, or in XML (which can then be transformed into whatever you like, using XSLT).