良いニュースは、それを行う方法があるということです。
中間ニュースは、十分に文書化されていないということです。
悪いニュースは、一部のプラットフォームでしか機能しないことです。
その他の中間ニュースは、少なくともいくつかのプラットフォームで Tk の外に出ることができるということです。
Tcl/Tk でこれを行う方法は、 で<Motion>
イベントを生成すること-warp 1
です。これに関するドキュメントはまばらで、いくつかの異なるページ ( から開始) に散らばっていますbind
が、詳細はここ で説明されています。基本的には、これだけです:
event generate . <Motion> -warp 1 -x 50 -y 50
では、Tkinter からこれを行うにはどうすればよいでしょうか。
まあ、event_generate
どこにも文書化されておらず、<Motion>
イベントもwarp
パラメーターもありません...しかし、TkがTkinterにどのようにマップされるかを知っていれば、理解するのは非常に簡単です:
window.event_generate('<Motion>', warp=True, x=50, y=50)
binding でわかるように、これは実際にイベントを生成します<Motion>
。簡単なテスト プログラムを次に示します。
from tkinter import *
root = Tk()
def key(event):
root.event_generate('<Motion>', warp=True, x=50, y=50)
def motion(event):
print('motion {}, {}'.format(event.x, event.y))
root.bind('<Key>', key)
root.bind('<Motion>', motion)
root.mainloop()
それを実行し、ウィンドウをクリックしてフォーカスがあることを確認し、カーソルを移動すると、次のような出力が表示されます。
motion 65, 69
motion 65, 70
motion 65, 71
次にキーを押すと、次のように出力されます。
motion 50, 50
これは素晴らしいことです... ただし、実際にはカーソルを移動できない場合があります。その場合、Tk をだましてカーソルが移動したと思わせるだけです。
さまざまなフォーラムをざっと見ると、次のようになります。
- マック: 動作しません。
- Windows: 通常は動作します。
- Tk 8.4.something 以降が必要です。これに関するバグは見つかりませんでしたが、Python 2.7 または 3.x+ の公式の Windows バイナリ インストールで 8.4 を期待できます。
- また、フルスクリーン アプリを実行していてはなりません (通常、Tk ではそうではありません)。
- Vista以降では動作しない場合があります。これは、デスクトップ セッションを所有していないか、ローカル コンソール セッションではないことに関係している可能性があります。あるいは、管理者権限またはその他の権限が必要であることに関係している可能性があります。
- それが機能しない場合は、Win32 API に直接アクセスするのは簡単です。
- X11 (ほとんどの Linux、*BSD など): 通常
- ウィンドウ マネージャーで、他のクライアントがポインターをゆがめるのを無効にしてはなりません。幸いなことに、それは一般的なことではないようです。
- この問題が発生した場合、それを回避する方法はありません。
- その他のプラットフォーム (iOS、Android など): わかりません。
Mac の場合、NSMouseMoved
イベントを生成して送信します。これを行う簡単な方法はpyobjc
次のとおりです (Apple の Python を使用している場合は組み込まれています。それ以外の場合は、インストールする必要があります)。
app = Foundation.NSApplication.sharedApplication()
event = Foundation.NSEvent.mouseEventWithType_location_modifierFlags_timestamp_windowNumber_context_eventNumber_clickCount_pressure_(
Foundation.NSMouseMoved, (50, 50), 0, 0,
app.mainWindow().windowNumber(), None, 0, 0, 0.0)
app.sendEvent_(event)
Windows の場合、SetCursorPos
API を呼び出すか、MOUSEEVENT を生成して送信します。前者は、たとえば DirectX ゲームでは機能しません。後者はリモート デスクトップでは機能しない場合があります。この場合、おそらく前者が必要です。いずれにせよ、これを行う最も簡単な方法は をインストールするpywin32
ことです。
win32api.SetCursorPos((50, 50))