在spyder中从一个提示运行两次pyqt应用程序

时间:2013-10-18 21:26:37

标签: python pyqt4 spyder

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

  1. 未正确关闭应用
  2. 未正确运行应用
  3. 我希望能够在同一个提示符下运行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_()
    

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

    win32上的Python 3.3.2(v3.3.2:d047928ae3f6,2013年5月16日,00:03:43)[MSC v.1600 32位(英特尔)] 输入“帮助”,“版权”,“信用”或“许可”以获取更多信息。

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

4 个答案:

答案 0 :(得分: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_()

答案 1 :(得分:1)

我遇到了同样的问题,但从未真正找到真正的解决办法。但是,我找到了解决问题的解决方法,也适用于Eelco van Vliet的答案中的示例代码。

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

if __name__=="__main__":
    if QCoreApplication.instance() != None:
        app = QCoreApplication.instance()
    else:
        app = QApplication(sys.argv)
    form = Form()
    form.show()
    app.exec_()

答案 2 :(得分:0)

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

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

对我有用的是输入

%复位

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

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

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_()

答案 3 :(得分:0)

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

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

这是源自here,它源于(并且更全面地解释)here