Мульти-диалоговая программа в PyQT не закроется (продолжение!) - PullRequest
1 голос
/ 19 июня 2010

У меня есть другая проблема с PyQT, на этот раз у меня есть пример, который будет гораздо более полезным, так как он содержит часть моего кода (конечно, очищен!) Мне трудно понять, как закрыть «Выбор программы» диалоговое окно только с помощью кнопки «ВЫХОД». Я мог бы просто использовать кнопку закрытия в форме, но я хочу сделать это с помощью кнопки «ВЫХОД».

Может ли кто-нибудь помочь мне решить эту головоломку?

Вот некоторый компилируемый код, чтобы вы все могли его пережевать.

connectionName = 'example'

class SelectProgramForm(QtGui.QDialog):   
    def __init__(self, connName, connPrivilege):
        QtGui.QWidget.__init__(self)
        self.fooA = connName
        self.fooB = connPrivilege

        self.widgetWidth = 100
        self.formWidth = self.widgetWidth + 40

    def setupUi(self, programSelectForm):
        programSelectForm.setObjectName("programSelectForm")
        programSelectForm.resize(400, self.formWidth)
        self.widget = QtGui.QWidget(programSelectForm)
        self.widget.setGeometry(QtCore.QRect(20, 20, 360, self.widgetWidth))
        self.widget.setObjectName("widget")
        self.verticalLayout = QtGui.QVBoxLayout(self.widget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.instructionLabel = QtGui.QLabel(self.widget)
        self.instructionLabel.setObjectName("instructionLabel")
        self.verticalLayout.addWidget(self.instructionLabel)
        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)
        self.optionsGridLayout = QtGui.QGridLayout()
        self.optionsGridLayout.setObjectName("optionsGridLayout")


        self.verticalLayout.addLayout(self.optionsGridLayout)
        spacerItemUpper = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItemUpper)
        self.horizontalLayout = QtGui.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItemLower = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItemLower)
        self.pushButtonLogout = QtGui.QPushButton(self.widget)
        self.pushButtonLogout.setObjectName("pushButtonLogout")
        self.horizontalLayout.addWidget(self.pushButtonLogout)
        self.verticalLayout.addLayout(self.horizontalLayout)

        self.connect(self.pushButtonLogout, QtCore.SIGNAL("clicked()"), self.reject)

        self.retranslateUi(programSelectForm)
        QtCore.QMetaObject.connectSlotsByName(programSelectForm)


    def retranslateUi(self, programSelectForm):
        programSelectForm.setWindowTitle(QtGui.QApplication.translate("programSelectForm", "Program Select", None, QtGui.QApplication.UnicodeUTF8))
        self.instructionLabel.setText(QtGui.QApplication.translate("programSelectForm", "Select the program that you wish to access:", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonLogout.setText(QtGui.QApplication.translate("programSelectForm", "Logout", None, QtGui.QApplication.UnicodeUTF8))


class LoginForm(QtGui.QDialog): 
    def __init__(self, connName):
        self.fooA = connName

    def setupUi(self, LoginForm):
        LoginForm.setObjectName("LoginForm")
        LoginForm.resize(275, 175)
        self.widget = QtGui.QWidget(LoginForm)
        self.widget.setGeometry(QtCore.QRect(10, 10, 251, 147))
        self.widget.setObjectName("widget")
        self.verticalLayout = QtGui.QVBoxLayout(self.widget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.dataInputLayout = QtGui.QHBoxLayout()
        self.dataInputLayout.setObjectName("dataInputLayout")
        self.labelVerticalLayout = QtGui.QVBoxLayout()
        self.labelVerticalLayout.setObjectName("labelVerticalLayout")
        self.userIDLabel = QtGui.QLabel(self.widget)
        self.userIDLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.userIDLabel.setObjectName("userIDLabel")
        self.labelVerticalLayout.addWidget(self.userIDLabel)
        self.passwordLabel = QtGui.QLabel(self.widget)
        self.passwordLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.passwordLabel.setObjectName("passwordLabel")
        self.labelVerticalLayout.addWidget(self.passwordLabel)
        self.dataInputLayout.addLayout(self.labelVerticalLayout)
        self.labelButtonVerticalLayout = QtGui.QVBoxLayout()
        self.labelButtonVerticalLayout.setObjectName("labelButtonVerticalLayout")
        self.userIDLineEdit = QtGui.QLineEdit(self.widget)
        self.userIDLineEdit.setObjectName("userIDLineEdit")
        self.labelButtonVerticalLayout.addWidget(self.userIDLineEdit)
        self.passwordLineEdit = QtGui.QLineEdit(self.widget)
        self.passwordLineEdit.setObjectName("passwordLineEdit")
        self.labelButtonVerticalLayout.addWidget(self.passwordLineEdit)
        self.dataInputLayout.addLayout(self.labelButtonVerticalLayout)
        self.verticalLayout.addLayout(self.dataInputLayout)
        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)
        self.buttonLayout = QtGui.QHBoxLayout()
        self.buttonLayout.setObjectName("buttonLayout")
        self.newUserPushButton = QtGui.QPushButton(self.widget)
        self.newUserPushButton.setObjectName("newUserPushButton")
        self.buttonLayout.addWidget(self.newUserPushButton)
        self.loginPushButton = QtGui.QPushButton(self.widget)
        self.loginPushButton.setObjectName("loginPushButton")
        self.buttonLayout.addWidget(self.loginPushButton)
        self.verticalLayout.addLayout(self.buttonLayout)

        self.retranslateUi(LoginForm)
        QtCore.QMetaObject.connectSlotsByName(LoginForm)

        QtCore.QObject.connect(self.loginPushButton, QtCore.SIGNAL("clicked()"), self.confirmUser)

    def confirmUser(self):
        programWindow = QtGui.QDialog()
        self.fooA = 'fooA'   # these are needed in real program
        self.fooB = 'fooB'   # these are needed in real program
        programDialog = SelectProgramForm(self.fooA, self.fooB)
        programDialog.setupUi(programWindow)
        programWindow.exec_()

    def retranslateUi(self, LoginForm):
        LoginForm.setWindowTitle(QtGui.QApplication.translate("LoginForm", "Login", None, QtGui.QApplication.UnicodeUTF8))
        self.userIDLabel.setText(QtGui.QApplication.translate("LoginForm", "Username:", None, QtGui.QApplication.UnicodeUTF8))
        self.passwordLabel.setText(QtGui.QApplication.translate("LoginForm", "Password:", None, QtGui.QApplication.UnicodeUTF8))
        self.newUserPushButton.setText(QtGui.QApplication.translate("LoginForm", "New User?", None, QtGui.QApplication.UnicodeUTF8))
        self.loginPushButton.setText(QtGui.QApplication.translate("LoginForm", "Log In", None, QtGui.QApplication.UnicodeUTF8))


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = QtGui.QDialog()
    newUser = LoginForm(connectionName)
    newUser.setupUi(window)
    window.show()
    sys.exit(app.exec_())

Вот еще один компилируемый пример, который показывает, что я ищу. Каждое окно может закрываться. Обратите внимание, что существует три уровня окон, один из которых активируется другим, что на втором и третьем окнах нет значков закрытия (также называемых кнопками «X»). Если бы только этот код работал с другим кодом ...

'''
Created on 2010-06-18

@author: dhatt
'''

import sys
from PyQt4 import QtGui, QtCore

class WindowLV3(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setWindowFlags(QtCore.Qt.CustomizeWindowHint|QtCore.Qt.WindowTitleHint|QtCore.Qt.WindowMaximizeButtonHint)
        self.setGeometry(300, 300, 120, 150)
        self.setWindowTitle('LV3')

        quit = QtGui.QPushButton('Close', self)
        quit.setGeometry(10, 10, 60, 35)

        self.connect(quit, QtCore.SIGNAL('clicked()'),
            self.reject)


class WindowLV2(QtGui.QDialog):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.Window3 = WindowLV3()

        self.setWindowFlags(QtCore.Qt.CustomizeWindowHint|QtCore.Qt.WindowTitleHint|QtCore.Qt.WindowMaximizeButtonHint)
        self.setGeometry(300, 300, 120, 150)
        self.setWindowTitle('LV2')

        self.quit = QtGui.QPushButton('Close', self)
        self.quit.setGeometry(10, 10, 60, 35)

        next = QtGui.QPushButton('Lv3', self)
        next.setGeometry(10, 50, 60, 35)

        self.connect(self.quit, QtCore.SIGNAL('clicked()'),
            self.reject)

        self.connect(next, QtCore.SIGNAL('clicked()'),
            self.nextWindow)

    def nextWindow(self):
        self.Window3.show()


class WindowLV1(QtGui.QDialog):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.Window2 = WindowLV2()

        self.setGeometry(300, 300, 120, 150)
        self.setWindowTitle('LV1')

        next = QtGui.QPushButton('Lv2', self)
        next.setGeometry(10, 50, 60, 35)

        quit = QtGui.QPushButton('Close', self)
        quit.setGeometry(10, 10, 60, 35)

        self.connect(next, QtCore.SIGNAL('clicked()'),
            self.nextWindow)

        self.connect(quit, QtCore.SIGNAL('clicked()'),
             self.reject)
        #QtGui.qApp, QtCore.SLOT('quit()'))

    def nextWindow(self):
        self.Window2.show()


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    Window1 = WindowLV1()
    Window1.show()
    sys.exit(app.exec_())

Удачной охоты!

Ответы [ 3 ]

0 голосов
/ 26 июня 2010

Я на самом деле не запускал код, но из-за ошибки кажется, что он пытается получить доступ к локальному объекту.

Следующим кодом может быть проблема:

def confirmUser(self):
        programWindow = QtGui.QDialog()
        self.fooA = 'fooA'   # these are needed in real program
        self.fooB = 'fooB'   # these are needed in real program
        programDialog = SelectProgramForm(self.fooA, self.fooB)
        programDialog.setupUi(programWindow)
        programWindow.exec_()

Здесь есть две возможности.1) Сделать programWindow переменной экземпляра.то есть make self.programWindow = QtGui.QDialog()

2) В идеале вы должны создать один экземпляр self.programWindow, и здесь можно просто позвонить self.programWindow.show().т.е. часть кода в confirmUser может быть перемещена в метод инициализации.Но я на самом деле не изучил ваш код, чтобы сказать «это правильный путь» ... просто попробуйте.

0 голосов
/ 14 июля 2010

Я снова здесь, и мне удалось вычеркнуть ответ.

Я попытался переключить передачи и вместо этого использовать QWizard, но когда даже в QWizard все еще возникали некоторые из тех же проблем, что и в моих диалогахИмея (RuntimeError: базовый объект C / C ++ был удален), я еще раз взглянул на свой код и выяснил это.

Я нашел способ окончательно закрыть формы, используя только диалог.Оказывается, что LoginForm не был настроен как QDialog должным образом, потому что это фактически два объекта, окно и сам объект (который не является истинным объектом QDialog).

Код перед:

# a QDialog inside a LoginForm object (as a QDialog class), if I close this, the 'window' QDialog object is left hanging and raises an error
window = QtGui.QDialog()
newUser = LoginForm(connectionName)
newUser.setupUi(window)
window.show() code here

Код после:

# a LoginForm object as a QDialog class.  When closed, nothing is left hanging
window = LoginForm(connectionName)
window.setupUi(window)
window.show()

Добавьте к этому работу по изменению нескольких строк в самом классе LoginForm (а именно, полностью изменив метод SetupUI из класса LoginForm)

И добавьте это к самому классу (класс LoginForm)

class LoginForm(QtGui.QDialog):
"""
This makes the LoginForm object subclassed from a QDialog object.
"""

def __init__(self, parent, fooA, fooB):
    super(LoginForm, self).__init__(parent)
    # Add whatever code you want afterwards

Возможно, это не самый лучший способ, но мне удалось это сделать, и я считаю, что мой код чище без всехтот беспорядок, который SetupUI создал для меня из QtDesigner.

0 голосов
/ 19 июня 2010

Я ответил на ваш предыдущий вопрос.Решение здесь то же самое, просто замените

self.connect(self.pushButtonLogout, QtCore.SIGNAL("clicked()"), self.reject)

на

self.connect(self.pushButtonLogout, QtCore.SIGNAL("clicked()"), self.close)

Это должно закрыть диалоговое окно.

...