Los cambios de QtDesigner se perderán después del rediseño de la interfaz de usuario

Resuelto Ahad aghapour asked hace 6 años • 2 respuestas

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?

Ahad aghapour avatar Oct 03 '17 19:10 Ahad aghapour
Aceptado

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 MainWindowplantilla en el design.uiarchivo y luego la convierte para Ui_Design.pyque 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.pydonde 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()
eyllanesc avatar Oct 03 '2017 12:10 eyllanesc

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_())
Ahad aghapour avatar Jan 24 '2018 08:01 Ahad aghapour