PyQt4中的多个Windows

时间:2009-09-18 00:57:15

标签: python inheritance 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类的初始化程序,而不是相应子类的初始化程序,因此会抛出异常。

如何调用子类的初始值设定项?有更优雅的方式吗?

2 个答案:

答案 0 :(得分: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_()

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 中使用的参数并不是一个好主意,因为很难确保所有构造函数都是相同的(可能是动物)对话框/窗口采用差异参数)。

希望它有所帮助。

答案 1 :(得分: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)