You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5截图工具完成截图后残留矩形框问题求助

Fix Lingering Selection Rectangle in PyQt5 Snipping Tool

Got it, let's tackle that annoying leftover rectangle issue in your snipping tool! The root problem is simple: after you finish a snip, your SnippingWidget doesn't reset the selection coordinates (start_point and end_point). So when you activate snipping again, the old coordinates are still there, and the paintEvent draws the previous rectangle.

Here are two clean ways to fix this:

Add a showEvent method to your SnippingWidget class. This ensures every time you open the snipping tool, it starts with a blank slate—no matter how you exited last time.

Update your SnippingWidget code like this:

class SnippingWidget(QtWidgets.QMainWindow):
    closed = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(SnippingWidget, self).__init__(parent)
        self.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
        self.setStyleSheet("background:transparent;")
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.outsideSquareColor = "red"
        self.squareThickness = 2
        self.start_point = QtCore.QPoint()
        self.end_point = QtCore.QPoint()

    def showEvent(self, event):
        # Reset selection points and trigger a repaint to clear old drawings
        self.start_point = QtCore.QPoint()
        self.end_point = QtCore.QPoint()
        self.update()
        super().showEvent(event)

    # Keep your existing mousePressEvent, mouseMoveEvent, mouseReleaseEvent, paintEvent methods here

Option 2: Reset Coordinates After Snip + Handle ESC Cancel

If you want extra control (like letting users cancel with ESC and clearing the rectangle immediately), add a keyPressEvent and reset coordinates in mouseReleaseEvent:

class SnippingWidget(QtWidgets.QMainWindow):
    closed = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        # ... your existing __init__ code ...

    def mouseReleaseEvent(self, QMouseEvent):
        r = QtCore.QRect(self.start_point, self.end_point).normalized()
        self.hide()
        img = ImageGrab.grab(bbox=r.getCoords())
        img.save("snips/testImage.png")
        QApplication.restoreOverrideCursor()
        # Reset points after capturing the snip
        self.start_point = QtCore.QPoint()
        self.end_point = QtCore.QPoint()
        self.closed.emit()

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Escape:
            # Reset points and clear the rectangle if user cancels with ESC
            self.start_point = QtCore.QPoint()
            self.end_point = QtCore.QPoint()
            self.update()
            self.hide()
            QApplication.restoreOverrideCursor()
            self.closed.emit()

    # Keep your other existing methods here

Either approach will eliminate the lingering rectangle. Option 1 is more robust because it guarantees a fresh state every time you activate snipping, while Option 2 adds a nice cancel feature for users.

内容的提问来源于stack exchange,提问作者Brett La Pierre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:08:13