如何让 PyQt 窗口在其“X"时调用方法?关闭按钮被选中 [英] How to have a PyQt window call a method when its "X" close button is selected

查看:13
本文介绍了如何让 PyQt 窗口在其“X"时调用方法?关闭按钮被选中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在选择 PyQt 窗口的X"关闭按钮时调用一个方法.轻快地,我有一个对象 QtGui.QWidget 的类,我希望它在使用X"关闭按钮关闭窗口时调用它的一个方法,以便结束一些子进程.这怎么可能?

I'm trying to have a method called when the "X" close button of a PyQt window is selected. Briskly, I have a class of the object QtGui.QWidget and I want it to call one of its methods when the window is closed using the "X" close button in order to wrap up some subprocesses. How could this be done?

代码如下所示.我想调用的类interface的方法是stylusProximityControlOff().此方法会终止一个可能有点混乱的子进程,但这是一个单独的问题.

The code is shown below. The method of the class interface that I want to have called is stylusProximityControlOff(). This method terminates a subprocess which is potentially a little messy, but that is a separate problem.

无论如何,如果选择X"时调用该方法,我将不胜感激.

Anyway, I would appreciate suggestions on having that method called when the "X" is selected.

#!/usr/bin/env python

"""
spin, a small utility to assist in setting usage modes of laptop-tablet devices

Usage:
    spin.py
    spin.py -h | --help
    spin.py --nogui
Options:
    -h,--help      : show this help message
    --nogui        : non-GUI mode
"""

from docopt import docopt
import os
import sys
import subprocess
from multiprocessing import Process
import time
from PyQt4 import QtGui
import logging

# logging
logger = logging.getLogger(__name__)
logging.basicConfig()
logger.level = logging.INFO

