为我的 PyQt 应用程序使用 IPython Qt 控制台
Posted
技术标签:
【中文标题】为我的 PyQt 应用程序使用 IPython Qt 控制台【英文标题】:Coopt IPython Qt Console for my PyQt Application 【发布时间】:2015-04-24 21:11:55 【问题描述】:我正在使用 Python 创建一个控制台驱动的 Qt 应用程序。我不想实现我自己的自定义控制台,而是想嵌入 IPython Qt 控制台,同时让它响应我的应用程序。例如,我希望某些关键字输入到控制台以触发我的主应用程序中的操作。所以我在控制台中输入“dothis”,然后在我的应用程序的另一个窗口中显示一个绘图。
我看到了一些类似的问题:this one 讨论了如何将 IPython Qt 小部件嵌入到您的应用程序中并传递函数,尽管看起来这些函数在 IPython 内核中执行,而不是在我的 main 内核中执行应用程序。还有this guy,但是我不能执行示例中的代码(已经两年了),而且它看起来也不像我想要的那样。
有没有一种方法可以传入将在我的主内核中执行的函数或方法,或者至少通过与 IPython 内核通信以某种方式模拟这种行为?以前有人做过吗?
【问题讨论】:
在 IPython 存储库中有 an example 用于在同一应用程序中嵌入 Qt 控制台和内核。不过,它从来都不是最稳定或最受支持的东西。如果您只需要触发某些预定义的函数,您可以使用某种 RPC 机制将它们公开回 IPython 内核 - 或者像 Pyro 4 这样的现成的东西,或者如果满足您的需要,可以使用简单的自定义东西。 我开始着手移植控制台代码并将其手动集成到我的应用程序中,但我一直希望能保持 IPython 框架完好无损。 【参考方案1】:这是我想出的,到目前为止它运行良好。我继承了 RichIPythonWidget 类并重载了_execute
方法。每当用户在控制台中输入内容时,我都会根据已注册的命令列表对其进行检查;如果它匹配一个命令,那么我执行命令代码,否则我只是将输入传递给默认的_execute
方法。
控制台代码:
from IPython.qt.console.rich_ipython_widget import RichIPythonWidget
class CommandConsole( RichIPythonWidget ):
"""
This is a thin wrapper around IPython's RichIPythonWidget. It's
main purpose is to register console commands and intercept
them when typed into the console.
"""
def __init__(self, *args, **kw ):
kw['kind'] = 'cc'
super(CommandConsole, self).__init__(*args, **kw)
self.commands =
def _execute(self, source, hidden):
"""
Overloaded version of the _execute first checks the console
input against registered commands. If it finds a command it
executes it, otherwise it passes the input to the back kernel
for processing.
"""
try:
possible_cmd = source.split()[0].strip()
except:
return super(CommandConsole, self)._execute("pass", hidden)
if possible_cmd in self.commands.keys():
# Commands return code that is passed to the console for execution.
s = self.commands[possible_cmd].execute()
return super(CommandConsole, self)._execute( s, hidden )
else:
# Default back to the original _execute
return super(CommandConsole, self)._execute(source, hidden)
def register_command( self, name, command ):
"""
This method links the name of a command (name) to the function
that should be called when it is typed into the console (command).
"""
self.commands[name] = command
示例命令:
from PyQt5.QtCore import pyqtSignal, QObject, QFile
class SelectCommand( QObject ):
"""
The Select command class.
"""
# This signal is emitted whenever the command is executed.
executed = pyqtSignal( str, dict, name = "selectExecuted" )
# This is the command as typed into the console.
name = "select"
def execute(self):
"""
This method is executed whenever the ``name`` command is issued
in the console.
"""
name = "data description"
data = "data dict" : 0
# The signal is sent to my Qt Models
self.executed.emit( name, data )
# This code is executed in the console.
return 'print("the select command has been executed")'
【讨论】:
以上是关于为我的 PyQt 应用程序使用 IPython Qt 控制台的主要内容,如果未能解决你的问题,请参考以下文章
为啥 PyQt4 在 Jupyter 和 IPython 笔记本之间的行为不同?