Fabii
Fabii

Reputation: 3890

PyQt4 :Detect window close event from child class

class Ui_MainWindow(QtGui.QWidget):

  def __init__(self):
      super(Ui_MainWindow, self).__init__()
      print('[Ui_MainWindow] __init__')

  def closeEvent(self, event):
      print("[ Ui_MainWindow closeEvent] event triggered...")

...

class Ui_Wrapper(Ui_MainWindow):
    def __init__(self, MainWindow):
        super(Ui_Wrapper, self).__init__()

        self.MainWindow = MainWindow
        self.setupUi(MainWindow)
        self.add_listeners()

        MainWindow.show()

    def closeEvent(self, event):
        print("[ Ui_Wrapper closeEvent] event triggered...")
        super(Ui_Wrapper,self).closeEvent(event)
...

Snippet A:

if __name__ == "__main__":
    ...
    print(sys.argv)
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_Wrapper(MainWindow)
    sys.exit(app.exec_())

Snippet B:

app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
...
ui.show()

Snippet A and B both render the GUI, but only snippet B allows me to capture the closeEvent. I am using PyQT design tool to build the GUI, the main GUI file is overwritten each time, so I need a wrapper (Ui_Wrapper) to handle listener setup etc. This is why I need to use snippet A .

Any ideas ? Have I missed something in my init function ?

Upvotes: 0

Views: 677

Answers (2)

Gary Hughes
Gary Hughes

Reputation: 4510

Are you running your .ui file through the uic tool to create a Python file containing your Ui_MainWindow? I'd expect the output of that to look more like this:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'C:\Users\gary\Desktop\mw\MainWindow.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(400, 300)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "Form", None))


The output will be overwritten each time you change your UI in Designer and re-run uic, like you say. So in a separate file you import the Ui_MainWindow and subclass to override closeEvent():

from PyQt4 import QtGui
from Ui_MainWindow import Ui_MainWindow


class MainWindow(QtGui.QWidget, Ui_MainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

    def closeEvent(self, event):
        print("[ MainWindow closeEvent] event triggered...")
        super(MainWindow, self).closeEvent(event)


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

Upvotes: 0

Fabii
Fabii

Reputation: 3890

I found a workaround that I can use for now using ui.loadUi . This allows me to make changes in QT Designer without affecting my code. There is a detailed article about it here : import PyQT ui files

class Ui_MainWindow(QtGui.QMainWindow):

    def __init__(self):
        super(Ui_MainWindow, self).__init__()
        uic.loadUi('app.ui', self)
        self.add_listeners()
        self.show()

Upvotes: 1

Related Questions