首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用Python在屏幕上绘制空矩形

如何用Python在屏幕上绘制空矩形
EN

Stack Overflow用户
提问于 2020-06-12 09:11:17
回答 4查看 12.4K关注 0票数 4

我不是专家,我试图在屏幕上显示一个矩形,它跟随鼠标从一个固定的起点移动,就像你在文字或绘画中选择什么一样。我带着这个密码来的:

代码语言:javascript
运行
复制
import win32gui
m=win32gui.GetCursorPos()
while True:
    n=win32gui.GetCursorPos()
    for i in range(n[0]-m[0]):
        win32gui.SetPixel(dc, m[0]+i, m[1], 0)
        win32gui.SetPixel(dc, m[0]+i, n[1], 0)
    for i in range(n[1]-m[1]):
        win32gui.SetPixel(dc, m[0], m[1]+i, 0)
        win32gui.SetPixel(dc, n[0], m[1]+i, 0)

如您所见,代码将绘制矩形,但前面的矩形将一直保持到屏幕更新。

我提出的唯一解决方案是,在将像素值设置为黑色之前,将其设置为黑色,并每次重新绘制它们,但这会使我的代码非常慢。有没有一种简单的方法可以更快地更新屏幕以防止这种情况发生?

..。

用溶液编辑。

正如@Torxed所建议的那样,使用win32gui.InvalidateRect解决了更新问题。然而,我发现只设置我需要设置的点的颜色比要求一个矩形更便宜。第一种解决方案相当干净,而第二种解决方案仍然有一点小问题。最后,对我来说最有效的代码是:

代码语言:javascript
运行
复制
import win32gui

m=win32gui.GetCursorPos()
dc = win32gui.GetDC(0)

while True:
    n=win32gui.GetCursorPos()
    win32gui.InvalidateRect(hwnd, (m[0], m[1], GetSystemMetrics(0), GetSystemMetrics(1)), True)
    back=[]
    for i in range((n[0]-m[0])//4):
        win32gui.SetPixel(dc, m[0]+4*i, m[1], 0)
        win32gui.SetPixel(dc, m[0]+4*i, n[1], 0)
    for i in range((n[1]-m[1])//4):
        win32gui.SetPixel(dc, m[0], m[1]+4*i, 0)
        win32gui.SetPixel(dc, n[0], m[1]+4*i, 0)

除法和乘四是必要的,以避免闪烁,但在视觉上与使用DrawFocusRect相同。

这将只有当你保持低沉和右从你的最初立场,但这正是我所需要的。不难改进,接受任何次要职位。

EN

Stack Overflow用户

发布于 2021-09-11 01:42:46

我已经根据这里的一些答案进行了一段时间的工作,这是我的解决方案。

这将等待鼠标被按下和拖动,并创建一个从按下位置到拖动位置的矩形。在鼠标释放时,它将清除矩形并输出单击和释放的位置,并关闭所有钩子。

有几个问题我想解决(一些轻微的闪烁和边框太薄),所以如果有人知道这些我会感谢一些帮助(win32ui文档真的很糟糕)

如果您想要纯色,只需将FrameRect((x,y,a,b),brush)更改为FillRect((x,y,a,b), brush)即可。

代码语言:javascript
运行
复制
from win32gui import GetDC, WindowFromPoint, SetPixel, InvalidateRect
from win32ui import CreateDCFromHandle, CreateBrush
from win32api import GetSystemMetrics, GetSysColor
from PyHook3 import HookManager
import ctypes
class Draw_Screen_Rect:
    def __init__(self):
        self.pos = [0, 0, 0, 0]
        dc = GetDC(0)
        self.dcObj = CreateDCFromHandle(dc)
        self.hwnd = WindowFromPoint((0,0))
        self.monitor = (0, 0, GetSystemMetrics(0), GetSystemMetrics(1))
        self.clicked = False
        self.b1 = CreateBrush()
        self.b1.CreateSolidBrush(GetSysColor(255))
        self.final_rect = None
        self.refresh_frames = 0
        self.refresh_after = 10

    def _draw_rect_func(self):
        self.dcObj.FrameRect(tuple(self.pos), self.b1)
    def _refresh_rect(self):
        InvalidateRect(self.hwnd, self.monitor, True)
    

    def _OnMouseEvent(self, event):
        if event.Message == 513:
            self.clicked = True
            self.pos[0], self.pos[1] = event.Position
        elif event.Message == 514:
            self.clicked = False
            self.pos[2], self.pos[3] = event.Position
            self._draw_rect_func()
            self._refresh_rect()
            self.final_rect = self.pos
            self._destroy_hooks()
        elif event.Message == 512:
            if self.clicked:
                self.pos[2], self.pos[3] = event.Position
                if self.refresh_frames%2 ==0:
                    self._draw_rect_func()
                self.refresh_frames+=1
                if self.refresh_frames > self.refresh_after:
                    self.refresh_frames = 0
                    self._refresh_rect()
        return True
    def create_hooks(self):
        self.hm = HookManager()
        self.hm.MouseLeftDown = self._OnMouseEvent
        self.hm.MouseLeftUp = self._OnMouseEvent
        self.hm.MouseMove = self._OnMouseEvent
        self.hm.HookMouse()
        self.hm.HookKeyboard()

    def _destroy_hooks(self):
        self.hm.UnhookMouse()
        ctypes.windll.user32.PostQuitMessage(0)

    def output(self):
        return self.final_rect

if __name__ == '__main__':
    app = Draw_Screen_Rect()
    app.create_hooks()
    from pythoncom import PumpMessages
    PumpMessages()
    out = app.output()
    print(out)
票数 0
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62341134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档