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

问题描述 投票:0回答:2

我不是专家,我试图在屏幕上显示一个矩形,该矩形跟随鼠标从定点开始的移动,就像您选择文字或绘画中的某些内容一样。我带有以下代码:

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)

如您所见,代码将绘制矩形,但是之前的矩形将保留到屏幕更新为止。

我自带的唯一解决方案是在将像素值设置为黑色之前,先获取要绘制的像素值,然后每次重新绘制它们,但这会使我的代码非常慢。有没有一种简便的方法可以更快地更新屏幕来防止这种情况?

python drawing pywin32 updating win32gui
2个回答
1
投票

为了刷新旧的绘制区域,您需要调用win32gui.UpdateWindow或类似方法来更新特定的窗口,但是由于从技术上讲,您不是在表面上绘制而是在整个监视器上绘制。您需要使监视器的整个区域无效,以便告诉Windows在其上重新绘制任何内容(或据我所知)

并且为了克服缓慢性,您可以使用win32ui.Rectangle一口气绘制它,而不是使用for循环来创建边界,而该边界将花费X个循环来进行迭代。

import win32gui, win32ui
from win32api import GetSystemMetrics

dc = win32gui.GetDC(0)
dcObj = win32ui.CreateDCFromHandle(dc)
hwnd = win32gui.WindowFromPoint((0,0))
monitor = (0, 0, GetSystemMetrics(0), GetSystemMetrics(1))

while True:
    m = win32gui.GetCursorPos()
    dcObj.Rectangle((m[0], m[1], m[0]+30, m[1]+30))
    win32gui.InvalidateRect(hwnd, monitor, True) # Refresh the entire monitor

可以在此处进行进一步的优化,例如不更新整个监​​视器,仅更新绘制的部分,依此类推。但这是基本概念:)

并且要创建一个没有填充的矩形,您可以将Rectangle交换为DrawFocusRect。或进行更多控制,甚至使用win32gui.PatBlt


是否有职位和决议?请注意,高DPI系统往往会引起很多问题。除了这篇文章之外,我没有找到其他解决方法,除了使用OpenGL解决方案或使用wxPython或OpenCV之类的框架之外,其他方法除外:Marking Your Python Program as High DPI Aware Seamlessly Windows


[关于清除旧图纸的唯一参考是这篇文章:win32 content changed but doesn't show update unless window is moved标记为c++ win winapi。希望这可以使一些人在寻找好的榜样之前免于搜索。


0
投票

如果您使用OpenCV,则可以像这样完成

© www.soinside.com 2019 - 2024. All rights reserved.