У меня есть другая перспектива ответить на это.
При работе на разных уровнях, например, в приложении MVC, контроллеру нужны службы для вызова бизнес-операций. В таких сценариях контейнер инжекции зависимостей может использоваться для инициализации служб, чтобы исключить исключение NullReferenceException. Это означает, что вам не нужно беспокоиться о проверке нулевого значения и просто вызвать службы с контроллера, как будто они всегда будут доступны (и инициализированы) как одиночный или прототип.
public class MyController
{
private ServiceA serviceA;
private ServiceB serviceB;
public MyController(ServiceA serviceA, ServiceB serviceB)
{
this.serviceA = serviceA;
this.serviceB = serviceB;
}
public void MyMethod()
{
// We don't need to check null because the dependency injection container
// injects it, provided you took care of bootstrapping it.
var someObject = serviceA.DoThis();
}
}
Когда возвращается initNewWindow()
, переменная window
удаляется, и счетчик ссылок окна падает до нуля, в результате чего новый объект C ++ удаляется. Вот почему ваше окно немедленно закрывается.
Если вы хотите сохранить его открытым, обязательно сохраните ссылку. Самый простой способ сделать это - сделать ваше новое окно дочерним по отношению к вызывающему окну и установить его атрибут виджета WA_DeleteOnClose
(см. Qt::WidgetAttribute
).
Если функция создает объект PyQt, который приложение должно продолжать использовать, вам нужно будет убедиться, что ссылка на него хранится как-то. В противном случае он может быть удален сборщиком мусора Python сразу после возвращения функции.
Таким образом, либо дать объекту родительский объект, либо сохранить его как атрибут какого-либо другого объекта. (В принципе, объект также можно было бы сделать глобальной переменной, но это обычно считается плохой практикой).
Вот пересмотренная версия сценария вашего примера, демонстрирующая, как исправить вашу проблему:
from PySide import QtGui, QtCore
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
menu = self.menuBar().addMenu(self.tr('View'))
action = menu.addAction(self.tr('New Window'))
action.triggered.connect(self.handleNewWindow)
def handleNewWindow(self):
window = QtGui.QMainWindow(self)
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.setWindowTitle(self.tr('New Window'))
window.show()
# or, alternatively
# self.window = QtGui.QMainWindow()
# self.window.setWindowTitle(self.tr('New Window'))
# self.window.show()
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(300, 300)
window.show()
sys.exit(app.exec_())