Bufferのread_onlyを一時的にOFFにしたいとき - Python
Bufferのread_only
がAlways()
だと、Bufferのtext
とかdocument
とか何も変更できないから、Never()
にする必要がある
form prompt_toolkit.filter import to_filter # read_onlyをONにする right.content.buffer.read_only = to_filter(True) # read_onlyをOFFにする right.content.buffer.read_only = to_filter(False)
使用例
from prompt_toolkit.application import Application from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.layout.containers import VSplit, Window from prompt_toolkit.layout.controls import BufferControl from prompt_toolkit.layout.layout import Layout from prompt_toolkit.buffer import Buffer from prompt_toolkit.document import Document from prompt_toolkit.filters import to_filter text = '\n'.join([str(i) for i in range(100)]) left = Window(BufferControl(Buffer(document=Document(text), read_only=True))) right = Window(BufferControl(Buffer(document=Document(text), read_only=True))) # ウィンドウ body = VSplit([ left, Window(width=1, char='|'), right, ]) # キーバインディング kb = KeyBindings() @kb.add('tab') def _(event): event.app.layout.focus_next() @kb.add('s-tab') def _(event): event.app.layout.focus_previous() @kb.add('q') def _(event): event.app.exit() @kb.add('c-o') def _(event): ## ここで、一時的にread_onlyをOFFにしている right.content.buffer.read_only = to_filter(False) right.content.buffer.document = Document('hello world!') right.content.buffer.read_only = to_filter(True) app = Application( layout=Layout(body), key_bindings=kb, full_screen=True) app.run()
以下、いろいろ調べたときのメモ
documentを変えるときだけ、read_onlyをFalseにする
Documnet
のコンストラクタを見ると引数でもらったread_onlu
をto_filter()
に渡している
https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/prompt_toolkit/buffer.py#L196
class Buffer(object): ... def __init__(self, completer=None, auto_suggest=None, history=None, validator=None, tempfile_suffix='', name='', complete_while_typing=False, validate_while_typing=False, enable_history_search=False, document=None, accept_handler=None, read_only=False, multiline=True, on_text_changed=None, on_text_insert=None, on_cursor_position_changed=None, on_completions_changed=None, on_suggestion_set=None): # Accept both filters and booleans as input. enable_history_search = to_filter(enable_history_search) complete_while_typing = to_filter(complete_while_typing) validate_while_typing = to_filter(validate_while_typing) read_only = to_filter(read_only) ...
to_filter()ってなに
prompt_toolkit.filters.utils
にいた
https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/prompt_toolkit/filters/utils.py
True
を渡すと、prompt_toolkit.filters.base.Always()
が返される。
False
を渡すと、prompt_toolkit.filters.base.Never()
が返される。
from __future__ import unicode_literals from .base import Always, Never, Filter __all__ = [ 'to_filter', 'is_true', ] _always = Always() _never = Never() def to_filter(bool_or_filter): """ Accept both booleans and Filters as input and turn it into a Filter. """ if not isinstance(bool_or_filter, (bool, Filter)): raise TypeError('Expecting a bool or a Filter instance. Got %r' % bool_or_filter) return { True: _always, False: _never, }.get(bool_or_filter, bool_or_filter) def is_true(value): """ Test whether `value` is True. In case of a Filter, call it. :param value: Boolean or `Filter` instance. """ return to_filter(value)()
AlwaysとNeverってなに
prompt_toolkit.filters.base
にいた
class Always(Filter): """ Always enable feature. """ def __call__(self): return True def __invert__(self): return Never() class Never(Filter): """ Never enable feature. """ def __call__(self): return False def __invert__(self): return Always()
__call__
と__invert__
って何
__call__
はインスタンス生成以外で関数っぽく呼び出した時に呼ばれる
Pythonのクラスにおけるcallメソッドの使い方 - Qiita
__invert__
は反転って意味らしい
よくわからなくなってきたけど、こうすればいいってことだ
form prompt_toolkit.filter import to_filter # read_onlyにするとき right.content.buffer.read_only = to_filter(True) # read_onlyを解除するとき right.content.buffer.read_only = to_filter(False)