Esempio n. 1
0
 def setCircle(widget):
     """
     设置成圆角
     """
     # 圆角
     bitmap = QBitmap(widget.size())
     bitmap.fill()
     painter = QPainter(bitmap)
     painter.begin(widget)
     painter.setPen(Qt.NoPen)
     painter.setBrush(Qt.black)
     painter.setRenderHint(QPainter.Antialiasing)
     painter.drawRoundedRect(bitmap.rect(), 5, 5)
     painter.end()
     widget.setMask(bitmap)
Esempio n. 2
0
    def load_img(self, c):
        global counter
        counter += 1
        imager = Imager(self.state["Title"], self.state["Artist"])
        data = imager.get_data()

        if (c + 1 != counter):
            return

        pixmap = QPixmap()
        pixmap.loadFromData(data)

        map = QBitmap(pixmap.size())
        map.fill(Qt.color0)
        painter = QPainter(map)
        painter.setBrush(Qt.color1)
        painter.drawRoundedRect(0, 0, pixmap.width(), pixmap.height(), 10, 10)
        painter.end()

        self.app.label.setScaledContents(True)
        pixmap.setMask(map)
        self.app.label.setPixmap(
            pixmap.scaled(self.app.label.size(), QtCore.Qt.KeepAspectRatio,
                          QtCore.Qt.SmoothTransformation))
Esempio n. 3
0
class GrabToolWindow(QWidget):
    """抓取工具窗口,显示在最前端"""
    sigDisplay = pyqtSignal()  # 创建信号,用于新建贴图窗口
    sigScreenShot = pyqtSignal()

    def __init__(self):
        super(GrabToolWindow, self).__init__()
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
                            | Qt.SplashScreen)  # 无边框 置顶 不显示任务栏图标
        self.setStyleSheet('''background-color:black; ''')
        self.setWindowOpacity(0.3)
        self.desktopRect = QDesktopWidget().screenGeometry()
        self.setGeometry(self.desktopRect)
        self.setCursor(Qt.CrossCursor)
        self.blackMask = QBitmap(self.desktopRect.size())
        self.blackMask.fill(Qt.black)
        self.availTopLeftPoint = QDesktopWidget().availableGeometry().topLeft(
        )  # 有效显示区域左上角点

        self.isDrawing = False
        self.startPoint = QPoint()
        self.endPoint = QPoint()

        self.hk1, self.hk2 = SystemHotkey(), SystemHotkey()  # 初始化两个热键
        # self.hk1.register(('control', '1'), callback=lambda x: self.showGrabWindow())
        self.hk2.register(('control', 'shift', 'j'),
                          callback=lambda x: self.showGrabWindow())

        self.sigDisplay.connect(self.createDisplayWin)  # 信号连接到子窗口创建函数
        self.displayWinDict = {}
        self.displayWinNum = 0

        self.sigScreenShot.connect(self.createScreenShotWin)

    def createDisplayWin(self):  # 这里使用字典存储新建的窗口,当窗口关闭时未进行内存释放,可进行优化
        self.displayWinDict[self.displayWinNum] = DisplayWindow(
            self.screenshot, self.startPoint + self.availTopLeftPoint,
            self.displayWinNum)
        self.displayWinDict[self.displayWinNum].show()
        self.displayWinNum += 1

    def createScreenShotWin(self):
        self.screenshotWindow = ScreenshotWindow()
        self.screenshot_full_screen = self.screenshotWindow.screenShot
        self.screenshotWindow.show()

    def showGrabWindow(self):
        self.sigScreenShot.emit()  # 创建并显示全屏截图窗口
        self.activateWindow()  # 激活窗口以在最顶部显示
        self.setWindowState(Qt.WindowActive)  # 设置为激活窗口,以便使用快捷键
        self.show()  # 显示抓取窗口(主窗口)

    def keyPressEvent(self, event):  # Alt+Q键或ESC关闭窗口退出程序, Q键隐藏抓取窗口
        if event.key() == Qt.Key_Escape:
            self.close(), exit(0)
        elif event.key() == Qt.Key_Q:
            if QApplication.keyboardModifiers() == Qt.AltModifier:
                self.close(), exit(0)
            else:
                self.hide()
                self.screenshotWindow.hide()

    def paintMask(self):
        self.mask = self.blackMask.copy()
        pp = QPainter(self.mask)
        pen = QPen()
        pen.setStyle(Qt.NoPen)
        pp.setPen(pen)
        brush = QBrush(Qt.white)
        pp.setBrush(brush)
        pp.drawRect(QRect(self.startPoint, self.endPoint))
        self.setMask(QBitmap(self.mask))
        self.update()

    def paintEvent(self, event):
        if self.isDrawing:
            self.paintMask()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.isDrawing = True
            self.startPoint = event.pos()  # 相对有效区域左上角点的坐标
            self.endPoint = self.startPoint

    def mouseMoveEvent(self, event):
        if Qt.LeftButton and self.isDrawing:
            self.endPoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.endPoint = event.pos()
            self.paintMask()  # 确保mask绘制完整
            self.isDrawing = False

            if self.endPoint.x() - self.startPoint.x() > 10 and self.endPoint.y(
            ) - self.startPoint.y() > 10:  # 框选区域太小或从右至左框选不进行截图
                self.screenshot = self.screenshot_full_screen.copy(
                    QRect(self.startPoint, self.endPoint))  # 截取框选区域
                self.hide()  # 隐藏抓取工具窗口
                self.screenshotWindow.close()  # 关闭全屏截图显示窗口
                self.sigDisplay.emit()  # 触发信号创建新的子窗口来显示截图

            self.setMask(QBitmap((self.blackMask.copy())))  # 框选操作结束, 恢复窗口mask
