2014-10-31 2 views
1

Я хочу поместить ipton qtconsole в приложение MDI pyqt в качестве подзаголовка, а затем создать другие подокна из qtconsole. Поэтому встроенная qtconsole должна иметь доступ к пространству имен приложения. Согласно this page из документов ipython, лучшим вариантом будет InProcessKernel. Я запустил this example script (воспроизведено ниже) с терминала python (если я запустил его из ipython, я получил MultipleInstanceError). Но забудьте о создании подокнов на данный момент, сначала мне нужно выяснить, как передать объекты во встроенную qtconsole.Встраивание ipython qtconsole и объектов передачи

  1. При первом запуске inprocess_qtconsole.py пространство имён встроенных qtconsole пуст. Почему объекты, ранее созданные в исходном терминале python или в скрипте, не передаются во встроенную qtconsole?
  2. Если я закрою приложение, содержащее встроенный qtconsole, определите некоторые переменные в исходном терминале и снова запустите сценарий, почему я могу теперь обращаться к этим переменным, а также от сценариев под if __name__ == __main__?
  3. Есть ли способ запустить встроенный qtconsole без блокировки терминала python, с которого я его начал?

основном я просто хочу, чтобы иметь возможность передать экземпляр QMainWindow во встроенную qtconsole, потому что создание подокна требует прохождения этого объекта (что-то вроде window.mdiArea.addSubWindow()). Это вроде бы работает хакерским способом, если я запускаю сценарий дважды.

Кстати, модуль internal_ipkernel, используемый в одном из других официальных примеров ipython (ipkernel_qtapp.py), кажется, отсутствует в последних версиях ipython.

Запуск 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() 

ответ

4

Вы можете использовать это, чтобы запустить консоль 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 one, только с указанными вами переменными (виджет, ядро, родительский объект здесь), то есть как консоль, так и командная строка имеют одинаковые ядра, а исходная - blo трахнуться.

Вы можете обойти такое поведение, выполнив вышеуказанное в приложении qt с другим основным окном и множеством взаимодействий. Чтобы передать переменные ядру, используйте (как указано выше) kernel.shell.push(dict).

+0

Ах, как-то я пропустил, что 'kernel.shell.push' был способом передачи объектов. А способ избежать блокировки заключался в том, чтобы опустить обычный 'app.exec _()' или 'guisupport.start_event_loop_qt4 (app)'. Благодаря! – firescape

+0

Спасибо, отличный ответ! Импорт из 'IPython.qt' теперь устарел для импорта из' qtconsole'. – hanslovsky

Смежные вопросы