1 回答
TA贡献1796条经验 获得超4个赞
如评论中所述,最好是使用单个 GUI 工具包,因此您需要为 Qt 重写代码或使用 tkinter 重写剪切代码。我不太了解 Qt,所以我无法帮助您选择第一个选项。然而,屏幕截图实际上是使用 PIL 截取的,而不是某些 Qt 特定方法,因此可以在 tkinter 中重写截图代码。
您所需要的只是一个包含带有可拖动矩形的画布的全屏顶层,就像在Tkinter 中使用鼠标事件绘制矩形一样。使顶层全屏:toplevel.attributes('-fullscreen', True)
顶层需要部分透明,这可以通过toplevel.attributes('-alpha', <value>)
. 我正在使用 Linux(带有 XFCE 桌面环境),我需要添加toplevel.attributes('-type', 'dock')
以使透明度起作用。
全部放在一个类中,这给出:
import sys
import tkinter as tk
from PIL import ImageGrab
import cv2
import numpy as np
class MyWidget(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
self.configure(cursor='cross')
if sys.platform == 'linux':
self.attributes('-type', 'dock') # to make transparency work in Linux
self.attributes('-fullscreen', True)
self.attributes('-alpha', 0.3)
self.canvas = tk.Canvas(self, bg='white')
self.canvas.pack(fill='both', expand=True)
self.begin_x = 0
self.begin_y = 0
self.end_x = 0
self.end_y = 0
self.canvas.create_rectangle(0, 0, 0, 0, outline='gray', width=3, fill='blue', tags='snip_rect')
self.canvas.bind('<ButtonPress-1>', self.mousePressEvent)
self.canvas.bind('<B1-Motion>', self.mouseMoveEvent)
self.canvas.bind('<ButtonRelease-1>', self.mouseReleaseEvent)
print('Capture the screen...')
def mousePressEvent(self, event):
self.begin_x = event.x
self.begin_y = event.y
self.end_x = self.begin_x
self.end_y = self.begin_y
self.canvas.coords('snip_rect', self.begin_x, self.begin_y, self.end_x, self.end_y)
def mouseMoveEvent(self, event):
self.end_x = event.x
self.end_y = event.y
self.canvas.coords('snip_rect', self.begin_x, self.begin_y, self.end_x, self.end_y)
def mouseReleaseEvent(self, event):
self.destroy()
self.master.update_idletasks()
self.master.after(100) # give time for screen to be refreshed so as not to see the blue box on the screenshot
x1 = min(self.begin_x, self.end_x)
y1 = min(self.begin_y, self.end_y)
x2 = max(self.begin_x, self.end_x)
y2 = max(self.begin_y, self.end_y)
img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
self.img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2RGB)
cv2.imshow('Captured Image', self.img)
cv2.waitKey(0)
if __name__ == '__main__':
root = tk.Tk()
tk.Button(root, text='Snip', command=lambda: MyWidget(root)).pack()
root.mainloop()
添加回答
举报