window - 如何让 PyQt 窗口在选择 "X"关闭按钮时调用方法

标签 window pyqt multiprocessing terminate

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

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

无论如何,我希望得到有关在选择“X”时调用该方法的建议。

#!/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()

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

关于window - 如何让 PyQt 窗口在选择 "X"关闭按钮时调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20895645/

相关文章:

python - 如何确定 QSlider 移动的方向?

java - 对 Java 如何在多处理期间共享变量感到困惑

java - Java如何在指定时间在右下角弹出一个小窗口

javascript - Jquery resize() 导致屏幕闪烁和 div 偏移

macos - Flutter Desktop - 从 Mac 生成 .exe

Java线程与CPU核心的关系

python - 具有全局变量的 multiprocessing.Pool

java - 使用按钮关闭窗口

python - QLineEdit python方式中的大写输入

python - 如何为包含动画元素的项目设置 QtDesigner?