如何停止移动光标,但仍能理解如果代码在Python中不起作用时光标的位置?

huangapple go评论84阅读模式
英文:

How to stop moving cursor but be able to understand where the cursor would be at if the code wasn't working in Python?

问题

I think it is a bit difficult to explain but I'll try. Basically, I need to prevent the mouse from moving but be able to track it.

For example, when I move the mouse for 10 pixels, the cursor moves 10 pixels normally. However, I want the cursor to stay in the same position and want the code to print "Mouse would be at x+10, y if it wasn't locked."

I am sorry if it wasn't clear enough. But, please help me, I don't have any other information or idea. By the way, I don't want the cursor to be moved to the start point again and again. Because this doesn't actually stop the cursor.

英文:

I think it is a bit difficult to explain but I'll try. Basically, I need to prevent the mouse to move but be able to track it.

For example, when I move mouse for 10 pixel, cursor moves 10 pixel normally. However, I want the cursor to stay in the same position and want the code to print "Mouse would be at x+10, y if it wasn't locked.".

I am sorry if it wasn't clear enough. But, please help me I don't have any other information or idea. By the way, I don't want the cursor to be moved to the start point again and again. Because this doesn't actually stop the cursor.

答案1

得分: 1

非常有趣的问题!这是我基于个人兴趣找到的结果。

pynput 库包含用于监视鼠标事件的工具,并且还可以实现自己的回调函数,该函数将在特定事件上触发(就像在 JavaScript 的 onClick 事件上执行函数一样)。

该工具的另一个有用属性是这个标志:
> suppress(布尔值)– 是否抑制事件。将其设置为 True
> 将阻止将输入事件传递给系统的其他部分。

有了它,你可以拦截所有鼠标移动事件,处理它们,同时不允许鼠标实际移动。

然而,由于最终鼠标实际上并没有移动,你必须手动计算它可能的位置,在事件之间保存先前的状态。

为了确保我的解决方案是正确的,我决定使用 turtle 来绘制虚拟鼠标的路径,结果相当准确(尽管有时鼠标的行为有点奇怪,所以这段代码肯定不完美,但可能会带你走向更准确的答案)。

最终,这段代码实际上完全停止了鼠标,并且实际上预测了鼠标的位置,“如果它没有被停止的话”。如果可视化,它看起来像这样:
如何停止移动光标,但仍能理解如果代码在Python中不起作用时光标的位置?

代码本身(为了仅获取坐标的计算,你可以删除与绘制相关的代码部分):

from pynput import mouse
from turtle import Screen, Turtle

# 请键入你的屏幕分辨率
SCREEN_SIZE = (2560, 1440)
DRAW_TURTLE = True

# ...(剩余的代码被截断)
英文:

Very interesting question!) That's what I managed to find thanks to personal interest.

The pynput library contains tools for monitoring mouse events, and also makes it possible to implement your own callbacks that will fire on certain events (just like implementing a function that will be executed on the onClick event in javascript).

Another useful property of this tool is this flag:
> suppress (bool) – Whether to suppress events. Setting this to True
> will prevent the input events from being passed to the rest of the
> system.

With it, you can literally intercept all mouse movement events, handle them, while not allowing the mouse to actually move.

However, due to the fact that the mouse doesn't really move in the end, you have to calculate its possible position manually, saving previous state between events.

To make sure my solution was correct, I decided to use the turtle to draw the path of an imaginary mouse, and it turned out pretty accurate (although sometimes the mouse behaves a little strange, so this code is definitely not perfect, but may lead you to a more accurate answer).

In the end, this code actually stops the mouse completely, and actually predicts its position "if it hadn't been stopped". It looks something like this, if visualized:
如何停止移动光标,但仍能理解如果代码在Python中不起作用时光标的位置?

Code itself (you can remove all parts of the code related to drawing in order to get only the calculation of coordinates):

from pynput import mouse
from turtle import Screen, Turtle

# please enter your screen resolution
SCREEN_SIZE = (2560, 1440)
DRAW_TURTULE = True


class Tracker:
    def __init__(self, screen_size):
        self.start_x, self.start_y = None, None
        self.curr_x, self.curr_y = None, None
        self.max_x, self.max_y = screen_size

        # drawing part
        self.screen = Screen()
        self.screen.screensize(self.max_x, self.max_y)
        self.screen.setworldcoordinates(0, self.max_y, self.max_x, 0)

        self.yertle = Turtle("turtle")
        self.yertle.speed("fastest")

    def move(self, x, y):
        # if this first time the mouse is moved, initialize the start position
        if self.start_x is None:
            print("Started at {0}".format((x, y)))
            self.start_x, self.start_y = x, y
            self.curr_x, self.curr_y = x, y
            return

        # take x and y difference from the start position
        # add that or subtract that from the current position
        # max and min needed to make sure the pointer doesn't go out of the screen
        self.curr_x = min(self.max_x, max(0, self.curr_x + (x - self.start_x)))
        self.curr_y = min(self.max_y, max(0, self.curr_y + (y - self.start_y)))

        positionStr = f"Pointer would be at ({self.curr_x:4}, {self.curr_y:4})"
        print(positionStr, end="")
        print("\b" * len(positionStr), end="", flush=True)

        # drawing part
        self.yertle.goto(self.curr_x, self.curr_y)

    # click to stop program
    def click(self, x, y, button, pressed):
        print("\n{0} at {1}".format("Pressed" if pressed else "Released", (x, y)))
        if not pressed:
            # Stop listener
            return False

    def draw(self):
        self.screen.mainloop()


t = Tracker(SCREEN_SIZE)

if DRAW_TURTULE:
    # Collect events until released (clicked) NON BLOCKING
    listener = mouse.Listener(on_move=t.move, on_click=t.click, suppress=True)
    listener.start()

    t.draw()
else:
    # Collect events until released (clicked) BLOCKING (syncronous)
    with mouse.Listener(on_move=t.move, on_click=t.click, suppress=True) as listener:
        listener.join()

huangapple
  • 本文由 发表于 2023年5月7日 07:23:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76191603.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定