0

我在 中运行一个pyqt4应用程序spyder,我退出QtGui.QMainWindow.close()并返回到spyder python interpreter提示符。但是,如果我再次尝试运行该应用程序,则runfile('C:/Python33/~/qtapp.py', wdir=r'C:/Python33/~/Appdir')该窗口不会显示。我必须关闭 python 解释器窗口并打开一个新窗口,然后才能再次运行我的pyqt4应用程序。这表明我是。

  1. 未正确关闭应用程序
  2. 未正确运行应用程序

我希望能够pyqt4从同一个提示符下运行应用程序,这将加快我的开发时间

这是示例代码:

from PyQt4 import QtCore, QtGui, Qwt5
import sys

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("MainWindow")
        MainWindow.resize(200, 200)
        self.checkBox = QtGui.QCheckBox(MainWindow)
        self.checkBox.setGeometry(QtCore.QRect(100, 100, 70, 17))
        self.checkBox.setObjectName("checkBox")


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

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Dialog",None, QtGui.QApplication.UnicodeUTF8))
        self.checkBox.setText(QtGui.QApplication.translate("MainWindow", "CheckBox", None, QtGui.QApplication.UnicodeUTF8))



class MainWindow(QtGui.QMainWindow,Ui_MainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()     
        self.setupUi(self)


app = QtGui.QApplication(sys.argv)
form = MainWindow()
form.show()
app.exec_()

窗口出现后我运行它,再次运行后窗口不显示,这是我的版本信息:

Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)] on win32 输入“帮助”、“版权”、“信用”或“许可”了解更多信息。

导入 NumPy 1.7.1、SciPy 0.12.0、Matplotlib 1.3.0 + guidata 1.6.1、guiqwt 2.3.1 输入“scientific”了解更多详情。

4

4 回答 4

3

要在 Spyder 中再次运行 PyQt 应用程序,必须删除/销毁正在运行的应用程序,但我们不能使用 sys.exit() 因为它会尝试关闭 Python。一种对我有用的解决方案(Python 3.4.1、Spyder 2.3.5.2、PyQt 4.10.4)是使用QtCore.QCoreApplication.instance().quit()deleteLater如下例所示:

import sys
from PyQt4 import QtGui, QtCore

class Window(QtGui.QMainWindow):
    """PyQt app that closes successfully in Spyder.
    """
    def __init__(self):
        super().__init__()
        self.setGeometry(200, 100, 400, 300)
        self.button()

    def button(self):
        btn = QtGui.QPushButton('Quit', self)
        btn.setGeometry(150, 125, 100, 50)
        btn.clicked.connect(self.quitApp)

    def quitApp(self):
        QtCore.QCoreApplication.instance().quit()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    app.aboutToQuit.connect(app.deleteLater)
    win = Window()
    win.show()
    app.exec_()
于 2015-07-25T19:51:56.570 回答
1

我遇到过同样的问题,但从未真正找到真正的解决方法。但是,我找到了一种解决方法,可以为我解决问题,也适用于 Eelco van Vliet 回答中的示例代码。

问题似乎是 Python 解释器中存储了一个全局 QApplication,它在程序调用之间没有被破坏。我没有在执行开始时实例化一个新的 QApplication ,而是检查它是否存在,如果存在,我使用现有的而不是创建一个新的:

if __name__=="__main__":
    if QCoreApplication.instance() != None:
        app = QCoreApplication.instance()
    else:
        app = QApplication(sys.argv)
    form = Form()
    form.show()
    app.exec_()
于 2015-03-23T16:39:19.160 回答
1

这实际上似乎是 IPython 内核及其与 PyQt 交互的问题。基本上,IPython 似乎挂在 Qt 实例上,需要在重新实例化之前清除它。这可以通过将保存 Qt 实例的变量重新绑定到其他东西来非常简单地完成:

app = 0
app = QtGui.QApplication([])
...
sys.exit(app.exec_())

这是从这里派生的,这是从这里派生的(并且更充分地解释了)。

于 2017-01-24T14:30:34.217 回答
0

我有同样的问题。下面的简单示例重现了该问题(使用 python 3.4)

当您第一次运行它时,它会关闭窗口并第二次运行失败。您可以在 spyder 中使用重置内核,但这会减慢开发时间。

对我有用的是打字

%重置

在当前内核的命令行上。这将重置变量 QtCriticalMsg、QtSystemMsg 等。之后您可以重新运行您的代码。

虽然这比重新启动内核要快一些,但仍然很烦人。显然,关闭窗口后 Qt 变量不会从内存中清除。有人建议如何在退出后从程序中强制清理内存?这可能会避免每次都必须键入 reset 并解决问题

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Form(QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.setAttribute(Qt.WA_DeleteOnClose)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|
                                     QDialogButtonBox.Cancel)
        grid = QGridLayout()
        grid.addWidget(buttonBox, 4, 0, 1, 2)
        self.setLayout(grid)

        self.connect(buttonBox, SIGNAL("accepted()"),
                     self, SLOT("accept()"))
        self.connect(buttonBox, SIGNAL("rejected()"),
                     self, SLOT("reject()"))
        self.setWindowTitle("Set Number Format (Modal)")


if __name__=="__main__":
    app = QApplication(sys.argv)
    form = Form()
    form.show()
    app.exec_()
于 2015-01-31T18:01:06.723 回答