我在IPython中做了一些非常简单的PySide(和PyQt)教程。一个教程只是创建一个带有一些滑块的窗口来演示插槽和信号。
当我关闭正在运行的演示应用程序的窗口时,我看到了这个错误:
An exception has occurred, use %tb to see the full traceback.
SystemExit: 0
To exit: use 'exit', 'quit', or Ctrl-D.
所以我运行%tb并得到这个:
SystemExit Traceback (most recent call last)
/Workspaces/scratch/<ipython-input-1-88966dcfb499> in <module>()
33
34 if __name__ == "__main__":
---> 35 main()
/Workspaces/scratch/<ipython-input-1-88966dcfb499> in main()
29 w.show()
30 app.exec_()
---> 31 sys.exit(0)
32
33
SystemExit: 0
如果我再次尝试执行我的代码,我会得到这个:
RuntimeError: A QApplication instance already exists.
如果它有帮助,这里是我的代码:
from PySide.QtCore import *
from PySide.QtGui import *
import sys
class MyWindow(QWidget):
def __init__(self):
QWidget.__init__(self, None)
vbox = QVBoxLayout(self)
self.slider1 = QSlider(Qt.Horizontal)
self.slider1.setRange(0, 99)
self.slider1.setValue(0)
vbox.addWidget(self.slider1)
self.slider2 = QSlider(Qt.Horizontal)
self.slider2.setRange(0, 99)
self.slider2.setValue(99)
vbox.addWidget(self.slider2)
self.slider1.valueChanged.connect(self.slider2Changed)
def slider2Changed(self, position):
self.slider2.setValue(self.slider2.maximum() - position)
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec_()
sys.exit(0)
if __name__ == "__main__":
main()
使用python运行代码时没有错误:
python myexample.py
当我在IPython(包括笔记本或qtconsole或常规ipython终端)中运行代码时,才会发生此错误。
更新:我的主要问题是我无法快速轻松地再次运行应用程序。如果我再次尝试运行我的代码,我会得到这个:
RuntimeError: A QApplication instance already exists.
这杀死了IPython的快速,互动性:(
答案 0 :(得分:21)
感谢来自ipython-users邮件列表的Matthias BUSSONNIER。
当我关闭正在运行的演示应用程序的窗口时,我看到此错误: 发生异常,使用%tb查看完整的回溯。 SystemExit:0
只是不要使用sys.exit(0),因为你没有退出python,但仍在运行IPython。
如果您希望从(真实)命令行运行应用程序并返回状态,请将其添加回来。
如果我再次尝试执行我的代码,我会得到这个:
RuntimeError:QApplication实例已存在。
这是一个他们“不会修复”的PySide Bug,因为他们认为它不是一个bug。
见https://github.com/ipython/ipython/issues/1124)
和http://bugs.pyside.org/show_bug.cgi?id=855
QApplication只能有一个实例并退出应用程序 显然不被认为是足够的理由删除 对象...
您可以使用以上问题中的此代码:
app=QtGui.QApplication.instance() # checks if QApplication already exists
if not app: # create QApplication if it doesnt exist
app = QtGui.QApplication(sys.argv)
这足以满足我目前的需求。
答案 1 :(得分:9)
您需要做的是使QApplication稍后被删除,如:
app = QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
使用此代码,您可以在IPython中或其他任何地方重新运行应用程序,并且每次关闭qt应用程序时,都将在python中删除该对象。
答案 2 :(得分:4)
sys.exit
只需引发SystemExit
即可终止互操作程序。
ipython在交互模式下执行脚本时捕获SysExit
,因此这不是一个错误但是ipython的一个功能确实避免了交互式解释器在执行脚本时被关闭,因为这不是什么你通常想要一个互动的会议。
答案 3 :(得分:3)
根据https://github.com/spyder-ide/spyder/issues/4639
首先,检查实例是否已经存在,然后分配该实例或创建一个新实例:
c = [[x + y for x, y in zip(s1, s2)] for s1, s2 in zip(a, b)]
(此摘要摘自@NotSoBrainy的答案。)
然后,在#print(c)
[[6, 6, 9, 9], [9, 11, 12, 10]]
方法之后:
if not QApplication.instance():
app = QApplication(sys.argv)
else:
app = QApplication.instance()
不需要show()
。
这解决了我的问题,完全一样。
答案 4 :(得分:0)
检查是否已经存在QApplication实例,因为当实例正在运行并且您尝试创建一个新实例时会发生错误。
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app = QtWidgets.QApplication.instance()