简体   繁体   English

pyside2 通过窗口“X”连接到自定义退出方法

[英]pyside2 connect close by Window "X" to custom exit method

I am using Qt Designer for the GUI layout and do load the .ui file into python with the help of QUILoader.我使用 Qt Designer 进行 GUI 布局,并在 QUILoader 的帮助下将 .ui 文件加载到 python 中。

I managed to connect a 'Quit' Button to my 'quit_app' method.我设法将“退出”按钮连接到我的“quit_app”方法。

My question is how to connect this method in the event that the user tries to close the Window with the 'X'.我的问题是,如果用户尝试使用“X”关闭窗口,如何连接此方法。

Thanks in advance!提前致谢!

---> PYTHON CODE <--- ---> 蟒蛇代码 <---

import sys
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication
from PySide2.QtCore import QFile

class main_w(object):
    def __init__(self):
        # load ui; create w
        self.file = QFile("simple_quit.ui")
        self.file.open(QFile.ReadOnly)
        self.loader = QUiLoader()
        self.w = self.loader.load(self.file)

        # connections

        # Quit Button
        self.w.QUITButton.clicked.connect(self.quit_app)

        # ??? Window's X Button ???
        # THROWS ERROR:
        self.w.closeEvent.connect(self.quit_app)

    def quit_app(self):
        # some actions to perform before actually quitting:
        print('CLEAN EXIT')
        app.exit()

    def show(self):
        self.w.show()

app = QApplication(sys.argv)
w = main_w()
w.show()
sys.exit(app.exec_())

---> UI XML <--- ---> UI XML <---

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="QUITButton">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>100</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>quit</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

In Qt there are 2 concepts: the signal and the event, the signal is connected to a slot but in the case of events you can not, and then you have the latter.在 Qt 中有 2 个概念:信号和事件,信号连接到一个插槽,但在事件的情况下你不能,然后你有后者。 In the case of the signal, it is known who is the receiver since it is declared in the connection, but the events are not, this is sent through the parent-child relationship tree of the QObject s and can be accepted or ignored according to the case.在信号的情况下,知道谁是接收者,因为它是在连接中声明的,但事件不是,这是通过QObject的父子关系树发送的,可以根据案子。

So that's why you have that problem.所以这就是为什么你有这个问题。


The solution in general would be to overwrite the closeEvent method:通常的解决方案是覆盖 closeEvent 方法:

C++ version: C++ 版本:

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (maybeSave()) {
        writeSettings();
        event->accept();
    } else {
        event->ignore();
    }
}

Python version:蟒蛇版本:

def closeEvent(self, event):
    if maybeSave():
        writeSettings()
        event.accept()
    else:
        event.ignore()

But for this it is necessary to inherit from the class, but in your case it is not possible so there is another solution, install an event filter:但是为此,有必要从类继承,但在您的情况下这是不可能的,因此有另一种解决方案,安装事件过滤器:

import sys
from PySide2 import QtCore, QtWidgets, QtUiTools


class Manager(QtCore.QObject):
    def __init__(self):
        super(Manager, self).__init__()
        # load ui; create w
        file = QtCore.QFile("simple_quit.ui")
        file.open(QtCore.QFile.ReadOnly)
        loader = QtUiTools.QUiLoader()
        self.w = loader.load(file)

        # connections
        # Quit Button
        self.w.QUITButton.clicked.connect(self.quit_app)

        self.w.installEventFilter(self)

    def eventFilter(self, obj, event):
        if obj is self.w and event.type() == QtCore.QEvent.Close:
            self.quit_app()
            event.ignore()
            return True
        return super(Manager, self).eventFilter(obj, event)

    @QtCore.Slot()
    def quit_app(self):
        # some actions to perform before actually quitting:
        print('CLEAN EXIT')
        self.w.removeEventFilter(self)
        app.quit()

    def show(self):
        self.w.show()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = Manager()
    w.show()
    sys.exit(app.exec_())
def closeEvent(self, event):
    if pendingChanges == True: #write your required condition/check 
        self.save()            #include required your functionality(eg. self.save())         
        event.accept()
    else:
        event.ignore()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM