2009-09-18 4 views
3

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

Каков наилучший способ достижения многооконных приложений в 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, а не у соответствующего подкласса, и, таким образом, бросить исключение.

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

ответ

6

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

Я также вижу проблему в вашей логике относительно того, что вы хотите, чтобы ваш суперкласс вызывал конструктор своих детей, что, конечно же, может быть любым типом. Я рекомендую вам переписать его следующим образом:

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

Неплохое представление о том, что суперкласс должен знать параметр, который будет использоваться в init из его подклассов, поскольку очень сложно гарантировать, что все конструкторы будут быть одинаковым (возможно, диалог/окно животного принимает параметры diff).

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

0

Для того, чтобы ссылаться на подкласс, который наследует супер-класса внутри супер-класса, я использую 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)