我正在尝试创建一个可以从 python 代码触发的屏幕截图区域工具。
它在第一次通话时有效,但在第二次通话时出现以下错误:
TclError: image "pyimage2" doesn't exist
只有在我重新启动内核后才能工作,但只有一次,然后出现同样的错误..
我包括了下面的所有代码。有 python-mss 作为依赖项(和 tkinter 在 linux 上)
import os
from tkinter import Tk, Canvas, PhotoImage, YES, BOTH, NW, Toplevel
from mss import mss, tools
def full_screenshot(fn="img"):
# Primary monitor screenshot
filename = os.path.relpath(f'{fn}.png')
with mss() as sct:
sct.shot(mon=1, output=filename)
return filename
def area_screenshot(sx, sy, ex, ey, fn="img"):
try:
os.mkdir("snaps")
except:
pass
with mss() as sct:
# The screen part to capture
monitor = {"top": sy, "left": sx, "width": ex-sx, "height": ey-sy, "mon":1}
filename = os.path.relpath("./snaps/" + fn + "-{top}x{left}_{width}x{height}.png".format(**monitor))
# Grab the data
sct_img = sct.grab(monitor)
# Save to the picture file
tools.to_png(sct_img.rgb, sct_img.size, output=filename)
del sct
return filename
class _Snap:
def __init__(self, name="snap"):
self.name = name
self.snap = None
self.window = Tk()
#self.window = Toplevel(root)
self.window.title("Snip picture")
self.window.attributes('-fullscreen', True)
self.c = Canvas(self.window, cursor="cross")
self.c.pack(expand=YES, fill=BOTH)
fname = full_screenshot("temp")
bg = PhotoImage(file=fname)
self.c.create_image(0, 0, image=bg, anchor=NW)
self.window.bind("<Escape>", self.quit_fullscreen)
self.c.bind("<ButtonPress-1>", self.on_press)
self.c.bind("<B1-Motion>", self.on_drag)
self.c.bind("<ButtonRelease-1>", self.on_release)
self.window.mainloop()
#root.mainloop()
def quit_fullscreen(self, event):
self.window.attributes("-fullscreen", False)
def clear_canvas(self):
self.c.delete(self.rect)
self.c.delete(self.d1)
self.c.delete(self.d2)
self.window.update()
def on_press(self, event):
#print("Pressed", event)
self.sx = event.x
self.sy = event.y
self.rect = self.c.create_rectangle(self.sx, self.sy, self.sx, self.sy, width=2, fill="", dash=(3,5), outline="green3")
self.d1 = self.c.create_line(self.sx, self.sy, self.sx, self.sy, width=1.2, fill="green2")
self.d2 = self.c.create_line(self.sx, self.sy, self.sx, self.sy, width=1.2, fill="green2")
def on_drag(self, event):
#print("Draged", event)
self.cx = event.x
self.cy = event.y
self.c.coords(self.rect, self.sx, self.sy, self.cx, self.cy)
self.c.coords(self.d1, self.sx, self.sy, self.cx, self.cy)
self.c.coords(self.d2, self.cx, self.sy, self.sx, self.cy)
def on_release(self, event):
#print("Released", event)
self.ex = event.x
self.ey = event.y
self.clear_canvas()
self.snap = area_screenshot(self.sx, self.sy, self.ex, self.ey, self.name)
self.close_snip_window()
def close_snip_window(self):
os.remove("temp.png")
self.window.withdraw()
self.window.quit()
#Main function
def take_snap():
obj = _Snap()
cx = (obj.sx + obj.ex) / 2
cy = (obj.sy + obj.ey) / 2
data = {
"sxy": (obj.sx, obj.sy,),
"exy": (obj.ex, obj.ey,),
"cxy": (cx, cy,),
"snap": obj.snap
}
del obj
return data
#take_snap()
我尝试使用 Toplevel() 函数,但没有成功。