Вопрос

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

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

Это было полезно?

Решение

Почему бы не использовать диалоги? В 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).

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

Другие советы

Чтобы сослаться на подкласс, который наследует суперкласс изнутри суперкласса, я использую 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 с атрибуция
Не связан с StackOverflow
scroll top