2013-10-18 70 views
0

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

  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,2013年5月16日,00:03:43 )win32上的[MSC v.1600 32位(Intel)] 输入“help”,“copyright”,“credits”或“license”以获取更多信息。

导入的NumPy 1.7.1,SciPy 0.12.0,Matplotlib 1.3.0 + guidata 1.6.1,guiqwt 2.3.1 键入“科学”的更多细节。

+3

(* Spyder dev here *)你可以发布一个我可以在我身边测试的最小例子吗? –

+0

再次看到上面的帖子... – laptop2d

+0

[关闭PyQt4 Gui应用程序后Python内核崩溃]的可能重复(http://stackoverflow.com/questions/24041259/python-kernel-crashes-after-closing-an-pyqt4- GUI的应用程序) – patrickvacek

回答

3

要再次运行PyQt的应用Spyder,正在运行的应用程序必须被删除/销毁,但我们不能使用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_() 
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_() 
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_() 
0

这实际上似乎与IPython的一个问题内核及其与PyQt的交互。基本上,IPython似乎挂在Qt实例上,它需要在重新实例化之前清除。这可以通过重新绑定变量保存Qt的情况下别的东西很简单做到:

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

这是从here,这是源自(并且更充分地解释)here的。

相关问题