0

GtkSourceView でファイルを開き、特定の行までスクロールする必要があります。一種のデバッガー gui であるため、一時的なアーティファクト (コンテンツの目に見える再調整やちらつき) なしで、(スタック フレームを切り替えるときに) このアクティビティを頻繁に行う必要があります。現在、私は次のアプローチを使用しています。

from gi.repository import GtkSource
class MyClientWindow:
  def __init__(self):
    self.__sourceview = GtkSource.View()
    self.__sourceview.connect('size-allocate', self.__source_resize)
    ...
  def __source_resize(self, widget, allocation):
    self.__sourceview.scroll_to_mark(self.__sourceview.get_buffer().get_insert(), 0.25, False, 0, 0)

このアプローチでは、目に見えるちらつきがあります。上記の __source_resize に 1 をスリープさせると、GtkSourceView が数回のパスで再調整されることがわかります (ソースの強調表示の前後に目に見えて描画され、追加の検証も行われます)。

GtkSource.View に強制的に行の高さを計算させ、画面に描画せずに検証を実行させる方法や、バッファの内容を設定したときに行の高さをすぐに計算させて後でアイドル状態にする方法はありますか? そうでない場合、目的の動作を得るために GtkSource.View コントロールをどの程度オーバーライドする必要がありますか?

注: Gtk.Stack を使用して、非表示の「背面」ビューで作業を行い、後で Gtk.idle_add を使用して表示できるようにしようとしましたが、ビューの可視性が行の検証の鍵であるという印象を受けました。少なくともこれまでのところ、望ましい結果は得られていません。

4

1 に答える 1

1

Gtk.Stack メソッドが機能しました。特定の一連の操作が必要です。これは、私が現在持っているソリューションからの抜粋です(明確にするために変更されています):

class MyClientWindow:
  def __init__(self):
    self.__stack = Gtk.Stack()
    ...
  def __switch_doc(content, line):
    buffer = GtkSource.Buffer()
    buffer.set_text(content)
    # buffer style settings are applied here
    ...
    iter = buffer.get_iter_at_line(line)
    buffer.place_cursor(iter)
    source_view = GtkSource.View.new_with_buffer(buffer)
    prev_sw = self.__stack.get_visible_child()
    next_sw = Gtk.ScrolledWindow()
    next_sw.add(source_view)
    next_sw.show_all()
    self.__stack.add(next_sw)
    GObject.idle_add(lambda: self.__switch_view(prev_sw, next_sw))
  def __switch_view(self, prev_sw, next_sw):
    source_view = next_sw.get_child()
    buffer = source_view.get_buffer()
    source_view.scroll_to_iter(buffer.get_iter_at_mark(buffer.get_insert()), 0, True, 0, 0.5)
    if prev_sw:
      self.__stack.remove(prev_sw)

毎回 GtkSourceView と親 GtkScrollWindow の両方を再作成します。これは多少最適化される可能性があります (スタック内の古いビューを削除するのではなく保持することによって)。

GtkScrollWindow をスタック コンテナーに追加する前に表示することが重要です。そうしないと、後で scroll_to_iter を使用してテキスト内の新しい位置に移動すると、色が表示されなくなります。(これがバグかどうかはわかりませんでした。)

追加する前にウィジェットを表示すると、スタックの「可視の子」になりますが、get_visible_child メソッドによって返されるという意味でのみです。ただし、画面にはレンダリングしません。

描画は古い子が削除された (または set_visible_child メソッドで新しい子がアクティブ化された) ときに開始されます。これは、上記の idle_add の使用により、GtkSourceView の行検証の後に発生します。したがって、scroll_to_mark の代わりに scroll_to_iter を使用してスクロールを実行できます。これにより、アクションがさらに延期されます。

于 2015-11-18T12:28:13.110 に答える