如何让 PyQt 窗口在其“X"时调用方法?关闭按钮被选中 [英] How to have a PyQt window call a method when its "X" close button is selected
问题描述
我试图在选择 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屋!