2013-10-18 74 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的。

相關問題