猿问

我应该用 PyQt 重写我的 Tkinter,还是相反?

我写了一个 Tkinter 应用程序,我想添加屏幕截图,所以我从GitHub (screen-snip)中找到了一个用 PyQt 编写的单独程序,我正在导入并在我的 Tkinter 应用程序中使用它。然后我决定合并这些程序,以便提出一个关于为什么它们不能完全协同工作的问题。我学会了不要将 Tk 和 Qt 结合起来。

所以现在我的问题是,我应该用 Qt 还是 Tk 重写我的程序?

这种情况哪个更好?

当您选择一个图像文件时,我当前的混合 Tk/Qt 程序可以工作,但现在 Qt 的屏幕截图部分会class MyWidget(QtWidgets.QWidget):导致它冻结然后崩溃。

我认为问题可能是将 Qt 与 Tk 混合使用的结果,但我不确定。我最初有两个运行的 tkinter 实例,这让我可以用一个新窗口来显示屏幕,但导致窗口出现问题button,所以我通过尝试使用来替换它tk.Toplevel


class MyWidget(QtWidgets.QWidget):

    def __init__(self, master):

        super().__init__()

        self.master = master

        self.window = tk.Toplevel(self.master)

那是我遇到麻烦的时候。该小部件根本不再工作,并且程序在没有任何线索或错误的情况下崩溃。知道为什么吗?

慕码人8056858
浏览 349回答 1
1回答

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()
随时随地看视频慕课网APP

相关分类

Python
我要回答