简体   繁体   English

PyQt4中的多个Windows

[英]Multiple Windows in PyQt4

I have a PyQt program used to visualize some python objects. 我有一个PyQt程序用于可视化一些python对象。 I would like to do display multiple objects, each in its own window. 我想在自己的窗口中显示多个对象。

What is the best way to achieve multi-window applications in PyQt4? 在PyQt4中实现多窗口应用程序的最佳方法是什么?

Currently I have the following: 目前我有以下内容:

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

However, this approach is not satisfactory, as I am facing problems when I try to factor out the MultipleWindows part in its own class. 但是,这种方法并不令人满意,因为当我尝试在其自己的类中分解MultipleWindows部件时,我遇到了问题。 For example: 例如:

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

The above code will call the initializer of the MainWindow class, rather than that of the appropriate subclass, and will thus throw an exception. 上面的代码将调用MainWindow类的初始化程序,而不是相应的子类的初始化程序,因此将抛出异常。

How can I call the initializer of the subclass? 如何调用子类的初始值设定项? Is there a more elegant way to do this? 有没有更优雅的方式来做到这一点?

Why not using dialogs? 为什么不使用对话框? In Qt you do not need to use the main window unless you want to use docks etc.. Using dialogs will have the same effect. 在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). 期望超类知道要在其子类的init中使用的参数并不是一个好主意,因为很难确保所有构造函数都是相同的(可能动物对话框/窗口采用diff参数) 。

Hope it helps. 希望能帮助到你。

In order to reference the subclass that is inheriting the super-class from inside the super-class, I am using self.__class__() , so the MultiWindows class now reads: 为了引用从超类内部继承超类的子类,我使用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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM