Domanda

Ho un programma PyQt usato per visualizzare alcuni oggetti Python. Vorrei visualizzare più oggetti, ognuno nella propria finestra.

Qual è il modo migliore per realizzare applicazioni multi-finestra in PyQt4?

Attualmente ho il seguente:

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_()

Tuttavia, questo approccio non è soddisfacente, poiché sto affrontando problemi quando provo a scomporre la parte MultipleWindows nella sua stessa classe. Ad esempio:

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_()

Il codice sopra richiamerà l'inizializzatore della classe MainWindow, piuttosto che quello della sottoclasse appropriata, e genererà quindi un'eccezione.

Come posso chiamare l'inizializzatore della sottoclasse? C'è un modo più elegante per farlo?

È stato utile?

Soluzione

Perché non usare le finestre di dialogo? In Qt non è necessario utilizzare la finestra principale se non si desidera utilizzare dock, ecc. L'uso delle finestre di dialogo avrà lo stesso effetto.

Posso anche vedere un problema nella tua logica riguardo al fatto che vuoi che la tua super classe chiami il costruttore dei suoi figli, che ovviamente può essere di qualsiasi tipo. Ti consiglio di riscriverlo come segue:

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_()

Non è una buona idea aspettarsi che la superclasse conosca il parametro da usare nella init delle sue sottoclassi poiché è davvero difficile garantire che tutto il costruttore sia lo stesso (forse l'animale dialog / window accetta i parametri diff).

Spero che sia d'aiuto.

Altri suggerimenti

Per fare riferimento alla sottoclasse che eredita la superclasse dall'interno della superclasse, sto usando self .__ class __ () , quindi la classe MultiWindows ora recita:

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

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

def addwindow(self, param)
    win = self.__class__(param)
    windowList.append(win)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top