我正在使用 Traits 4 构建一个简单的交互式 GUI 应用程序。此应用程序将在 GUI 的专用部分显示带有时间戳的事件日志。此日志当前存储为字符串特征。
String trait 的默认编辑器(或视图?不确定确切的命名法)是一个可滚动的多行显示小部件。当内部字符串值更改时,小部件会更新以显示新值。如果内容的长度超过了小部件的可视大小,则会出现一个滚动条,允许用户在整个值上上下滚动。
似乎当小部件刷新并且垂直滚动条可见(内容超过小部件大小)时,视图重置到值的开头(顶部),并且滚动条也返回到顶部,遮盖了值的最后部分.
在我的应用程序中,我希望日志中的最新事件(在底部)始终在值刷新后显示。但是由于视图重置到值的顶部,它不会跟随最新的条目,并且用户必须在每次刷新后不断滚动到底部。这在这种形式中是不可用的。
有没有一种简单的方法可以将此特征的编辑器/视图配置为从底部滚动?
如果没有,如何为这个 String trait 编写自定义编辑器/视图?是否有必要使用 wx/qt4 原语从头开始编写新视图,或者是否有某种方法可以从现有视图派生新视图并仅覆盖实现所需功能所需的部分?
这是一些演示该问题的示例代码:
# from https://svn.enthought.com/enthought/ticket/1619 - broken SSL cert
from threading import Thread
from time import sleep
from enthought.traits.api import *
from enthought.traits.ui.api import View, Item, ButtonEditor
class TextDisplay(HasTraits):
string = String()
view= View( Item('string',show_label=False, springy=True, style='custom' ))
class CaptureThread(Thread):
def run(self):
self.display.string = 'Camera started\n' + self.display.string
n_img = 0
while not self.wants_abort:
sleep(.5)
n_img += 1
self.display.string += '%d image captured\n' % n_img
self.display.string += 'Camera stopped\n'
class Camera(HasTraits):
start_stop_capture = Button()
display = Instance(TextDisplay)
capture_thread = Instance(CaptureThread)
view = View( Item('start_stop_capture', show_label=False ))
def _start_stop_capture_fired(self):
if self.capture_thread and self.capture_thread.isAlive():
self.capture_thread.wants_abort = True
else:
self.capture_thread = CaptureThread()
self.capture_thread.wants_abort = False
self.capture_thread.display = self.display
self.capture_thread.start()
class MainWindow(HasTraits):
display = Instance(TextDisplay, ())
camera = Instance(Camera)
def _camera_default(self):
return Camera(display=self.display)
view = View('display', 'camera', style="custom", resizable=True)
if __name__ == '__main__':
MainWindow().configure_traits()
多次单击“开始停止捕获”按钮,直到视图填满,您会观察到后续刷新会将滚动条位置重置到视图顶部。