Pregunta

Tengo un programa PyQt usado para visualizar algunos objetos de Python. Me gustaría mostrar varios objetos, cada uno en su propia ventana.

¿Cuál es la mejor manera de lograr aplicaciones de múltiples ventanas en PyQt4?

Actualmente tengo lo siguiente:

from PyQt4 import QtGui

class MainWindow(QtGui.QMainWindow):
    windowList = []

    def __init__(self, animal):
        pass

    def addwindow(self, animal)
        win = MainWindow(animal)
        windowList.append(win)

if __name__=="__main__":
    import sys

    app = QtGui.QApplication(sys.argv)

    win = QMainWindow(dog)
    win.addWindow(fish)
    win.addWindow(cat)

    app.exec_()

Sin embargo, este enfoque no es satisfactorio, ya que estoy enfrentando problemas cuando intento factorizar la parte MultipleWindows en su propia clase. Por ejemplo:

class MultiWindows(QtGui.QMainWindow):
    windowList = []

    def __init__(self, param):
        raise NotImplementedError()

    def addwindow(self, param)
        win = MainWindow(param) # How to call the initializer of the subclass from here?
        windowList.append(win)

class PlanetApp(MultiWindows):
    def __init__(self, planet):
        pass

class AnimalApp(MultiWindows):
    def __init__(self, planet):
        pass

if __name__=="__main__":
    import sys

    app = QtGui.QApplication(sys.argv)

    win = PlanetApp(mercury)
    win.addWindow(venus)
    win.addWindow(jupiter)

    app.exec_()

El código anterior llamará al inicializador de la clase MainWindow, en lugar del de la subclase apropiada, y por lo tanto arrojará una excepción.

¿Cómo puedo llamar al inicializador de la subclase? ¿Hay alguna forma más elegante de hacer esto?

¿Fue útil?

Solución

¿Por qué no usar diálogos? En Qt no necesita usar la ventana principal a menos que quiera usar muelles, etc. Usar diálogos tendrá el mismo efecto.

También puedo ver un problema en su lógica con respecto al hecho de que desea que su superclase llame al constructor de sus hijos, que por supuesto puede ser de cualquier tipo. Te recomiendo que lo reescribas así:

class MultiWindows(QtGui.QMainWindow):

    def __init__(self, param):
        self.__windows = []

    def addwindow(self, window):
        self.__windows.append(window)

    def show():
        for current_child_window in self.__windows:
             current_child_window.exec_() # probably show will do the same trick

class PlanetApp(QtGui.QDialog):
    def __init__(self, parent, planet):
       QtGui.QDialog.__init__(self, parent)
       # do cool stuff here

class AnimalApp(QtGui.QDialog):
    def __init__(self, parent, animal):
       QtGui.QDialog.__init__(self, parent)
       # do cool stuff here

if __name__=="__main__":
    import sys # really need this here??

    app = QtGui.QApplication(sys.argv)

    jupiter = PlanetApp(None, "jupiter")
    venus = PlanetApp(None, "venus")
    windows = MultiWindows()
    windows.addWindow(jupiter)
    windows.addWindow(venus)

    windows.show()
    app.exec_()

No es una buena idea esperar que la superclase conozca el parámetro que se utilizará en el init de sus subclases, ya que es realmente difícil asegurarse de que todo el constructor sea el mismo (tal vez el animal dialog / window toma parámetros diff).

Espero que ayude.

Otros consejos

Para hacer referencia a la subclase que hereda la superclase desde dentro de la superclase, estoy usando self .__ class __ () , por lo que la clase MultiWindows ahora lee:

class MultiWindows(QtGui.QMainWindow):
windowList = []

def __init__(self, param):
    raise NotImplementedError()

def addwindow(self, param)
    win = self.__class__(param)
    windowList.append(win)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top