Хорошей новостью является то, что есть способ сделать это.
Промежуточная новость заключается в том, что она плохо документирована.
Плохая новость заключается в том, что она работает только на некоторых платформах.
Другая промежуточная новость заключается в том, что вы можете выйти за пределы Tk по крайней мере на некоторых платформах.
Способ сделать это в Tcl/Tk является путем генерации <Motion>
события с -warp 1
. Документация по этому вопросу разрежена и разбросана по нескольким страницам (начинаются с bind
), но детали описаны here. В основном это:
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)
И это действительно генерирует событие, как вы можете видеть, привязывая <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 думать, курсор переехал.
С скользя различных форумов, это выглядит следующим образом:
- Mac: Не работает.
- Windows: Обычно работает.
- У вас должен быть Tk 8.4.something или более поздний. Я не мог найти ошибку для этого, но вы можете рассчитывать на 8.4 с любой официальной бинарной установкой Windows для Python 2.7 или 3.x +.
- Вы также не должны запускать полноэкранное приложение (которого вы обычно не используете, с Tk).
- В Vista и позже, в некоторых случаях это не сработает. Это может иметь какое-то отношение к тому, чтобы не иметь сеанс рабочего стола или не являться сеансом локальной консоли, или, возможно, это связано с необходимостью использования Администратора или других привилегий.
- Если это не сработает, легко перейти к API Win32.
- X11 (большинство Linux, * BSD и т.д.): Обычно
- Ваш оконный менеджер не должен иметь инвалид других клиентов коробления указателя. К счастью, это не похоже на обычное дело.
- Если у вас есть эта проблема, ее нет.
- Другие платформы (iOS, Android и т. Д.): Понятия не имею.
Для Mac вы хотите сгенерировать и отправить событие NSMouseMoved
. Самый простой способ сделать это с pyobjc
(который построен, если вы используете Python от Apple, в противном случае вы должны установить его):
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))
Вместо перемещения указателя, возможно, сделать положение элемента управления Пиковые * скорость *, с которой мир вращается - чем дальше от центра, тем быстрее вращение. – unutbu
Это отличное предложение unetbu, и я использовал эту схему управления, но это не так удобно, как хотелось бы, поэтому мне нужно что-то похожее на то, как управляется игра с шутер от первого лица. – sam