使用IPython运行PyQt

问题

PyQt在Python中直接执行需要调用QCoreApplication.exec()开始消息循环,但是调用该函数会阻塞命令行。

解决方法

使用IPython特有的扩展脚本:

1
%gui qt

调用该脚本后,IPython会自动开启消息循环,不需要再调用QCoreApplication.exec()阻塞命令行。

但是,如果使用的是其他版本的Qt库,比如PySide6,使用该方法会默认调用PyQt6,导致不再能导入PySide6。

因此,应当提前导入PySide6,再开启消息循环,以绕过IPython的自动选择机制:

1
2
from PySide6.QtWidgets import *
%gui qt

这里必须是PySide6.QtWidgets,因为QApplication类在QtWidgets模块中定义,而IPython的自动选择机制会依赖于QApplication

%gui相关代码可以在IPython.terminal.pt_inputhooks库中找到。

最终结论

使用如下代码即可在IPython中运行PyQt或PySide,并且导入常用的模块:

1
2
3
4
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
%gui qt

参考资料

  1. Integrating with GUI event loops - IPython documentation
  2. How to have Qt run asynchroneously for interactive use like Matplotlib's ion mode? - Stack Overflow