Добрата новина е, че има начин да го направите.
Междинната новина е, че не е добре документиран.
Лошата новина е, че работи само на някои платформи.
Другата междинна новина е, че можете да излезете извън 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)
И това наистина генерира събитие, както можете да видите чрез обвързване <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: Does not work.
- Windows: Usually works.
- You must have Tk 8.4.something or later. I couldn't find the bug for this, but you can count on 8.4 with any official Windows binary install of Python 2.7 or 3.x+.
- Също така не трябва да стартирате приложение на цял екран (което обикновено не сте, с Tk).
- На Vista и по-нови в някои случаи няма да работи. Това може да има нещо общо с това, че не притежавате сесията на работния плот или не сте сесия на локална конзола, или може да е свързано с необходимостта от администраторски или други привилегии.
- Ако не работи, лесно е да отидете направо на Win32 API.
- X11 (most linux, *BSD, etc.): Usually
- Your window manager must not have disabled other clients from warping the pointer. Fortunately, that doesn't seem to be a common thing to do.
- Ако имате този проблем, няма начин да го заобиколите.
- Други платформи (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))
person
abarnert
schedule
23.05.2013