私は現在、neovimのサンプル UI を実装しており、プラットフォームの人気/シンプルさから Tkinter/python を使用することにしました。私が抱えている問題は、ウィンドウの高さが特定のしきい値を超えると、tkinter が UI の更新を「スタック」するように見えることです。
これが問題を示すビデオです。
右側のウィンドウは neovim を実行するターミナル エミュレーターで、左側のウィンドウはそれに接続された Tkinter UI プログラムです。アイデアは、tkinter UI が寸法を含む neovim 端末画面をミラーリングする必要があるということです。このビデオでは、ターミナル ウィンドウからフォーカスを外さないため、Tk が処理しなければならない唯一のイベントは、neovim (画面の更新を記述する仮想 'nvim' イベント) への接続から発生します。
ビデオの最初の部分は、ウィンドウの高さが小さい場合はすべてがうまく機能することを示していますが、高さを上げると更新が遅れ始めます。
Tkinter プログラムのコードは次のとおりです。neovim API は非常に新しく、まだ大規模な開発が行われていますが (一部の読者にはコードが意味をなさない可能性があります)、私が解決しようとしている問題は、(Tk テキスト ウィジェットを使用して) ターミナル エミュレーターを実装することに近いと思います。フォーマットされたテキストのバーストが効率的に更新されます。
私はGUIプログラミングに非常に不慣れです。Tkinter はこのタスクに賢明な選択ですか? はいの場合、誰かが私が間違っていることのヒントを教えてくれますか?
何が起こっているのかを少し説明するには: Neovim API はスレッドセーフでありvim.next_event()
、イベントが受信されるまでメソッドはブロックされます (ビジー待機なしで、下で libuv イベントループを使用します)。
呼び出しが戻ると、vim.next_event()
を使用して Tkinter スレッドに通知し、実際のイベント処理を行います (画面の更新を最適化するためにとgenerate_event
の間のイベントもバッファリングします)。redraw:start
redraw:stop
そのため、実際には 2 つのイベント ループが並行して実行されており、バックグラウンド イベント ループがスレッド セーフな方法で Tkinter イベント ループにフィードしています (このgenerate_event
メソッドは、他のスレッドから呼び出すことができる数少ないメソッドの 1 つです)。