【问题标题】:PyQt window not closingPyQt 窗口未关闭
【发布时间】:2016-04-25 23:06:17
【问题描述】:

我正在学习如何使用 PyQt4,我似乎创建了一个简单的程序,当单击第一个窗口中的按钮时,它会打开第二个窗口。我的问题是我希望第一个窗口在第二个窗口打开时关闭。我在点击事件中使用了self.close() 函数无济于事。我需要帮助。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'uitest.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(QtGui.QMainWindow):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setupUi(self)

    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.setWindowModality(QtCore.Qt.NonModal)
        MainWindow.resize(288, 242)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(50, 50, 171, 101))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        ####################################################################################
        self.pushButton.clicked.connect(self.ChangeUi)
        ########################################################################
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 288, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

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

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.pushButton.setText(_translate("MainWindow", "NEXT", None))

    def ChangeUi(self):

        self.newUser = Ui_MainWindow1()
        self.newUser.show()


class Ui_MainWindow1(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setupUi(self)

    def setupUi(self, MainWindow1):
        MainWindow1.setObjectName(_fromUtf8("MainWindow1"))
        MainWindow1.resize(480, 265)
        self.centralwidget = QtGui.QWidget(MainWindow1)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.label = QtGui.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(180, 70, 111, 71))
        font = QtGui.QFont()
        font.setPointSize(15)
        self.label.setFont(font)
        self.label.setObjectName(_fromUtf8("label"))
        MainWindow1.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow1)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 480, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow1.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow1)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow1.setStatusBar(self.statusbar)

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

    def retranslateUi(self, MainWindow1):
        MainWindow1.setWindowTitle(_translate("MainWindow1", "MainWindow", None))
        self.label.setText(_translate("MainWindow1", "IT WORKED", None))

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

【问题讨论】:

  • 希望你不要介意,我编辑了你的帖子添加了一个python标签(在pyqt标签旁边),这样线程中的所有代码都会被python浸染语法高亮,使代码更易于阅读。

标签: python pyqt


【解决方案1】:

1) 你在这里做了一些时髦的事情:

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

如果我更改如下代码,第一个窗口将关闭:

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    #MainWindow.show()
    ui.show()
    sys.exit(app.exec_())

2) 这段代码:

ui = Ui_MainWindow()
ui.setupUi(MainWindow)

调用 setupUi() 两次,因为创建 Ui_MainWindow 实例会导致 setupUi() 被调用:

class Ui_MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        ...
        self.setupUi(self)

3) 转换后的 .ui 文件看起来很奇怪:

class Ui_MainWindow(QtGui.QMainWindow): 

我转换的 .ui 文件有一个类似的类(Qt 4.8.6),但该类继承自对象——不是 QtGui.QMainWindow,这意味着我的类不是小部件类,它只是一个包含一堆数据和一些用于创建小部件的方法。你改变了吗?也许是为了响应错误:AttributeError: 'Ui_MainWindow' object has no attribute 'close'?

我认为您不应该干预转换后的 .ui 文件。相反,为您的代码创建一个不同的文件并导入转换后的 .ui 文件,即 .py 文件,您可以调用其中定义的方法。这允许您在 Qt Designer 中进行更改,然后将更改后的 .ui 文件再次转换为 .py 文件——无需更改程序文件中的任何内容。而且,这样做可以防止你犯你所犯的错误。

下面是一个简化的例子,它由一个窗口和一个关闭窗口的按钮组成。您犯的相同错误将阻止此应用程序中的窗口关闭。但是,如果您的代码位于与转换后的 .ui 文件不同的文件中,看看会发生什么:

design.py(未对转换后的 .ui 文件进行任何更改):

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'mainwindow.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(568, 409)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(230, 150, 110, 32))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 568, 22))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

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

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.pushButton.setText(_translate("MainWindow", "Close window", None))

main.py(为您的代码创建此文件):

import sys
import design
from PyQt4.QtGui import QMainWindow, QApplication

class MyWindow(QMainWindow, design.Ui_MainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.setupUi(self)

        self.pushButton.clicked.connect(self.close_window)

    def close_window(self):
        self.close()


app = QApplication(sys.argv) 
window = MyWindow()
window.show()
sys.exit(app.exec_())

请注意,因为您只创建了一个窗口,所以您不能显示错误的窗口。此外,如果您决定更改 .ui 文件(然后将其再次转换为 .py 文件),唯一会改变的是函数内部的代码,因为 main.py 只调用您不需要对 main.py 进行任何更改的函数。

因为 MyWindow 继承自 design.py 中定义的 Ui_MainWindow 类,所以在该类中分配给 self 的所有小部件都可以在 MyWindow 类中使用 self.widgetName 访问——当在 MyWindow 类中找不到 widgetName 时,它​​的父类在类中搜索 widgetName。

【讨论】:

  • 非常感谢您的帮助。它运作良好,提高了我的理解
  • @AK27,Wel....我发布了三种不同的解释,描述了您的窗口无法关闭的原因,我将它们全部删除,因为在进一步测试后证明它们是错误的。我真的无法解释为什么将MainWindow.show() 更改为ui.show() 会成功——这削弱了我的理解。 :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-17
  • 1970-01-01
  • 2014-11-11
  • 2018-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多