closeEvent not running
-
I have my base class here:
class MyWindow: def __init__(self): self.window = loadUiFile(os.path.join(os.path.dirname(__file__), "window.ui")) def closeEvent(self, event): print("closing...") event.accept()
but it does not run. I tried having the class inherit
QWindow
andQWidget
and nothing.
loadUiFile
just returns a read UI file like so:def loadUiFile(file_path): file = QFile(file_path) file.open(QFile.ReadOnly) loader = QUiLoader() window = loader.load(file) return window
-
Hi and welcome to devnet
Your MyWindow is just a Python object subclass hence it has no closeEvent.
-
What do I need to add to it so that it has that method?
-
It should inherit QWidget and but your dynamically loaded UI in a layout set on it.
-
Do you mean
loadUiType
? I tried using that but it kept sayingUi_mywindow
was not defined -
No, as I wrote your MyWindow.
You should start by following a tutorial before trying the dynamic UI route like that. Especially if you want to have custom methods.
-
I attempted to use
loadUiType
to get the QWindow stuff, but it raises this error:NameError: name 'Ui_MainWindow' is not defined
Code is below:window, qwindow = loadUiType(os.path.join(os.path.dirname(__file__), "window.ui")) class MyWindow(window, qwindow):```
-
That's wrong.
Please follow the example shown in QUiLoader documentation.
-
I followed the example and got this:
class MyWindow(QWidget): def __init__(self): super(QWidget, self).__init__() file = QFile(os.path.join(os.path.dirname(__file__), "window.ui")) file.open(QFile.ReadOnly) loader = QUiLoader() window = loader.load(file, self) #window = loadUiFile(os.path.join(os.path.dirname(__file__), "window.ui")) layout = QVBoxLayout() layout.addWidget(window) self.setLayout(layout)
It raises the error
TypeError: PySide6.QtCore.QObject isn't a direct base class of MyWindow
I'm not sure if I read it wrong or if I'm looking at the wrong spot -
What if your replace:
@DoubleFelix said in closeEvent not running:super(QWidget, self).init()
with:
super().__init__()
-
That fixes that error, but now when I try to access elements, it says they don't exist.
self.my_button.clicked.connect(self.button_clicked)
raisesAttributeError: 'MyWindow' object has no attribute 'my_button'
-
That fixes that error, but now when I try to access elements, it says they don't exist.
self.my_button.clicked.connect(self.button_clicked)
raisesAttributeError: 'MyWindow' object has no attribute 'my_button'
@DoubleFelix
I read that you're supposed to do it via:super(MyWindow, self).__init__()
Though whether that equates to
super().__init__()
I don't know.
-
@JonB I still get the same error if I modify it to be that
-
That fixes that error, but now when I try to access elements, it says they don't exist.
self.my_button.clicked.connect(self.button_clicked)
raisesAttributeError: 'MyWindow' object has no attribute 'my_button'
@DoubleFelix said in closeEvent not running:
That fixes that error, but now when I try to access elements, it says they don't exist.
self.my_button.clicked.connect(self.button_clicked)
raisesAttributeError: 'MyWindow' object has no attribute 'my_button'
Because my_button is something that belongs to the widget you created with designer ? If so it's your "window" variable that will have access to it.
-
I tried switching it to
window
and now thecloseEvent
still does nothing. I have this now:class TexasHoldEmServerWindow(QWidget): def __init__(self): super(TexasHoldEmServerWindow, self).__init__() file = QFile(os.path.join(os.path.dirname(__file__), "window.ui")) file.open(QFile.ReadOnly) loader = QUiLoader() window = loader.load(file, self) self.window = loadUiFile(os.path.join(os.path.dirname(__file__), "window.ui")) layout = QVBoxLayout() layout.addWidget(window) self.setLayout(layout) self.window.start_game_button.clicked.connect(self.start_game) def closeEvent(self, event): print("PLS WORK") event.accept()
No errors, but it still doesn't run the function
-
You should learn how inheritance work.
The proper way to add closeEvent handling to your Designer based class is to create a proper class i.e. you cannot use QUiLoader for that.
Since you are using Python, you can cheat and monkey patch your window object (you really should name your variable in a more meaningful way).
-
I do have a different name, I just named it differently for convenience. Although I guess it's less convenient than I thought.
I think I understand how inheritance works, I just don't know how I'd make this a "proper" class while still loading from a UI. I guess I just don't know what I need to inherit to getcloseEvent()
. -
I do have a different name, I just named it differently for convenience. Although I guess it's less convenient than I thought.
I think I understand how inheritance works, I just don't know how I'd make this a "proper" class while still loading from a UI. I guess I just don't know what I need to inherit to getcloseEvent()
.@DoubleFelix
I don't mean to open up a box of asps, but...Are you wedded to using
QUiLoader
/loadUiFile
? This reads the.ui
file generated from Qt Designer at runtime. It does not lend itself to subclassing, I think. And I believe that is what @SGaist is referring toThe proper way to add closeEvent handling to your Designer based class is to create a proper class i.e. you cannot use QUiLoader for that.
though I stand to be corrected.
If that is so, read on:
Most C++ Qt-ers will instead run the
uic
tool at compilation stage to generate the source code for a derived class, and use that in their project. This gives better control and compile-time help, IMHO.You can do the same from Python, if you wish. Exact depends on whether you are PyQt5 or PySide2/6, but principle is the same. They supply an equivalent
pyuic
tool, to read a.ui
file and produce a Python class from it, which you thenimport
.You can then subclass from that and define your own
def closeEvent
override.Read Option A: Generating a Python class. And compare against your way, which is Option B: Loading it directly. See which you prefer.
Hope this helps.
-
I wasn't aware that is what
uic
did. I will try that out! Is there a tool that can auto convert this stuff or do I need to do it with every change? -
I wasn't aware that is what
uic
did. I will try that out! Is there a tool that can auto convert this stuff or do I need to do it with every change?@DoubleFelix
You do have run thepyuic
every time you re-save the.ui
file. When using C++ inside Creator the build process will do that automatically just before recompiling. I don't know whether there is anything similar when you use Python/PySide inside Creator, or whether you have to do it by hand. You should Google around.