Esempio n. 4
0
class WScreenShot(QWidget):
    storePath = 'screenShot.jpg'
    imageType = 'JPG'
    quality = 100

    def __init__(self, parent=None):
        super(WScreenShot, self).__init__(parent)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.setStyleSheet('''background-color:black; ''')
        self.setWindowOpacity(0.6)
        desktopRect = QDesktopWidget().screenGeometry()
        self.setGeometry(desktopRect)
        self.setCursor(Qt.CrossCursor)
        self.blackMask = QBitmap(desktopRect.size())
        self.blackMask.fill(Qt.black)
        self.mask = self.blackMask.copy()
        self.isDrawing = False
        self.startPoint = QPoint()
        self.endPoint = QPoint()

    def paintEvent(self, event):
        if self.isDrawing:
            self.mask = self.blackMask.copy()
            pp = QPainter(self.mask)
            pen = QPen()
            pen.setStyle(Qt.NoPen)
            pp.setPen(pen)
            brush = QBrush(Qt.white)
            pp.setBrush(brush)
            pp.drawRect(QRect(self.startPoint, self.endPoint))
            self.setMask(QBitmap(self.mask))

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.startPoint = event.pos()
            self.endPoint = self.startPoint
            self.isDrawing = True

    def mouseMoveEvent(self, event):
        if self.isDrawing:
            self.endPoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.endPoint = event.pos()
            screenShot = QApplication.primaryScreen().grabWindow(
                QApplication.desktop().winId())
            rect = QRect(self.startPoint, self.endPoint)
            outputRegion = screenShot.copy(rect)
            outputRegion.save(self.storePath,
                              format=self.imageType,
                              quality=self.quality)
            self.close()

    def handleClick(self):
        if not self.isVisible():
            self.show()

    def handleClose(self):
        self.close()
