thanks for reading!
The problem generally is, that i do not really know where to properly code signals and slots when using a converted .py file from the QtDesigner, and I don't seem to find any useful answers on this particular problem. My initial code consists of three files, which I mostly did not create by myself btw, all credit goes to "rebelCoder" (https://www.youtube.com/user/JurisL85) and "Alan D Moore Codes" (https://www.youtube.com/channel/UCj7i-mmOjLV17YTPIrCPkog).
The first file is just running methods of the DNAEngine class (see third file) and the second file is a converted .py file from the QtDesigner (engine_ui in third file). I don't edit both of these files.
The third file initially looked like this (copied from rebelCoder):
from engine_ui import Ui_MainWindow
import sys
from PySide2 import QtWidgets as qtw
from PySide2 import QtCore as qtc
class DNAEngine:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.app = qtw.QApplication(sys.argv)
self.MainWindow = qtw.QMainWindow()
def setup(self):
self.ui = Ui_MainWindow()
self.ui.setupUi(self.MainWindow)
def run(self):
sys.exit(self.app.exec_())
def display(self):
self.MainWindow.show()
My idea now was to create a subclass of Ui_MainWindow (the class from the converted file), where I theoretically would be able to add signals, which leads to this:
from engine_ui import Ui_MainWindow
from PySide2 import QtWidgets as qtw
from PySide2 import QtCore as qtc
from PySide2 import QtGui as qtg
import sys
class DNASignal(Ui_MainWindow):
def __init__(self, window):
self.setupUi(window)
# signal code starts here
self.actionQuit.triggered.connect(self.close) # does not work
self.actionSave.triggered.connect(self.onActionSaveTriggered)
self.actionOpen.triggered.connect(self.onActionOpenTriggered)
# signal code ends here
def onActionSaveTriggered(self):
text = self.textedit.toPlainText()
filename, _ = qtw.QFileDialog.getSaveFileName()
if filename:
with open(filename, 'w') as handle:
handle.write(text)
self.statusBar().showMessage(f'Saved to {filename}')
def onActionOpenTriggered(self):
filename, _ = qtw.QFileDialog.getOpenFileName()
if filename:
with open(filename, 'r') as handle:
text = handle.read()
self.textEditInput.clear()
self.textEditInput.insertPlainText(text)
self.textEditInput.moveCursor(qtg.QTextCursor.Start)
self.statusBar().showMessage(f'Editing {filename}')
class DNAEngine:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.app = qtw.QApplication(sys.argv)
self.MainWindow = qtw.QMainWindow()
def setup(self):
self.ui = DNASignal(self.MainWindow)
def run(self):
sys.exit(self.app.exec_())
def display(self):
self.MainWindow.show()
I am trying to connect three actions of the menubar, a Quit, Save, and Open button. While the Open and Save actions work perfectly fine, the Quit action does not work. When I start the app without commenting the Quit signal out, it throws this error:
AttributeError: 'DNASignal' object has no attribute 'close'
How to get the quit action to work?
Also, while this approach seems to work for the other actions, it is quite messy and surely not optimal, so how to optimise this? However, Id like to keep the first file (the one running the DNAEngine class) separately.
Subclassing the "form class" (the one created from the ui) is pointless, as it's just a python class that does almost nothing on its own.
What you need is to implement the methods provided by the QWidget you're using (QMainWindow, in your case), so you need to inherit from both the widget and the form classes:
class DNAMainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
# ...
class DNAEngine:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.app = qtw.QApplication(sys.argv)
def setup(self):
self.mainWindow = DNAMainWindow()
def display(self):
self.mainWindow.show()