Solved PySide2, Qt Creator, how to override MainWindow.closeEvent()?
-
I need to confirm close main window when unsaved changes user may want to save.
The normal way to do this is sub-class from
QMainWindow
and overridecloseEvent()
. However, I do not begin to understand how to do this from my environment:- We use Qt Designer, so it produces the class:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
That goes into
mainwindow.cpp
. But I don't think that is used in PySide2 environment. It processes themainwindow.ui
file viapyside2-uic
to producemainwindow.py
. That in turn then has# WARNING! All changes made in this file will be lost!
, so I can't alter that.- I can't alter the original
.cpp
(even if I wanted to), as I shall be wanting to call a Python/PySide2 function in the override ofQMainWindow.closeEvent()
, this all needs to be done at the Python/Pyside2 side, not C++.
So I am lost here: how am I supposed to override
QMainWindow.closeEvent()
orMainWindow.closeEvent()
from Python, given that it is not my code which is producing theMainWindow
class derived fromQMainWindow
??For now, I am having a go at https://stackoverflow.com/a/53102880/489865. There the poster recognises the problem in a
QUiLoader
situation from Python, where he saysBut 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:
I do not have
QUiLoader
in code, but I'm thinking nonetheless I am facing a similar problem(?). Should I stick with that approach ofMainWindow.installEventFilter
, or is there a neater way of overridingMainWindow.closeEvent()
here? I might still need the latter if at a future date I need to override a different method.... -
@Denni-0
Hi Denni. I know your views about Qt Designer. This one is not up to me, I'm working on someone else's project where it is to be used for design time whether you or I agree that is a good idea or not! I do know it would have been easy in non-designer code, I've sub-classed and overridden from there before, but that's a not a choice in this instance. -
@Denni-0
That would be sub-classing at the C++ side. That won't help me, it was sub-classing at the Python side I was looking for, but where I couldn't.... It gets complicated! -
Since I posted this question I have come to realize that things are different from what I thought.
Although using Qt Creator to design the UI generates a
mainwindow.cpp
file in whichMainWindow
is a subclass ofQMainWindow
, my assumption that the generatedmainwindow.py
would work the same way seems to be erroneous. Instead I found the code was creating its own explicitQMainWindow()
and then passing that to generated code to fill with the settings frommainwindow.ui
file.I do not know whether that is how it's all supposed to be configured, or whether that is indeed different from the C++ approach, but that's what I see in the code I have.
Anyway, the end result is that means I can create my own Python subclass of
QMainWindow
and pass that instance to the code generated for setting the stuff from Qt Creator. So I can overridecloseEvent()
easily. -
In docs https://doc.qt.io/qtforpython/tutorials/basictutorial/uifiles.html#generating-a-python-class we are shown creating a class
class MainWindow(QMainWindow):
I thought the
pyuic
produced this class definition, and same foruic
with C++. That is what I expected. I think not now. You are supposed to write that yourself. They only produceUi_MainWindow
class. Right?It turns out the code I am working on does not take that approach, hence my confusion. It does not create any
MainWindow
class at all. Instead it creates a plainQMainWindow
instance and then passes that to the generatedUi_MainWindow.setupUi()
. That changes the issue for me, I shall have to ask the author why that approach was adopted....EDIT OK, he said "no reason". So now I am free to create my own subclass of
QMainWindow
in code, and thereby overridecloseEvent()
as required.