簡體   English   中英

嵌入ipython qtconsole並傳遞對象

[英]embedding ipython qtconsole and passing objects

我想將ipython qtconsole放在MDI pyqt應用程序中作為子窗口,然后從qtconsole創建其他子窗口。 因此,嵌入式qtconsole需要能夠訪問應用程序的名稱空間。 根據該頁面從IPython中的文檔,一個InProcessKernel將是最好的解決方案。 我從python終端運行了這個示例腳本 (如下所示)(如果從ipython運行它,則會收到MultipleInstanceError)。 但是暫時不要創建子窗口,首先,我需要弄清楚如何將對象傳遞到嵌入式qtconsole中。

  1. 我第一次運行inprocess_qtconsole.py時,嵌入式qtconsole的名稱空間為空。 為什么先前在初始python終端或腳本中創建的對象不會傳遞給嵌入式qtconsole?
  2. 如果關閉包含嵌入式qtconsole的應用程序,在初始終端中定義一些變量,然后再次運行腳本,為什么現在可以訪問這些變量以及if __name__ == __main__下腳本中的變量?
  3. 有沒有一種方法可以啟動嵌入式qtconsole而不阻止我從中啟動的python終端?

我主要只是希望能夠將QMainWindow實例傳遞到嵌入式qtconsole中,因為創建子窗口需要傳遞該對象(類似於window.mdiArea.addSubWindow() )。 如果我兩次運行腳本,它的工作方式會有些怪異。

順便說一下,最新版本的ipython中似乎缺少其他官方ipython示例之一(ipkernel_qtapp.py)中使用的internal_ipkernel模塊。

運行Python 2.7,IPython 2.2 / 2.3和Windows 8.1。

from __future__ import print_function
import os

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


def print_process_id():
    print('Process ID is:', os.getpid())


def main():
    # Print the ID of the main process
    print_process_id()

    app = guisupport.get_app_qt4()

    # Create an in-process kernel
    # >>> print_process_id()
    # will print the same process ID as the main process
    kernel_manager = QtInProcessKernelManager()
    kernel_manager.start_kernel()
    kernel = kernel_manager.kernel
    kernel.gui = 'qt4'
    kernel.shell.push({'foo': 43, 'print_process_id': print_process_id})

    kernel_client = kernel_manager.client()
    kernel_client.start_channels()

    def stop():
        kernel_client.stop_channels()
        kernel_manager.shutdown_kernel()
        app.exit()

    control = RichIPythonWidget()
    control.kernel_manager = kernel_manager
    control.kernel_client = kernel_client
    control.exit_requested.connect(stop)
    control.show()

    guisupport.start_event_loop_qt4(app)


if __name__ == '__main__':
    test = 'hello'
    main()

您可以使用它在給定的qt小部件中啟動ipython控制台:

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

def put_ipy(parent):
    kernel_manager = QtInProcessKernelManager()
    kernel_manager.start_kernel()
    kernel = kernel_manager.kernel
    kernel.gui = 'qt4'

    kernel_client = kernel_manager.client()
    kernel_client.start_channels()
    kernel_client.namespace  = parent

    def stop():
        kernel_client.stop_channels()
        kernel_manager.shutdown_kernel()

    layout = QtGui.QVBoxLayout(parent)
    widget = RichIPythonWidget(parent=parent)
    layout.addWidget(widget)
    widget.kernel_manager = kernel_manager
    widget.kernel_client = kernel_client
    widget.exit_requested.connect(stop)
    ipython_widget = widget
    ipython_widget.show()
    kernel.shell.push({'widget':widget,'kernel':kernel, 'parent':parent})
    return {'widget':widget,'kernel':kernel}

要從控制台彈出窗口,可以運行

app = QtGui.QApplication([])
win = QtGui.QWidget(None)
win.show()
put_ipy(win)

但這會將原來的python解釋器換成一個空的ipy解釋器,只帶有您傳遞的已定義變量(widget,kernel,parent在這里),即控制台和命令行具有相同的內核,而原來的是受阻。

通過在帶有另一個主窗口和一組交互的qt應用程序中執行上述操作,可以避免這種行為。 要將變量傳遞給內核,請使用(如上所述) kernel.shell.push(dict)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM