Как создать в новом окне кнопку PySide / PyQt? - PullRequest
4 голосов
/ 12 декабря 2011

У меня проблемы с функцией «Новое окно» в PyQt4 / PySide с Python 2.7.Я подключил функцию initNewWindow(), чтобы создать новое окно, к действию и поместил его в строку меню.Когда-то распространенная функция в настольном программном обеспечении.Вместо того, чтобы дать мне новое постоянное окно рядом с другим, появляется новое окно и закрывается.Код, над которым я работаю, проприетарный, поэтому я создал пример, который делает то же самое с той же ошибкой ниже.Есть ли способ заставить это работать?Работает в PySide с Python 2.7.Он был написан и протестирован в Windows.

from PySide.QtCore import QSize
from PySide.QtGui import QAction
from PySide.QtGui import QApplication
from PySide.QtGui import QLabel
from PySide.QtGui import QMainWindow
from PySide.QtGui import QMenuBar
from PySide.QtGui import QMenu
from sys import argv

def main():
    application = QApplication(argv)
    window = QMainWindow()
    window.setWindowTitle('New Window Test')
    menu = QMenuBar(window)
    view = QMenu('View')
    new_window = QAction('New Window', view)
    new_window.triggered.connect(initNewWindow)
    view.addAction(new_window)
    menu.addMenu(view)
    label = QLabel()
    label.setMinimumSize(QSize(300,300))
    window.setMenuBar(menu)
    window.setCentralWidget(label)
    window.show()
    application.exec_()


def initNewWindow():
   window = QMainWindow()
   window.setWindowTitle('New Window')
   window.show() 


if __name__ == '__main__':
   main()

Ответы [ 2 ]

5 голосов
/ 12 декабря 2011

Если функция создает объект 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_())
3 голосов
/ 12 декабря 2011

Когда возвращается initNewWindow(), переменная window удаляется, и счетчик ссылок окна падает до нуля, что приводит к удалению вновь созданного объекта C ++. Вот почему ваше окно закрывается немедленно.

Если вы хотите оставить его открытым, обязательно сохраните ссылку. Самый простой способ сделать это - сделать ваше новое окно дочерним по отношению к вызывающему окну и установить его атрибут WA_DeleteOnClose widget (см. Qt::WidgetAttribute).

...