From e33e835bd426e232d37741f1fbc98c1467628c1a Mon Sep 17 00:00:00 2001 From: Stefan Hacker Date: Sun, 16 Nov 2014 21:43:17 +0100 Subject: [PATCH 1/2] Add interactive IPython console as a dock widget. Turns out IPython makes embedding it into Qt applications trivial. Since everything is better with an IPython console this patch adds a console dock widget to LogikSim. --- .travis.yml | 4 +-- requirements.txt | 1 + src/docks/console_widget.py | 54 +++++++++++++++++++++++++++++++++++++ src/main_window.py | 10 +++++++ src/main_window.ui | 21 +++++++++++++++ src/resources_rc.py | 2 +- src/ui_main_window.py | 11 +++++++- 7 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 src/docks/console_widget.py diff --git a/.travis.yml b/.travis.yml index 5cad025..e74c7d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,10 +4,10 @@ python: before_install: - "sudo apt-get update" install: - - "sudo apt-get install -y python3-pyside xvfb" + - "sudo apt-get install -y python3-pyside ipython3 xvfb" - pip install coveralls pylama script: - pylama src/ - xvfb-run --server-args="-screen 0 1280x1024x16" coverage run --source=src -m unittest discover -s src/tests/ -t src after_success: - coveralls \ No newline at end of file + coveralls diff --git a/requirements.txt b/requirements.txt index 3e7394c..21f663e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ PySide>=1.2.2 pylama cx_Freeze +ipython diff --git a/src/docks/console_widget.py b/src/docks/console_widget.py new file mode 100644 index 0000000..9d2ca79 --- /dev/null +++ b/src/docks/console_widget.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright 2011-2014 The LogikSim Authors. All rights reserved. +# Use of this source code is governed by the GNU GPL license that can +# be found in the LICENSE.txt file. +# +''' +Rich integrated IPython console as for use in dock widget. +''' + +from IPython.qt.console.rich_ipython_widget import RichIPythonWidget +from IPython.qt.inprocess import QtInProcessKernelManager +from PySide import QtCore + + +class ConsoleWidget(RichIPythonWidget): + """ + Rich interactive ipython console widget. + """ + def __init__(self, parent=None): + """ + Creates a new interactive ipython console. + + Starts an IPython in-process kernel and embeds a RichIPythonWidget + for interacting with it. Expose application variables using + the expose function. + + :param parent: Optional Qt parent widget + """ + super().__init__(parent) + + # Start interactive python shell + self.kernel_manager = QtInProcessKernelManager() + self.kernel_manager.start_kernel() + self.kernel = self.kernel_manager.kernel + self.kernel.gui = 'qt' + + kernel_client = self.kernel_manager.client() + kernel_client.start_channels() + + self.kernel_manager = self.kernel_manager + self.kernel_client = kernel_client + + self.height = 10 # Reduce default number of rows. + + @QtCore.Slot(dict) + def expose(self, what): + """ + Exposes the given variables to the interactive shell. + + :param what: Dictionary of variable name to variable to expose. + """ + self.kernel.shell.push(what) diff --git a/src/main_window.py b/src/main_window.py index 9b1afd2..b6317e2 100755 --- a/src/main_window.py +++ b/src/main_window.py @@ -70,8 +70,18 @@ def __init__(self, parent=None): # Add toggle view actions for dockwidgets self.toggle_history_dock_widget_view_qaction = self.history_dock_widget.toggleViewAction() self.menu_view.addAction(self.toggle_history_dock_widget_view_qaction) + self.toggle_console_dock_widget_view_qaction = self.console_dock_widget.toggleViewAction() + self.menu_view.addAction(self.toggle_console_dock_widget_view_qaction) + + # Console + self.console_dock_widget.hide() # Hidden by default + self.console_widget.exit_requested.connect(self.close) # Request exit from console exits LogikSim + self.console_widget.expose({'app': QtGui.QApplication.instance(), + 'main_window': self, + 'settings': settings()}) s = settings() + # Restore layout self.restoreGeometry(s.main_window_geometry) self.restoreState(s.main_window_state) diff --git a/src/main_window.ui b/src/main_window.ui index 031cb01..bb2fbbf 100644 --- a/src/main_window.ui +++ b/src/main_window.ui @@ -131,6 +131,21 @@ + + + + 80 + 50 + + + + Console + + + 8 + + + &Exit @@ -169,6 +184,12 @@ QListView
actions/action_stack_view/
+ + ConsoleWidget + QWidget +
docks/console_widget/
+ 1 +
diff --git a/src/resources_rc.py b/src/resources_rc.py index 68d244f..f909fb8 100755 --- a/src/resources_rc.py +++ b/src/resources_rc.py @@ -2,7 +2,7 @@ # Resource object code # -# Created: Thu 16. Oct 22:16:21 2014 +# Created: Sun 16. Nov 21:42:06 2014 # by: The Resource Compiler for PySide (Qt v4.8.5) # # WARNING! All changes made in this file will be lost! diff --git a/src/ui_main_window.py b/src/ui_main_window.py index babde6a..b592b3c 100755 --- a/src/ui_main_window.py +++ b/src/ui_main_window.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'main_window.ui' # -# Created: Thu Oct 16 22:16:21 2014 +# Created: Sun Nov 16 21:42:06 2014 # by: pyside-uic 0.2.15 running on PySide 1.2.2 # # WARNING! All changes made in this file will be lost! @@ -66,6 +66,13 @@ def setupUi(self, MainWindow): self.verticalLayout_2.addWidget(self.action_stack_view) self.history_dock_widget.setWidget(self.history_widget) MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.history_dock_widget) + self.console_dock_widget = QtGui.QDockWidget(MainWindow) + self.console_dock_widget.setMinimumSize(QtCore.QSize(80, 50)) + self.console_dock_widget.setObjectName("console_dock_widget") + self.console_widget = ConsoleWidget() + self.console_widget.setObjectName("console_widget") + self.console_dock_widget.setWidget(self.console_widget) + MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(8), self.console_dock_widget) self.action_exit = QtGui.QAction(MainWindow) self.action_exit.setObjectName("action_exit") self.action_redo = QtGui.QAction(MainWindow) @@ -98,11 +105,13 @@ def retranslateUi(self, MainWindow): self.menu_help.setTitle(QtGui.QApplication.translate("MainWindow", "&Help", None, QtGui.QApplication.UnicodeUTF8)) self.tool_bar.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Toolbar", None, QtGui.QApplication.UnicodeUTF8)) self.history_dock_widget.setWindowTitle(QtGui.QApplication.translate("MainWindow", "History", None, QtGui.QApplication.UnicodeUTF8)) + self.console_dock_widget.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Console", None, QtGui.QApplication.UnicodeUTF8)) self.action_exit.setText(QtGui.QApplication.translate("MainWindow", "&Exit", None, QtGui.QApplication.UnicodeUTF8)) self.action_redo.setText(QtGui.QApplication.translate("MainWindow", "&Redo", None, QtGui.QApplication.UnicodeUTF8)) self.action_undo.setText(QtGui.QApplication.translate("MainWindow", "&Undo", None, QtGui.QApplication.UnicodeUTF8)) self.action_about.setText(QtGui.QApplication.translate("MainWindow", "&About", None, QtGui.QApplication.UnicodeUTF8)) self.action_about_qt.setText(QtGui.QApplication.translate("MainWindow", "About &Qt", None, QtGui.QApplication.UnicodeUTF8)) +from docks.console_widget import ConsoleWidget from actions.action_stack_view import ActionStackView import resources_rc From 9c7068e63a3e00c0d8d01067286917f1bba4260f Mon Sep 17 00:00:00 2001 From: Stefan Hacker Date: Sun, 16 Nov 2014 22:49:52 +0100 Subject: [PATCH 2/2] Add missing travis and appveyor dependencies --- .travis.yml | 2 +- requirements.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e74c7d1..e24acb6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ python: before_install: - "sudo apt-get update" install: - - "sudo apt-get install -y python3-pyside ipython3 xvfb" + - "sudo apt-get install -y python3-pyside ipython3 ipython3-qtconsole xvfb" - pip install coveralls pylama script: - pylama src/ diff --git a/requirements.txt b/requirements.txt index 21f663e..5370ad5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,5 @@ PySide>=1.2.2 pylama cx_Freeze ipython +# Seems like ipython doesn't declare all dependencies: +pygments