Esempio n. 5
0
class WScreenShot(QWidget):
    def __init__(self, Init, chooseRange, parent=None):

        super(WScreenShot, self).__init__(parent)
        self.setWindowFlags(Qt.FramelessWindowHint
                            | Qt.WindowStaysOnTopHint)  # | Qt.Tool)
        self.setWindowState(Qt.WindowFullScreen | Qt.WindowActive)
        self.setStyleSheet('''background-color:black; ''')
        self.setWindowOpacity(0.6)
        desktopRect = QDesktopWidget().screenGeometry()
        self.setGeometry(desktopRect)
        self.setCursor(Qt.CrossCursor)
        self.blackMask = QBitmap(desktopRect.size())
        self.blackMask.fill(Qt.black)
        self.mask = self.blackMask.copy()
        self.isDrawing = False
        self.startPoint = QPoint()
        self.endPoint = QPoint()
        self.Init = Init
        self.chooseRange = chooseRange

    def paintEvent(self, event):

        try:
            if self.isDrawing:
                self.mask = self.blackMask.copy()
                pp = QPainter(self.mask)
                pen = QPen()
                pen.setStyle(Qt.NoPen)
                pp.setPen(pen)
                brush = QBrush(Qt.white)
                pp.setBrush(brush)
                pp.drawRect(QRect(self.startPoint, self.endPoint))
                self.setMask(QBitmap(self.mask))
        except Exception:
            write_error(format_exc())

    def mousePressEvent(self, event):

        try:
            if event.button() == Qt.LeftButton:
                self.startPoint = event.pos()
                self.endPoint = self.startPoint
                self.isDrawing = True
        except Exception:
            write_error(format_exc())

    def mouseMoveEvent(self, event):

        try:
            if self.isDrawing:
                self.endPoint = event.pos()
                self.update()
        except Exception:
            write_error(format_exc())

    def getRange(self):

        start = findall(r'(\d+), (\d+)', str(self.startPoint))[0]
        end = findall(r'\d+, \d+', str(self.endPoint))[0]
        end = end.split(', ')

        X1 = int(start[0])
        Y1 = int(start[1])
        X2 = int(end[0])
        Y2 = int(end[1])

        if X1 > X2:
            tmp = X1
            X1 = X2
            X2 = tmp

        if Y1 > Y2:
            tmp = Y1
            Y1 = Y2
            Y2 = tmp

        with open(folder_path + '/config/settin.json') as file:
            data = load(file)

        data["range"]["X1"] = X1
        data["range"]["Y1"] = Y1
        data["range"]["X2"] = X2
        data["range"]["Y2"] = Y2

        with open(folder_path + '/config/settin.json', 'w') as file:
            dump(data, file, indent=2)

        self.chooseRange.setGeometry(X1, Y1, X2 - X1, Y2 - Y1)
        self.chooseRange.Label.setGeometry(0, 0, X2 - X1, Y2 - Y1)
        self.chooseRange.show()
        # screenshot = QApplication.primaryScreen().grabWindow(QApplication.desktop().winId())
        # screenshot.save(folder_path + '/config/full.jpg', format='JPG', quality=100)
        # outputRegion = screenshot.copy(QRect(int(X1), int(Y1), int(X2 - X1), int(Y2 - Y1)))
        # outputRegion.save(folder_path + '/config/image.jpg', format='JPG', quality=100)

    def updata_Init(self):

        try:
            if self.Init.mode == False:
                self.Init.start_login()
        except Exception:
            write_error(format_exc())

    def mouseReleaseEvent(self, event):

        try:
            if event.button() == Qt.LeftButton:
                self.endPoint = event.pos()
                self.getRange()

                self.close()
                self.updata_Init()
        except Exception:
            write_error(format_exc())

    def keyPressEvent(self, QKeyEvent):
        if QKeyEvent.key() == Qt.Key_Escape:
            self.close()
