2013-05-23 36 views
7

Tôi có chương trình kết xuất đồ họa 3D xoay vòng thế giới xung quanh một người quan sát dựa trên vị trí của chuột trên màn hình. Số tiền trong radian rằng thế giới có thể xoay được xác định bởi dòng nàyLàm thế nào tôi có thể đặt vị trí chuột trong cửa sổ tkinter

glob.worldx=-(w.winfo_pointerxy()[0]-xy[0])/250 

đâu xy [0] là tọa độ x của trung tâm của màn hình

này có nghĩa là số tiền mà các nhà quan sát lĩnh vực xem có thể xoay được giới hạn bởi khoảng cách chuột có thể đi. Nếu tôi có thể đưa chuột trở lại giữa màn hình, tôi có thể giải quyết vấn đề này. Bất kỳ ý tưởng?

+0

Thay vì di chuyển con trỏ, có lẽ làm cho vị trí của điều khiển con trỏ các * tốc * mà thế giới quay - xa hơn từ tâm quay nhanh hơn. – unutbu

+0

Đó là một gợi ý unetbu tuyệt vời, và tôi sử dụng để sử dụng chương trình kiểm soát, nhưng nó không phải là thân thiện với người như tôi muốn nó được, vì vậy tôi muốn một cái gì đó tương tự như cách một trò chơi bắn súng góc nhìn thứ nhất được điều khiển – sam

Trả lời

7

Tin vui là có cách để thực hiện.

Tin tức trung gian là nó không được ghi chép đầy đủ.

Tin xấu là nó chỉ hoạt động trên một số nền tảng.

Tin tức trung gian khác là bạn có thể bước ra ngoài Tk trên ít nhất một số nền tảng.


Cách để làm điều này trong Tcl/Tk là bằng cách tạo ra một sự kiện <Motion> với -warp 1. Các tài liệu về điều này là thưa thớt, và rải rác xung quanh một vài trang khác nhau (bắt đầu tại bind), nhưng các chi tiết được mô tả here. Về cơ bản, nó chỉ là:

event generate . <Motion> -warp 1 -x 50 -y 50 

Vì vậy, làm thế nào để bạn làm điều này từ Tkinter?

Vâng, event_generate không ghi nhận bất cứ nơi nào, và không phải là sự kiện <Motion>, hoặc warp tham số ... nhưng nó khá đơn giản để tìm ra nếu bạn biết làm thế nào Tk bản đồ để Tkinter:

window.event_generate('<Motion>', warp=True, x=50, y=50) 

Và đây thực sự tạo ra một sự kiện, như bạn có thể thấy bằng cách ràng buộc <Motion>. Dưới đây là một chương trình thử nghiệm đơn giản:

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() 

Chạy nó, nhấp vào cửa sổ để chắc chắn rằng nó đã tập trung, di chuyển con trỏ xung quanh, và bạn sẽ thấy nó in ra một cái gì đó như thế này:

motion 65, 69 
motion 65, 70 
motion 65, 71 

sau đó nhấn một phím, và nó sẽ in ra này:

motion 50, 50 

đó là tuyệt vời ... ngoại trừ việc nó có thể không thực sự có thể di chuyển con trỏ của bạn, trong trường hợp tất cả điều này là lừa Tk vào suy nghĩ con trỏ đã di chuyển.


Từ lướt các diễn đàn khác nhau, nó trông giống như:

  • Mac: Không làm việc.
  • Windows: Thông thường hoạt động.
    • Bạn phải có Tk 8.4.something hay muộn. Tôi không thể tìm thấy lỗi này, nhưng bạn có thể đếm trên 8.4 với bất kỳ cài đặt nhị phân Windows chính thức nào của Python 2.7 hoặc 3.x +.
    • Bạn cũng không nên chạy một ứng dụng toàn màn hình (mà bạn nói chung là không, với Tk).
    • Trên Vista và sau đó, trong một số trường hợp, nó sẽ không hoạt động. Điều này có thể có liên quan đến việc không sở hữu phiên máy tính để bàn hoặc không phải là phiên điều khiển cục bộ hoặc có thể phải làm với việc cần có Quản trị viên hoặc các đặc quyền khác.
    • Nếu nó không hoạt động, thật dễ dàng để truy cập ngay vào API Win32.
  • X11 (hầu hết các Linux, * BSD, vv): Thường
    • quản lý cửa sổ của bạn không phải đã vô hiệu hóa các khách hàng khác từ cong vênh con trỏ. May mắn thay, đó không phải là một điều phổ biến để làm.
    • Nếu bạn có vấn đề này, không có cách nào xung quanh nó.
  • nền tảng khác (iOS, Android, vv): Không có ý tưởng.

Đối với máy Mac, bạn muốn tạo và gửi sự kiện NSMouseMoved. Cách đơn giản để làm điều này là với pyobjc (được xây dựng vào nếu bạn đang sử dụng Python của Apple, nếu không bạn phải cài đặt nó):

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) 

Đối với Windows, bạn muốn gọi SetCursorPos API, hoặc tạo và gửi một MOUSEEVENT. Tên cũ sẽ không hoạt động với, ví dụ: trò chơi DirectX; sau này có thể không hoạt động với máy tính để bàn từ xa. Đối với trường hợp này, bạn có thể muốn trước đây. Dù bằng cách nào, cách dễ nhất để làm điều này là để cài đặt pywin32, và sau đó nó chỉ là:

win32api.SetCursorPos((50, 50)) 
+0

này đang làm việc cho tôi trên Windows 7. – Tim

+0

@Tim: Tuyệt vời! Tôi đã nghiên cứu thêm một chút; hãy để tôi cập nhật mọi thứ. – abarnert

+0

Hoạt động như một abernart quyến rũ! Có cách nào tôi có thể làm điều này mà không cần nhấn phím? gần nhất tôi đã nhận được là bằng cách đặt các chức năng root.event_generate trong trường hợp chuyển động chuột, nhưng điều đó cập nhật khá chậm – sam

Các vấn đề liên quan