1

アプリケーションに 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()

リッチは私のRichTextCtrlです。

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

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

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

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

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

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

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

4

1 に答える 1

3

どうやら、コードには 2 つの問題があります。

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

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

したがって、実際の例(私がテストしたところ、希望どおりに機能します)は次のようになります。

# 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ので、イベント プロセッサは、このハンドラーの後にイベントの伝達を停止するかどうかを認識します。

于 2009-03-08T09:00:18.190 に答える