Los cambios de QtDesigner se perderán después del rediseño de la interfaz de usuario
Estoy usando Qt Designer para diseñar GUI para usar en Python, después de diseñar mi UI deseada en Qt Designer, la convertí a código Python y luego cambié el código generado para realizar alguna acción en mi código Python, pero si cambié la UI con Qt Designer y lo convertí a código Python nuevamente, perdí mis cambios anteriores en mi código.
¿Cómo puedo solucionar el problema?
¿Podemos distribuir una clase en varios archivos en Python para escribir código en otros archivos?
Para evitar tener estos problemas es recomendable no modificar este archivo sino crear un archivo nuevo donde implementemos una clase que use ese diseño.
Por ejemplo, supongamos que ha utilizado la MainWindow
plantilla en el design.ui
archivo y luego la convierte para Ui_Design.py
que tenga la siguiente estructura:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
[...]
def retranslateUi(self, MainWindow):
[...]
Luego crearemos un nuevo archivo al que llamaremos logic.py
donde crearemos el archivo que maneja la lógica y que utiliza el diseño anterior:
class Logic(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
Entonces incluso si modificas el diseño y generas nuevamente el archivo .py no tendrás que modificar el archivo de la lógica.
Para generalizar la idea debemos tener las siguientes reglas pero para ello la clase lógica debe tener la siguiente estructura:
class Logic(PyQtClass, DesignClass):
def __init__(self, *args, **kwargs):
PyQtClass.__init__(self, *args, **kwargs)
self.setupUi(self)
- PyQtClass: Esta clase depende del diseño elegido.
Template PyQtClass
─────────────────────────────────────────────
Main Window QMainWindow
Widget QWidget
Dialog with Buttons Bottom QDialog
Dialog with Buttons Right QDialog
Dialog with Without Buttons QDialog
- DesignClass: El nombre de la clase que aparece en su diseño.
La ventaja de esta implementación es que puedes implementar toda la lógica ya que es un widget, por ejemplo implementaremos la solución cerrando pyqt messageBox con closeevent de la ventana principal :
class Logic(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
def closeEvent(self, event):
answer = QtWidgets.QMessageBox.question(
self,
'Are you sure you want to quit ?',
'Task is in progress !',
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if answer == QtWidgets.QMessageBox.Yes:
event.accept()
else:
event.ignore()
La forma más sencilla es utilizar el archivo *.ui directamente en el código Python; no es necesario convertirlo al archivo *.py cada vez que cambia la interfaz de usuario. Puedes utilizar este pseudocódigo en tu proyecto.
# imports
from PyQt5 import uic
# load ui file
baseUIClass, baseUIWidget = uic.loadUiType("MainGui.ui")
# use loaded ui file in the logic class
class Logic(baseUIWidget, baseUIClass):
def __init__(self, parent=None):
super(Logic, self).__init__(parent)
self.setupUi(self)
.
.
.
.
def main():
app = QtWidgets.QApplication(sys.argv)
ui = Logic(None)
ui.showMaximized()
sys.exit(app.exec_())