我正在尝试学习PySide以进行我正在进行的项目。我正在完成Zetcode教程,但从一开始我就遇到了问题。我正在通过Enthought的Canopy编写和运行我的代码。当我从命令行运行代码时,它工作正常。 This question可能与我的问题有关,但没有给出答案。
当我使用教程中最简单的代码时
import sys
from PySide import QtGui
wid = QtGui.QWidget()
wid.resize(250, 150)
wid.setWindowTitle('Simple')
wid.show()
一切都正常运行。除了从OOP的角度来看,下一个例子或多或少都是一样的。
import sys
from PySide import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Icon')
self.setWindowIcon(QtGui.QIcon('web.png'))
self.show()
def main():
ex = Example()
if __name__ == '__main__':
main()
运行程序时闪烁(我可以看到窗口短暂显示)然后关闭。在main()
结束之前提出异常将使窗口保持在屏幕上。
TL; DR
为什么将程序放在一个类中使它不起作用?
答案 0 :(得分:2)
两个示例之间的区别在于,第一个示例将窗口小部件的引用保留为全局变量,而第二个示例创建一个局部变量,当它超出范围时(即函数返回时)进行垃圾收集
解决此问题的最简单方法是将ex
变量设为全局变量,如下所示:
def main():
global ex
ex = Example()
或者您可以摆脱main
功能,只需执行:
if __name__ == '__main__':
ex = Example()
答案 1 :(得分:1)
运行进出Canopy的区别在于,Canopy使用IPython QTConsole,默认情况下,在带有QT GUI后端的pylab模式下运行。关于这个(以及ipython的众多天才之一)的好处是你可以在命令提示符和GUI之间进行实时交互。
我怀疑你正在碰到pylab。像Matplotlib这样复杂的程序可以判断GUI事件循环是否已经启动,并相应地进行调整。但是出于您的目的,您可能只想禁用pylab模式,以便Canopy中的IPython更像是一个通用的python。为此,请从Canopy Preference菜单(Python选项卡)中禁用Pylab模式。