导入错误:将IPython嵌入PyQt应用程序

1 投票
1 回答
1488 浏览
提问于 2025-04-17 21:42

我有一个完全可以运行的基于PyQt4的应用程序,现在我想在里面嵌入一个IPython控制台,作为一种脚本环境。

我大致调整了来自IPython的GitHub页面的示例,以适应我应用程序的模块系统。但是,如果任何 PyQt的导入在IPython的导入之前发生

from IPython.qt.console.rich_ipython_widget import RichIPythonWidget
from IPython.qt.inprocess import QtInProcessKernelManager

我就会遇到以下错误:

ImportError: 
Could not load requested Qt binding. Please ensure that
PyQt4 >= 4.7 or PySide >= 1.0.3 is available,
and only one is imported per session.

Currently-imported Qt library:   'pyqtv1'
PyQt4 installed:                 True
PySide >= 1.0.3 installed:       False
Tried to load:                   ['pyside', 'pyqt']

我追踪到这个错误是由于IPythonqt模块引起的,但基本上强制加载'pyqtv1'(通过将api_opts = [QT_API]替换为api_opts = ['pyqtv1'])会导致IPython窗口里的QString出现问题。

不过,如果我先进行这些导入(通过在其他任何东西之前导入这个代码所在的模块),那个错误就消失了,但这会导致QString完全崩溃,并出现ImportError: cannot import name QString的错误。

我确认如果在包含IPython实例的模块中创建一个独立的QApplication,并确保在做完IPython的导入后再导入PyQt.QtGui,它就能正常工作。问题只出现在我尝试将IPython代码与其他PyQt代码混合时。

有没有什么建议可以解决这个错误?

我使用的是Ubuntu Linux 12.04,IPython的版本是2.0.0-dev,拉取于3月10日。

1 个回答

0

PyQt提供了两种不同的字符串处理方式,你可以通过下面的代码来选择使用哪一种:

import sip
sip.setapi('QString', 2)
from PyQt4 import QtGui

一旦你导入了PyQt4,这种方式就确定了,不能再改变。在Python 2中,默认使用的是第一种方式,以便与旧版本兼容,但IPython需要使用第二种方式。在Python 3中,默认使用的是第二种方式,而PySide的方式也和第二种一样。

如果你在应用程序中使用了第一种方式,就不能在这个应用程序中使用嵌入的IPython Qt控制台,除非你把它转换成第二种方式。不过,你可以在你的应用程序中嵌入一个IPython内核,然后从一个单独的进程中的Qt控制台连接到它。

撰写回答