SMILET
如评论中所述,最好是使用单个 GUI 工具包,因此您需要为 Qt 重写代码或使用 tkinter 重写剪切代码。我不太了解 Qt,所以我无法帮助您选择第一个选项。然而,屏幕截图实际上是使用 PIL 截取的,而不是某些 Qt 特定方法,因此可以在 tkinter 中重写截图代码。您所需要的只是一个包含带有可拖动矩形的画布的全屏顶层,就像在Tkinter 中使用鼠标事件绘制矩形一样。使顶层全屏:toplevel.attributes('-fullscreen', True)顶层需要部分透明,这可以通过toplevel.attributes('-alpha', <value>). 我正在使用 Linux(带有 XFCE 桌面环境),我需要添加toplevel.attributes('-type', 'dock')以使透明度起作用。全部放在一个类中,这给出:import sysimport tkinter as tkfrom PIL import ImageGrabimport cv2import numpy as npclass 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()