Created
February 2, 2016 13:21
-
-
Save jf---/01045fba04250c8dd486 to your computer and use it in GitHub Desktop.
WIP: ipython qml component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import QtQuick 2.0 | |
import IPython 1.0 | |
Item { | |
id: ipy_shell | |
IPyShellQml { | |
id: ipy_shell_qml | |
anchors.fill: parent | |
Component.onCompleted: { console.log(ipy_shell_qml + " initialized") } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
from PyQt5.QtCore import QUrl | |
from PyQt5.QtGui import QPixmap, QPainter | |
from PyQt5.QtQml import qmlRegisterType | |
from PyQt5.QtQuick import QQuickView, QQuickPaintedItem | |
from PyQt5.QtWidgets import QApplication | |
os.environ['QT_API'] = 'pyqt5' | |
from PyQt5 import QtWidgets | |
# ipython won't work if this is not correctly installed. And the error message will be misleading | |
# Import the console machinery from ipython | |
from IPython.qt.console.rich_ipython_widget import RichIPythonWidget | |
from IPython.qt.inprocess import QtInProcessKernelManager | |
def get_app_qt5(*args, **kwargs): | |
"""Create a new qt5 app or return an existing one.""" | |
app = QtWidgets.QApplication.instance() | |
if app is None: | |
if not args: | |
args = ([''],) | |
app = QtWidgets.QApplication(*args, **kwargs) | |
return app | |
class QIPythonWidget(RichIPythonWidget): | |
""" Convenience class for a live IPython console widget. We can replace the standard banner using the customBanner argument""" | |
def __init__(self, customBanner=None, *args, **kwargs): | |
super(QIPythonWidget, self).__init__(*args, **kwargs) | |
if customBanner != None: self.banner = customBanner | |
self.kernel_manager = kernel_manager = QtInProcessKernelManager() | |
kernel_manager.start_kernel() | |
kernel_manager.kernel.gui = 'qt' | |
self.kernel_client = kernel_client = self._kernel_manager.client() | |
kernel_client.start_channels() | |
def stop(): | |
kernel_client.stop_channels() | |
kernel_manager.shutdown_kernel() | |
get_app_qt5().exit() | |
self.exit_requested.connect(stop) | |
def pushVariables(self, variableDict): | |
""" Given a dictionary containing name / value pairs, push those variables to the IPython console widget """ | |
self.kernel_manager.kernel.shell.push(variableDict) | |
def clearTerminal(self): | |
""" Clears the terminal """ | |
self._control.clear() | |
def printText(self, text): | |
""" Prints some plain text to the console """ | |
self._append_plain_text(text) | |
def executeCommand(self, command): | |
""" Execute a command in the frame of the console widget """ | |
self._execute(command, False) | |
class IPyShellQml(QQuickPaintedItem): | |
""" Main GUI Window including a button and IPython Console widget inside vertical layout """ | |
def __init__(self, parent=None): | |
super(IPyShellQml, self).__init__(parent) | |
self.setFlag(QQuickPaintedItem.ItemHasContents, True) | |
self.ipyConsole = QIPythonWidget(customBanner="Welcome to the embedded ipython console\n") | |
self.ipyConsole.pushVariables({"foo": 43, "print_process_id": print_process_id}) | |
self.ipyConsole.printText("The variable 'foo' and the method 'print_process_id()' are available." | |
" Use the 'whos' command for information.\n\nTo push variables run this " | |
"before starting the UI:" | |
"\n ipyConsole.pushVariables({\"foo\":43,\"print_process_id\":print_process_id})") | |
def keyPressEvent(self, event): | |
self.ipyConsole.keyPressEvent(event) | |
def keyReleaseEvent(self, event): | |
self.ipyConsole.keyReleaseEvent(event) | |
def paint(self, painter): | |
painter.setRenderHints(QPainter.Antialiasing, True) | |
rect = self.contentsBoundingRect() | |
pix_map = QPixmap(rect.size().toSize()) | |
self.ipyConsole.render(pix_map) | |
painter.drawPixmap(rect, pix_map, rect) | |
def print_process_id(): | |
print('Process ID is:', os.getpid()) | |
def main(): | |
app = QApplication(sys.argv) | |
qmlRegisterType(IPyShellQml, "IPython", 1, 0, "IPyShellQml") | |
view = QQuickView(QUrl("ipy.qml")) | |
view.setResizeMode(QQuickView.SizeRootObjectToView) | |
view.resize(500, 500) | |
view.show() | |
app.exec_() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
WIP rendering a ipython qwidget as a QML component