Esempio n. 6
0
class Ui_ScShot_Logic(QWidget, Ui_ScShot):
    """
    截屏逻辑:
    1、一打开截屏,就先创建屏幕截图pixScreenshot,并设置为主窗口的背景,并设置窗口无标题栏。再创建一个QWidget(wTop),
    用来作为全屏的阴影遮盖,设置背景样式rgba的透明,它的大小以及主窗口的大小都是全屏大小(和全屏截图一样大)。功能
    按钮容器wFunc,以及其它功能不作介绍,代码里有注释。
    2、设置鼠标按下、移动,释放,来画出一个矩形框。在移动的时候设置标记(flagDrawing)为True,并self.update刷新界面,在刷新
    界面时就能设置画笔和画刷来画出所要截图的范围
    3、这第三步,其实有一部分在第一处就要设置。这对我来说是个难点,研究了两天,才瞎猫碰到死耗子搞成了。原本在网上复制的
    截屏代码,竟然矩形选框内被穿透了,直接可以操作内部(此程序下面此范围内),很是让人无语。才研究两天,总算总算解决了。
    此程序就是用pyqt5的setMask遮罩效果来完成对我来说主要的功能的。
    在初始化处先创建一个QBitmap(blackMask),并填充成黑色,然后设置QWidget(wTop)的遮罩为blackMask。这里简单说一下,如果
    在遮罩的地方用白色画刷涂的地方会失去遮罩(也就是wTop的背景),显示出下层窗口(窗口已经设置为全屏截图)的图片。
    用黑色画刷涂的话,就是显示出wTop的背景。这里就样photoShop中的那个蒙版效果,原理是一样的。重要处在paintEvent事件中,
    已经有注释。
    """

    def __init__(self, parent):
        super(Ui_ScShot_Logic, self).__init__()
        self.setupUi(self) # 加载设计师画的界面
        self.p = parent

        # 主窗口设置
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)  # 隐藏标题栏
        self.pixPrtSc = QApplication.primaryScreen().grabWindow(QApplication.desktop().winId())  # 截取整个屏幕(QPixmap类型)
        self.resize(self.pixPrtSc.size())  # 设置主窗口大小
        p = QPalette()
        p.setBrush(self.backgroundRole(), QBrush(self.pixPrtSc))
        self.setPalette(p)  # 设置主窗口背景
        self.flagDrawing = False  # 主窗口的鼠标拖动标记,已经为子

        self.wid = QLabel(self)
        self.wid.lower()
        # self.wid.raise_() # 最上层
        self.wid.resize(self.size())
        self.wid.move(0, 0)
        self.wid.setStyleSheet('border:3px solid #00FFFF;')
        # self.wid.hide()


        # 阴影容器设置
        self.wTop.resize(self.size())  # 设置wTop也为屏幕大小
        self.blackMask = QBitmap(self.size())  # 创建位图,全屏大小
        self.blackMask.fill(Qt.black)  # 填充位图为全黑。显示效果为原本wTop的背影,如果全白,相当于把wTop擦掉了。
        self.wTop.setMask(self.blackMask)  # 设置self.wTop的遮罩为self.blackMask
        self.wTop.enterEvent = self.wTop_EnterEvent  # 设置wTop的鼠标进入事件。事件内有详细注释。
        self.flagWTopEnter = False  # wTop的鼠标进入事件的标记

        # 其它需要初始化的
        self.btnOk.clicked.connect(self.slot_ScShot_btns)
        self.btnSaveAs.clicked.connect(self.slot_ScShot_btns)
        self.wFunc.hide()  # 先隐藏功能按钮容器
        self.wInfo.hide() # 本来可以不用隐藏,再让后面显示,但是那样它会闪一下。因为原来的位置是在Qt设计师中乱放的。
        self.strDpi = "0 x 0"
        self.flag = False

        # lab = QLabel('aaa', self.wTop)
        # lab.resize(300, 300)
        # lab.setStyleSheet('background:red;')

    def wTop_EnterEvent(self, e):
        """
        鼠标进入wTop子QWidget内,为了处理一打开截屏界面wInfo初始跟随鼠标状态,只需要一次,因为有self的鼠标
        mouseMoveEvent处理后续动作。之所以要做一个标记flagWTopEnter为False才有动作,是因为在截图时,画的矩形
        选区内是self的焦点,之外才是wTop的焦点。鼠标在矩形内外来回移动会多次处理此事件动作,关键是此动作和
        self的鼠标移动件事有冲突,都在处理wInfo的鼠标跟随。目前只想到这种方法解决。
        """
        if not self.flagWTopEnter:  # 只有self.flagWTopEnter=False时,not self.flagWTopEnter 才为真
            self.flagWTopEnter = True
            self.imgPrtSc = self.pixPrtSc.toImage()
            self.method_wInfo(e.globalPos().x(), e.globalPos().y())
            self.wInfo.show()
            # rect = QRect(e.globalPos().x() - 13, e.globalPos().y() - 10, 114, 85)  # 截取的范围
            # copyZoomIn = self.pixPrtSc.copy(rect)
            # self.labInfoZoomIn.setPixmap(copyZoomIn)

    def method_wInfo(self, pointX, pointY):
        """QWidget(wInfo)的移动,以及wInfo内的QLebal(labInfoZoomIn)的图片设置"""
        self.wInfo.move(pointX + 5, pointY + 20)
        color = self.imgPrtSc.pixelColor(pointX, pointY)
        self.strRgb = str(color.getRgb()[:-1])
        self.textEdInfoRgb.setText(f"DPI:({self.strDpi})<br/>RGB:{self.strRgb}")  # 13 10
        # 参数32,24,是矩形的宽高,是要QLabel(labInfoZoomIn)设置的图片,因为在设计师中已经设置setScaledContents为True,
        # 所以它放比它小的图片会放大。而pointX-14和pointY-10,是矩形的左上角位置,需要减多少,是看原图大小的宽高除以2,
        # 再减去十字线(宽4px)的一半(32/2-2=14,24/2-2=10。labInfoZoomIn的尺寸是116x84
        # 这样,labInfoZoomIn在显示图片的时候,十字交差处才会是鼠标指针点的位置。
        rect = QRect(pointX-14, pointY-10, 32, 24)  # 截取的范围
        copyZoomIn = self.pixPrtSc.copy(rect)
        self.labInfoZoomIn.setPixmap(copyZoomIn)

    def slot_ScShot_btns(self):
        sender = self.sender()
        filePath = self.p.lineEdFilePath.text()
        rq = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
        self.copyPixPrtSc = self.pixPrtSc.copy(self.rect)  # 截取矩形区内的图片
        PlaySound('prtSc.wav', flags=1)
        if sender == self.btnOk:
            if not os.path.exists(filePath):  # 如果此路径没有此文件夹,就创建一个
                os.mkdir(filePath)
            imgPath = f"{filePath}/{rq}.png"
            self.copyPixPrtSc.save(imgPath, format='png', quality=100)
        elif sender == self.btnSaveAs:
            currentPath = filePath + f"/{rq}.png"
            fileName, _ = QFileDialog.getSaveFileName(self, "另存为", currentPath, f"PNG File(*.png);;All Files(*)")
            if fileName:
                self.copyPixPrtSc.save(fileName, format='png', quality=100)
                self.close()

    def paintEvent(self, event):
        if self.flag:
            pointX = self.endPoint.x()
            pointY = self.endPoint.y()
            self.method_wInfo(pointX, pointY)  # 调用移动方法

        if self.flagDrawing:
            self.mask = self.blackMask.copy()  # 必须要拷贝,其实我也不是很理解这句为何。
            pp = QPainter(self.mask)  # 参数一定要是拷贝的QPixmap(self.mask)
            pen = QPen()  # 创建画笔    Qt.green, 13, Qt.DashDotLine, Qt.RoundCap, Qt.RoundJoin
            pen.setStyle(Qt.NoPen)
            pp.setPen(pen)
            brush = QBrush(Qt.white)  # 创建画刷
            pp.setBrush(brush)
            rect = QRect(self.startPoint, self.endPoint)
            pp.drawRect(rect)  # 画矩形
            self.wTop.setMask(QBitmap(self.mask))  # 是wTop设置遮罩,不是主窗口。不然会穿透的。

            self.strDpi = f"{abs(rect.width())} x {abs(rect.height())}"
            # self.wid.setStyleSheet('border:2px dashed #00FFFF;') # 改变边宽和样式(虚线)
            # self.wid.setGeometry(rect.adjusted(-2, -2, 2, 2)) # 上下左右都往外偏移2px,因为上面设置border为2px
            # self.wid.setGeometry( rect.x()-2, rect.y()-2,abs(rect.width())+2,abs(rect.height())+2) # 上下左右都往外偏移2px,因为上面设置border为2px
            try:
                sX, sY, eX, eY = self.startPoint.x(), self.startPoint.y(), self.endPoint.x(), self.endPoint.y()
                p2 = QPainter(self)
                pen2 = QPen(QColor('#00FFFF'), 1)
                p2.setPen(pen2)
                p2.drawRect(rect)
                # 下面这四句忘了本来要做什么的了
                # p2.fillRect(rect, QColor('background:rgba(0,0,0,100);'))
                # rect.adjust(50, 50, -50, -50)
                # p2.drawRect(rect)
                # p2.fillRect(rect, Qt.red)


                listPointRect = [(sX, sY), (sX + (eX - sX) / 2, sY), (eX, sY), (eX, sY + (eY - sY) / 2),
                                 (eX, eY), (sX + (eX - sX) / 2, eY), (sX, eY), (sX, sY + (eY - sY) / 2)]
                for x, y in listPointRect:
                    p2.drawRect(x - 3, y - 3, 6, 6)
                    p2.fillRect(x - 3, y - 3, 6, 6, QBrush(QColor('#00FFFF')))


                # p2.begin(self)
                # path = QPainterPath()
                # path.addRect(QRectF(self.startPoint, self.endPoint))

                # self.wid.setGeometry(QRect(*path.controlPointRect().getRect()).adjusted(-20, -20, 20, 20))
                # p2.drawRect(QRectF(*(sX, sY), *(sX + (eX - sX) / 2, sY)))



                # listPointRect = [(sX, sY), (sX+(eX-sX)/2, sY), (eX, sY), (eX, sY+(eY-sY)/2),
                #                  (eX, eY), (sX+(eX-sX)/2, eY), (sX, eY), (sX, sY+(eY-sY)/2)]
                # path2 = QPainterPath()
                # for x, y in listPointRect:
                #     path2.addRect(x-3, y-3, 6, 6)
                # p2.fillPath(path2, QBrush(QColor('#00FFFF')))
                # path.connectPath(path2) # 连接两个闭合路径
                # path.translate(50, 50) # 偏移到某点
                # p2.drawPath(path)
                # self.wid.setStyleSheet('border:none;')
                # p2.end()

            except Exception as e:
                print(e)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            # self.wid.hide()
            self.wTop.setStyleSheet('background:rgba(0,0,0,100);') # 设置背景透明度,阴影效果。鼠标按下时再出现
            self.wInfo.show()
            self.startPoint = event.pos()
            self.endPoint = self.startPoint
            self.wFunc.hide()  # 鼠标按下时隐藏功能按钮容器
            self.flagDrawing = True
        elif event.button() == Qt.RightButton:
            self.close()

    def mouseMoveEvent(self, event):
        """
        必须为子控件设置鼠标跟踪setMouseTracking(True),不然鼠标在控件上时,就不再追踪了。
        已经在Qt设计师中设置好了
        """
        self.flag = True
        self.endPoint = event.pos()
        self.update()

        # self.pointX = event.globalPos().x()  # event.pos()也行
        # self.pointY = event.globalPos().y()
        # self.flag = True
        # # self.method_wInfo_move(pointX, pointY)  # 调用移动方法
        # if self.flagDrawing:
        #     self.endPoint = event.pos()
        # self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.endPoint = event.pos()
            self.rect = QRect(self.startPoint, self.endPoint)  # 截取的范围
            shotX, shotY, shotWidth, shotHeight = self.rect.getRect()
            wFuncWidth, wFuncHeight = self.wFunc.width(), self.wFunc.height()
            # 以下if语句是判断鼠标释放后,最后一点到窗口边缘时,功能按钮容器超界问题
            if shotWidth < 0:
                moveX = shotX + shotWidth - (wFuncWidth + shotWidth)  # 这里width是负数,这里用+号相当于减去
            else:
                moveX = shotX + shotWidth - wFuncWidth
            if shotHeight < 0:
                moveY = shotY
            else:
                moveY = shotY + shotHeight
            if moveX < 0:
                moveX = 0
            if self.pixPrtSc.height() - moveY < wFuncHeight:
                moveY = moveY - shotHeight - wFuncHeight
            self.wFunc.move(moveX, moveY)
            self.wFunc.show() # 鼠标释放时显示功能按钮容器
            self.wInfo.hide() # 鼠标释放时隐藏信息显示容器
            self.flagDrawing = False
            self.flag = False #

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.close()