イベントハンドラでwxRichTextCtrlのカーソル位置を変更するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/622417

質問

アプリケーションにRichTextCtrlがあり、 EVT_KEY_DOWN のハンドラーがあります。実行されるコードは次のとおりです。


def move_caret(self):
    pdb.set_trace()
    self.rich.GetCaret().Move((0,0))
    self.Refresh()


def onClick(self,event):
    self.move_caret()
    event.Skip()

rich は私のRichTextCtrlです。

これが私がやりたいことです:

  • キーを押すたびに、コントロールにキーを追加します(これはデフォルトの動作です)

  • コントロールの先頭、最初の位置にカーソルを移動します

実際に行うことは次のとおりです:

  • コントロールにキーを追加します

  • キャレットの位置を調べたところ、デバッガは0,0にあると報告しましたが、コントロール上では現在の位置(キーを押す前の位置+ 1)で点滅します

ここで何か問題がありますか?私が間違っていることをしているはずです。

役に立ちましたか?

解決

明らかに、コードには2つの問題があります:

  1. EVT_KEY_DOWN をリッスンします。これはおそらく EVT_TEXT の前に処理されます。デフォルトハンドラーはカーソル位置を設定します。

  2. SetInsertionPoint メソッドを使用する代わりに、 Caret オブジェクトを変更します。これにより、キャレットが移動し、次の文字が所定の場所に表示されます。

したがって、実際の例(私はテストし、あなたが望むように動作します)は次のようになります:

# Somewhere in __init__:
    self.rich.Bind(wx.EVT_TEXT, self.onClick)

def onClick(self, event):
    self.rich.SetInsertionPoint(0) # No refresh necessary.
    event.Skip()

編集:末尾にテキストを追加したいが、カーソルを先頭に残したい場合(コメントを参照)、 EVT_KEY_DOWN EVT_TEXT の前に処理されます(これは文字の追加後に処理されます)。したがって、イベントの順序は次のとおりです。

  1. ハンドル EVT_KEY_DOWN
  2. 現在の挿入ポイントに文字を追加
  3. ハンドル EVT_TEXT

実際にキャラクターを追加する直前に挿入ポイントを最後に移動する EVT_KEY_DOWN のハンドラーを追加すると、非常にうまく機能します。したがって、前述のコードに加えて、次のように記述します。

# Somewhere in __init__:
    self.rich.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)

def onKeyDown(self, event):
    self.rich.SetInsertionPointEnd()
    event.Skip()

ところで、 event.Skip()はすぐに次のイベントハンドラを呼び出さず、 event オブジェクトにフラグを設定するだけなので、イベントプロセッサはこのハンドラーの後のイベントの伝播を停止します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top