PyQt4中的多个窗口

3 投票
2 回答
9526 浏览
提问于 2025-04-15 14:24

我有一个用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_()

不过,这种方法不太理想,因为当我尝试把多个窗口的部分单独放到一个类里时,遇到了问题。例如:

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

上面的代码会调用主窗口类的初始化方法,而不是适当子类的初始化方法,这样就会出现错误。

我该怎么调用子类的初始化方法呢?有没有更好的方法来实现这个?

2 个回答

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)
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中要用的参数并不是个好主意,因为很难保证所有的构造函数都是一样的(比如动物对话框/窗口可能需要不同的参数)。

希望这对你有帮助。

撰写回答