【发布时间】:2009-02-12 17:10:39
【问题描述】:
使用 Cocoa 组件显示不断更新的日志输出的最佳方式是什么?输出是基于行的,由应用程序生成。追加行应该很快,并且视图应该自动滚动到底部。总而言之,它应该可以工作并且看起来像终端中的基本标准。
我的代码是用 Python 编写的,使用 PyObjC 桥接器。我正在寻找可以适应的方法/示例,欢迎使用 Objective-C 代码。
【问题讨论】:
使用 Cocoa 组件显示不断更新的日志输出的最佳方式是什么?输出是基于行的,由应用程序生成。追加行应该很快,并且视图应该自动滚动到底部。总而言之,它应该可以工作并且看起来像终端中的基本标准。
我的代码是用 Python 编写的,使用 PyObjC 桥接器。我正在寻找可以适应的方法/示例,欢迎使用 Objective-C 代码。
【问题讨论】:
似乎有两种选择:(1)使用 NSTableView 和(2)使用 NSTextView。 Console.app 似乎使用 NSTableView 但 NSTextView 的代码可能更少。
对于 (1),我将编写一个 NSTableDataSource,它返回 tableView_objectValueForTableColumn_rowIndex_ 的相应行(从内存或磁盘)和 numberOfRowsInTableView_ 的日志行总数。将此数据源设置为 NSTableView 的数据源。当新的日志行进入时,您可能需要调用tableView.reloadData() 重新显示数据。假设表格视图嵌入在 NSScrollView 中(如果您在 Interface Builder 中创建表格视图,则默认为),您可以滚动到底部Apple Scroll View Programming Guide 中的这个方法(很容易翻译成 Python)
- (void)scrollToBottom:sender;
{
NSPoint newScrollOrigin;
// assume that the scrollview is an existing variable
if ([[scrollview documentView] isFlipped]) {
newScrollOrigin=NSMakePoint(0.0,NSMaxY([[scrollview documentView] frame])
-NSHeight([[scrollview contentView] bounds]));
} else {
newScrollOrigin=NSMakePoint(0.0,0.0);
}
[[scrollview documentView] scrollPoint:newScrollOrigin];
}
显然,此代码假定您有一个 IBOutlet 到滚动视图。
对于 (2),您可以使用 textView.textStorage().appendString_(new_log + '\n') 在文本视图的末尾添加一行(假设末尾还没有换行符)。您可以通过调用textView.setSelectedRange_(NSMakeRange(textView.textStorage().length(),0)) 强制封闭滚动视图滚动到末尾(indirectoy)
【讨论】:
textView.textStorage().appendAttributedString_(NSAttributedString.alloc().initWithString_(new_log + u"\n"),滚动似乎对我不起作用。此外,在编辑字符串之前和之后,在textStorage() 上调用beginEditing() 和endEditing() 可能是值得的。
scrollRangeToVisible_,而不是setSelectedRange_。见stackoverflow.com/questions/15546808/…