Несколько окон в PyQt4

У меня есть программа PyQt, используемая для визуализации некоторых объектов Python. Я хотел бы отображать несколько объектов, каждый в своем окне.

Как лучше всего реализовать многооконные приложения в PyQt4?

В настоящее время у меня есть следующее:

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

Однако этот подход не является удовлетворительным, так как я сталкиваюсь с проблемами, когда пытаюсь выделить часть MultipleWindows в отдельный класс. Например:

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

Приведенный выше код вызовет инициализатор класса MainWindow, а не соответствующего подкласса, и, таким образом, вызовет исключение.

Как я могу вызвать инициализатор подкласса? Есть ли более элегантный способ сделать это?


person D R    schedule 18.09.2009    source источник


Ответы (2)


Почему бы не использовать диалоги? В Qt вам не нужно использовать главное окно, если вы не хотите использовать доки и т. д. Использование диалогов будет иметь тот же эффект.

I can also see a problem in your logic regarding the fact that you want your super class to be calling the constructor of its children, which of course can be any type. I recommend you rewrite it like the following:

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

It is not a nice idea to expect the super class to know the parameter to be used in the init of its subclasses since it is really hard to ensure that all the constructor will be the same (maybe the animal dialog/window takes diff parameters).

Надеюсь, поможет.

person mandel    schedule 18.09.2009

Чтобы сослаться на подкласс, который наследует суперкласс внутри суперкласса, я использую self.__class__(), поэтому класс MultiWindows теперь читается:

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

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

def addwindow(self, param)
    win = self.__class__(param)
    windowList.append(win)
person D R    schedule 18.09.2009