closeEvent not running
-
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.uifile 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
uictool 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
pyuictool, to read a.uifile and produce a Python class from it, which you thenimport.You can then subclass from that and define your own
def closeEventoverride.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
uicdid. 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
uicdid. 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 thepyuicevery time you re-save the.uifile. 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. -
Okay, I used
pyuic5 -x window.ui -o window.pyin the same directory as mywindow.py, but it gives meFatal error in launcher: Unable to create process using '"d:\python\python.exe" "D:\Python\Scripts\pyuic5.exe" -x window.ui -o window.py': The system cannot find the file specified.I'm not sure why it can't find the file. It doesn't work if I provide a direct file path either.
-
Okay, I used
pyuic5 -x window.ui -o window.pyin the same directory as mywindow.py, but it gives meFatal error in launcher: Unable to create process using '"d:\python\python.exe" "D:\Python\Scripts\pyuic5.exe" -x window.ui -o window.py': The system cannot find the file specified.I'm not sure why it can't find the file. It doesn't work if I provide a direct file path either.
@DoubleFelix
I don't know. But have a Google for, say,pyuic5 Fatal error in launcher. I'm getting a few hits for you to look through. I think one possible suggestion was make sure everything is either 32- or 64-bit?I think the
pyuicon your PATH is apyuic.bat, which runspython.exeto execute thepyuic5.exe. Try just runningD:\Python\Scripts\pyuic5.exedirectly and see whether you get an error from that? -
I can only find an instance of
pyuic5.batin an anaconda folder, which I do not use. I was originally runningpyuic5.exe, which returns the error I'm getting. Sorry for not elaborating better. As for 32-bit vs. 64-bit, I have verified everything is 64-bit. -
How did you install PySide2 exactly ?
-
With
pip install pyside6(I use PySide6 but I was told they were the same but with more features so I'm not sure it matters) -
With
pip install pyside6(I use PySide6 but I was told they were the same but with more features so I'm not sure it matters)@DoubleFelix
PySide6 is not the same as PySide2, hence the6instead of2! It's PySide for Qt6, instead of for Qt5. It's new. It does not yet have all features either.And I notice you are running
pyuic5, which I assume from the5is for Qt5.Anyway, if it were me, I would scrub (uninstall, remove) anything Qt6/PySide6, and install Qt 5.15-ish (latest) + PySide2. (If the PySide2 comes with its own version of Qt5 [I don't know if that's how it works] that's fine, you don't need to do Qt5 separately.) And try again, at least to see how that fares in comparison.
-
Is it your system pip ? Conda ?
-
@JonB I have uninstalled PySide6 and installed PySide2 and I get the same error.
@SGaist I don't think it is but I'm not sure how to tellI attempted to use a mix of PySide6's normal features with PyQt5's
uicmodule, but usingclass TexasHoldEmServerWindow(QMainWindow): def __init__(self): super(TexasHoldEmServerWindow, self).__init__() uic.loadUi(os.path.join(os.path.dirname(__file__), "window.ui"), self)Raises this error:
Exception has occurred: TypeError ('Wrong base class of toplevel widget', (<class 'topaz.server.texas_hold_em.server_window.TexasHoldEmServerWindow'>, 'QMainWindow')) -
Isn't the original base widget a QWidget ?
-
I tried using that too but it throws the same error
-
Then what base class did you select in designer ?
-
The main window is
QMainWindowbut I have a layout inside the window (grid) which isQWidget. Inheriting either gives the same error however. -
I was able to get it working by using
pyuic6 window.ui -o window.py
I have this:super(TexasHoldEmServerWindow, self).__init__() self.window = Ui_MainWindow self.window.setupUi(self)But
setupUi()also needs to passed a parameter called MainWindow, but I'm not sure what to give it here. -
I got it sort of working using a bit of code someone put in a stack overflow post:
from PySide6.QtCore import QMetaObject from PySide6.QtUiTools import QUiLoader class UiLoader(QUiLoader): def __init__(self, baseinstance, customWidgets=None): QUiLoader.__init__(self, baseinstance) self.baseinstance = baseinstance self.customWidgets = customWidgets def createWidget(self, class_name, parent=None, name=''): if parent is None and self.baseinstance: return self.baseinstance else: if class_name in self.availableWidgets(): widget = QUiLoader.createWidget(self, class_name, parent, name) else: try: widget = self.customWidgets[class_name](parent) except (TypeError, KeyError) as e: #raise Exception('No custom widget ' + class_name + ' found in customWidgets param of UiLoader __init__.') pass if self.baseinstance: setattr(self.baseinstance, name, widget) return widget def loadUi(uifile, baseinstance=None, customWidgets=None, workingDirectory=None): loader = UiLoader(baseinstance, customWidgets) if workingDirectory is not None: loader.setWorkingDirectory(workingDirectory) widget = loader.load(uifile) QMetaObject.connectSlotsByName(widget) return widgetThen I add this to my UI Class:
QMainWindow.__init__(self) loadUi(os.path.join(os.path.dirname(__file__), "window.ui"), self)But it keeps saying the widget creation fails.
-
Wait, this is related to another issue. This one is solved.
Sorry for being such a pain and thank you so much.I don't know how to close this