Múltiplas janelas em PyQt4
-
22-07-2019 - |
Pergunta
Eu tenho um programa PyQt usado para visualizar alguns objetos python. Eu gostaria de fazer exibição de vários objetos, cada um em sua própria janela.
O que é a melhor maneira de conseguir aplicações multi-window em PyQt4?
Atualmente tenho o seguinte:
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_()
No entanto, esta abordagem não é satisfatória, como eu estou enfrentando problemas quando tento fator de fora a parte MultipleWindows em sua própria classe. Por exemplo:
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_()
O código acima irá chamar o inicializador da classe MainWindow, em vez do que a subclasse apropriada, e, assim, lançar uma exceção.
Como posso chamar o inicializador da subclasse? Existe uma maneira mais elegante de fazer isso?
Solução
Por que não usar diálogos? Em Qt você não precisa usar a janela principal a menos que você quiser usar docas etc .. Utilizando diálogos terá o mesmo efeito.
Eu também posso ver um problema em sua lógica sobre o fato de que você quer sua classe super para ser chamar o construtor de seus filhos, o que naturalmente pode ser qualquer tipo. Eu recomendo que você reescrevê-lo como o seguinte:
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_()
Não é uma boa idéia esperar o super classe para saber o parâmetro a ser usado na init de suas subclasses, uma vez que é realmente duro para assegurar que todo o construtor será o mesmo (talvez o animal diálogo / janela leva diff parâmetros).
Hope isso ajuda.
Outras dicas
A fim de fazer referência a subclasse que está herdando a super-classe de dentro do super-classe, eu estou usando self.__class__()
, então a classe MultiWindows agora lê-se:
class MultiWindows(QtGui.QMainWindow):
windowList = []
def __init__(self, param):
raise NotImplementedError()
def addwindow(self, param)
win = self.__class__(param)
windowList.append(win)