class interface(QtGui.QWidget):
    def __init__(
        self,
        docopt_args=None
    ):
        self.docopt_args=docopt_args
        super(interface, self).__init__()
        logger.info("running spin")
        # engage stylus proximity control
        self.stylusProximityControlOn()
        if not docopt_args["--nogui"]:
            # create buttons
            buttonsList = []
            # button: tablet mode
            buttonModeTablet = QtGui.QPushButton('tablet mode', self)
            buttonModeTablet.clicked.connect(self.engageModeTablet)
            buttonsList.append(buttonModeTablet)
            # button: laptop mode
            buttonModeLaptop = QtGui.QPushButton('laptop mode', self)
            buttonModeLaptop.clicked.connect(self.engageModeLaptop)
            buttonsList.append(buttonModeLaptop)
            # button: left
            buttonLeft = QtGui.QPushButton('left', self)
            buttonLeft.clicked.connect(self.engageLeft)
            buttonsList.append(buttonLeft)
            # button: right
            buttonRight = QtGui.QPushButton('right', self)
            buttonRight.clicked.connect(self.engageRight)
            buttonsList.append(buttonRight)
            # button: inverted
            buttonInverted = QtGui.QPushButton('inverted', self)
            buttonInverted.clicked.connect(self.engageInverted)
            buttonsList.append(buttonInverted)
            # button: normal
            buttonNormal = QtGui.QPushButton('normal', self)
            buttonNormal.clicked.connect(self.engageNormal)
            buttonsList.append(buttonNormal)
            # button: touchscreen on
            buttonTouchscreenOn = QtGui.QPushButton('touchscreen on', self)
            buttonTouchscreenOn.clicked.connect(self.engageTouchscreenOn)
            buttonsList.append(buttonTouchscreenOn)
            # button: touchscreen off
            buttonTouchscreenOff = QtGui.QPushButton('touchscreen off', self)
            buttonTouchscreenOff.clicked.connect(self.engageTouchscreenOff)
            buttonsList.append(buttonTouchscreenOff)
            # button: touchpad on
            buttonTouchpadOn = QtGui.QPushButton('touchpad on', self)
            buttonTouchpadOn.clicked.connect(self.engageTouchpadOn)
            buttonsList.append(buttonTouchpadOn)
            # button: touchpad off
            buttonTouchpadOff = QtGui.QPushButton('touchpad off', self)
            buttonTouchpadOff.clicked.connect(self.engageTouchpadOff)
            buttonsList.append(buttonTouchpadOff)
            # button: nipple on
            buttonNippleOn = QtGui.QPushButton('nipple on', self)
            buttonNippleOn.clicked.connect(self.engageNippleOn)
            buttonsList.append(buttonNippleOn)
            # button: nipple off
            buttonNippleOff = QtGui.QPushButton('nipple off', self)
            buttonNippleOff.clicked.connect(self.engageNippleOff)
            buttonsList.append(buttonNippleOff)
            # button: stylus proximity on
            buttonStylusProximityControlOn = QtGui.QPushButton('stylus proximity on', self)
            buttonStylusProximityControlOn.clicked.connect(self.engageStylusProximityControlOn)
            buttonsList.append(buttonStylusProximityControlOn)
            # button: stylus proximity off
            buttonStylusProximityControlOff = QtGui.QPushButton('stylus proximity off', self)
            buttonStylusProximityControlOff.clicked.connect(self.engageStylusProximityControlOff)
            buttonsList.append(buttonStylusProximityControlOff)
            # set button dimensions
            buttonsWidth=150
            buttonsHeight=60
            for button in buttonsList:
                button.setFixedSize(buttonsWidth, buttonsHeight)
            # set layout
            vbox = QtGui.QVBoxLayout()
            vbox.addStretch(1)
            for button in buttonsList:
                vbox.addWidget(button)
                vbox.addStretch(1)  
            self.setLayout(vbox)
            # window
            self.setGeometry(200, 200, 150, 100)
            self.setWindowTitle('spin')
            self.show()
    elif docopt_args["--nogui"]:
            logger.info("non-GUI mode")
    def displayLeft(self):
        logger.info("changing display to left")
        os.system('xrandr -o left')
    def displayRight(self):
        logger.info("changing display to right")
        os.system('xrandr -o right')
    def displayInverted(self):
        logger.info("changing display to inverted")
        os.system('xrandr -o inverted')
    def displayNormal(self):
        logger.info("changing display to normal")
        os.system('xrandr -o normal')
    def touchscreenLeft(self):
        logger.info("changing touchscreen to left")
        os.system('xinput set-prop "ELAN Touchscreen" "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1')
    def touchscreenRight(self):
        logger.info("changing touchscreen to right")
        os.system('xinput set-prop "ELAN Touchscreen" "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1')
    def touchscreenInverted(self):
        logger.info("changing touchscreen to inverted")
        os.system('xinput set-prop "ELAN Touchscreen" "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1')
    def touchscreenNormal(self):
        logger.info("changing touchscreen to normal")
        os.system('xinput set-prop "ELAN Touchscreen" "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1')
    def touchscreenOn(self):
        logger.info("changing touchscreen to on")
        os.system('xinput enable "ELAN Touchscreen"')
    def touchscreenOff(self):
        logger.info("changing touchscreen to off")
        os.system('xinput disable "ELAN Touchscreen"')
    def touchpadOn(self):
        logger.info("changing touchpad to on")
        os.system('xinput enable "SynPS/2 Synaptics TouchPad"')
    def touchpadOff(self):
        logger.info("changing touchpad to off")
        os.system('xinput disable "SynPS/2 Synaptics TouchPad"')
    def nippleOn(self):
        logger.info("changing nipple to on")
        os.system('xinput enable "TPPS/2 IBM TrackPoint"')
    def nippleOff(self):
        logger.info("changing nipple to off")
        os.system('xinput disable "TPPS/2 IBM TrackPoint"')
    def stylusProximityControl(self):
        previousProximityStatus = None
        while True:
            proximityCommand = 'xinput query-state "Wacom ISDv4 EC Pen stylus" | grep Proximity | cut -d " " -f3 | cut -d "=" -f2'
            proximityStatus = subprocess.check_output(proximityCommand, shell=True).lower().rstrip()
            if (proximityStatus == "out") and (previousProximityStatus != "out"):
                logger.info("stylus inactive")
        self.touchscreenOn()
            elif (proximityStatus == "in") and (previousProximityStatus != "in"):
                logger.info("stylus active")
        self.touchscreenOff()
        previousProximityStatus = proximityStatus
            time.sleep(0.25)
    def stylusProximityControlOn(self):
        logger.info("changing stylus proximity control to on")
    self.process1 = Process(target=self.stylusProximityControl)
    self.process1.start()
    def stylusProximityControlOff(self):
        logger.info("changing stylus proximity control to off")
    self.process1.terminate()
    def engageModeTablet(self):
        logger.info("engaging mode tablet")
        self.displayLeft()
    self.touchscreenLeft()
        self.touchscreenOff()
        self.touchpadOff()
        self.nippleOff()
    def engageModeLaptop(self):
        logger.info("engaging mode laptop")
        self.displayNormal()
        self.touchscreenNormal()
        self.touchscreenOn()
        self.touchpadOn()
        self.nippleOn()
    def engageLeft(self):
        logger.info("engaging mode left")
        self.displayLeft()
        self.touchscreenLeft()
    def engageRight(self):
        logger.info("engaging mode right")
        self.displayRight()
        self.touchscreenRight()
    def engageInverted(self):
        logger.info("engaging mode inverted")
        self.displayInverted()
        self.touchscreenInverted()
    def engageNormal(self):
        logger.info("engaging mode normal")
        self.displayNormal()
        self.touchscreenNormal()
    def engageTouchscreenOn(self):
        self.touchscreenOn()
    def engageTouchscreenOff(self):
        self.touchscreenOff()
    def engageTouchpadOn(self):
        self.touchpadOn()
    def engageTouchpadOff(self):
        self.touchpadOff()
    def engageNippleOn(self):
        self.nippleOn()
    def engageNippleOff(self):
        self.nippleOff()
    def engageStylusProximityControlOn(self):
        self.stylusProximityControlOn()
    def engageStylusProximityControlOff(self):
        self.stylusProximityControlOff()
def main(docopt_args):
    application = QtGui.QApplication(sys.argv)
    interface1 = interface(docopt_args)
    sys.exit(application.exec_())
if __name__ == '__main__':
    args = docopt(__doc__)
    main(args)

推荐答案

一种方法是重新实现 QWidget 的 closeEvent 方法,让它调用加入(或终止)子进程的方法,然后让它调用 deleteLater()destroy().

One approach is to reimplement the closeEvent method of the QWidget, having it call the method that joins (or terminates) subprocesses and then having it call either deleteLater() or destroy().

    def closeEvent(self, event):
        logger.info("stopping spin")
        self.stylusProximityControlOff()
        self.deleteLater() 

这篇关于如何让 PyQt 窗口在其“X"时调用方法?关闭按钮被选中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