Replacing InteractiveShellEmbed with Qt console - ipython

I am running embedded ipython console via (simplified):
# the code uses PyQt4, this makes sure it is initialized properly
import IPython.lib.inputhook
qapp=IPython.lib.inputhook.enable_gui(gui='qt4')
# create the embedded terminal
from IPython.frontend.terminal.embed import InteractiveShellEmbed
ipshell=InteractiveShellEmbed()
ipshell()
What would this code look like if I would like to run ipython's Qt console instead of the embedded terminal shell? There are examples of using ipython qtconsole all around, but not how to integrate it into my own code.

There is an example script that works in this question: Embedding IPython Qt console in a PyQt application
Here you can find it for reference:
from IPython.zmq.ipkernel import IPKernelApp
from IPython.lib.kernel import find_connection_file
from IPython.frontend.qt.kernelmanager import QtKernelManager
from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
from IPython.utils.traitlets import TraitError
from PySide import QtGui, QtCore
import atexit
def event_loop(kernel):
kernel.timer = QtCore.QTimer()
kernel.timer.timeout.connect(kernel.do_one_iteration)
kernel.timer.start(1000*kernel._poll_interval)
def default_kernel_app():
app = IPKernelApp.instance()
app.initialize(['python', '--pylab=qt', '--profile=plask'])
app.kernel.eventloop = event_loop
return app
def default_manager(kernel):
connection_file = find_connection_file(kernel.connection_file)
manager = QtKernelManager(connection_file=connection_file)
manager.load_connection_file()
manager.start_channels()
atexit.register(manager.cleanup_connection_file)
return manager
def console_widget(manager):
try: # Ipython v0.13
widget = RichIPythonWidget(gui_completion='droplist')
except TraitError: # IPython v0.12
widget = RichIPythonWidget(gui_completion=True)
widget.kernel_manager = manager
return widget
def terminal_widget(**kwargs):
kernel_app = default_kernel_app()
manager = default_manager(kernel_app)
widget = console_widget(manager)
# Update namespace
kernel_app.shell.user_ns.update(kwargs)
kernel_app.start()
return widget
# This simply opens qtconsole widged in a new window. But you can find embed it wherever you want
app = QtGui.QApplication([''])
widget = terminal_widget(testing=123)
widget.setWindowTitle("Your console")
widget.show()
app.exec_()

Related

Adding checkable combobox in QGIS plugin builder plugin

I am developing a QGIS plugin in python and hit a roadblock when displaying my GUI. I am using the plugin builder framework to develop my plugin and I have trouble displaying a checkable combo box in a scrollArea in my GUI. The code with core functionality is as follows.
def run(self):
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
if self.first_start == True:
self.first_start = False
# Sets up the pyqt user interface
self.dlg = EarthingToolDialog()
# Fetching the active layer in the QGIS project
layer = self.iface.activeLayer()
checkable_combo = CheckableComboBox()
# Going through each field of the layer
# and adding field names as items to the
# combo box
for j,field in enumerate(layer.fields()):
checkable_combo.addItem(str(field.name()))
# Setting the checked state to True by default
checkable_combo.setItemChecked(j, True)
# putting the check box inside the scroll area of the GUI
self.dlg.scrollArea.setWidget(checkable_combo)
self.dlg.scrollArea.setMinimumSize(QSize(700,400))
# show the dialog
self.dlg.show()
# Run the dialog event loop
self.dlg.exec_()
class EarthingToolDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super(EarthingToolDialog, self).__init__(parent)
self.setupUi(self)
class CheckableComboBox(QComboBox):
def __init__(self):
super().__init__()
self._changed = False
self.view().pressed.connect(self.handleItemPressed)
def setItemChecked(self, index, checked=False):
print('checked')
item = self.model().item(index, self.modelColumn()) # QStandardItem object
print(type(item))
if checked:
item.setCheckState(Qt.CheckState.Checked)
else:
item.setCheckState(Qt.CheckState.Unchecked)
def handleItemPressed(self, index):
print('pressed')
item = self.model().itemFromIndex(index)
if item.checkState() == Qt.Checked:
item.setCheckState(Qt.Unchecked)
else:
item.setCheckState(Qt.Checked)
self._changed = True
print('set ' + str(item.checkState()))
def hidePopup(self):
print('hide')
if not self._changed:
super().hidePopup()
self._changed = False
def itemChecked(self, index):
print('read')
item = self.model().item(index, self.modelColumn())
return item.checkState() == Qt.Checked
In summary, the run function is the main function called by the plugin when it is loaded. self.dlg is the instance of the actual pyqt python user interface. This is rendered with the help of the EarthingToolDialog class. The checkable combo box and it's functionalities are self contained in the CheckableComboBox class.
The run function executes without any error when the plugin is loaded but the checkboxes are not visible in the combobox. Just a normal combo box with a list of items (just the standard dropdown combo box) is seen on the GUI's scroll area and not the desired checkable combo box. The CheckableComboBox class was taken from https://morioh.com/p/d1e70112347c and it runs perfectly well in the demo code shown there.
I understand that this is a very specific question and it would be great if someone could figure out what the problem might be. Thanks in advance!
Within the run function, this piece of codes didn't work for me:
self.dlg.scrollArea.setWidget(checkable_combo)
self.dlg.scrollArea.setMinimumSize(QSize(700,400))
So instead, I use:
layout = QVBoxLayout()
layout.addWidget(checkable_combo)
self.dlg.setLayout(layout)
I didn't use directly this class (It was generated automatically since I use Plugin Builder, so in here I commented it):
class EarthingToolDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super(EarthingToolDialog, self).__init__(parent)
self.setupUi(self)
Now, in order to display checkable combo box, CheckableComboBox constructor is changed as :
def __init__(self):
super().__init__()
self._changed = False
self.view().pressed.connect(self.handleItemPressed)
delegate = QtWidgets.QStyledItemDelegate(self.view())
self.view().setItemDelegate(delegate)
The last two lines are from the answer listed here.
Codes display checkable combo box list with all items checked by default.

Make jxBrowser open popups in the current window instead of "popping up"

How to set jxBrowser to open links that would pop-up in a new window to open on the calling page (or, at least, in a new tab)?
this is the call I think I have to override (it's the example):
//....
Engine engine = Engine.newInstance(
EngineOptions.newBuilder(
enderingMode.OFF_SCREEN ).enableIncognito().build()
Browser _browser = engine.newBrowser();
//this won't even compile
_browser.set(
OpenPopupCallback.class,
(params) -> {
// Access the created popup.
Browser popup = params.popupBrowser();
_browser.navigation().loadUrl(params.targetUrl());
return Response.proceed();
});
_browser.navigation().loadUrl("http://www.stackoverflow.com");
This is how I call it in my jfx but won't even compile, the code without this call works (opens a browser).
Update, given the nature of the popup I tried to rewrite javascript function (window.open) itself to force name to _parent.
This by running on every navigation the code
String the Javascript = "window.open = function (open) {return function (url, name, features{ console.log("open wrapper");return open.call(window, url, '_parent', features);};}(window.open);"
I thaught I couldn achieve this by
_browser.frames().get(0).executeJavaScript(theJavascript);
But in the remote console, I can't even see the log message ("open wrapper").
I double-checked the same code and it works if copy-pasted in the remote consolle.
What am I missing?
Here's complete JavaFX example that demonstrates how to open popup's URL in the main Browser instance and suppress popup:
import static com.teamdev.jxbrowser.engine.RenderingMode.OFF_SCREEN;
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.CreatePopupCallback;
import com.teamdev.jxbrowser.browser.callback.CreatePopupCallback.Response;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.view.javafx.BrowserView;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public final class SmokeTest extends Application {
#Override
public void start(Stage primaryStage) {
// Creating and running Chromium engine.
Engine engine = Engine.newInstance(OFF_SCREEN);
Browser browser = engine.newBrowser();
browser.set(CreatePopupCallback.class, params -> {
browser.navigation().loadUrl(params.targetUrl());
return Response.suppress();
});
// Creating UI component for rendering web content
// loaded in the given Browser instance.
BrowserView view = BrowserView.newInstance(browser);
BorderPane root = new BorderPane(view);
Scene scene = new Scene(root, 1280, 900);
primaryStage.setTitle("Hello World");
primaryStage.setScene(scene);
primaryStage.show();
browser.navigation().loadUrl(
"https://www.encodedna.com/javascript/demo/open-new-window-using-javascript-method.htm");
// Close the engine when stage is about to close.
primaryStage.setOnCloseRequest(event -> engine.close());
}
}
Run this program and click a button that displays popup. You will see that popup is not displayed and its URL is loaded in the main Browser.

Deploy Bokeh Document to Server

I am following the example code I've attached below. It currently displays the plot and associated slider embedded in the doc returned by the "modify_doc" function in the notebook. However, I'd like to deploy it into it's own server to make a GUI, while still maintaining it's ability to run the callback when the slider is changed and update the plot. However when I try to use Panel Pyviz to deploy it, it just displays the message "< bokeh.document.document.Document object at 0x00000193EC5FFE80 >" on the server that pops up. How do I deploy the doc in a way that will display the image?
import numpy as np
import holoviews as hv
from bokeh.io import show, curdoc
from bokeh.layouts import layout
from bokeh.models import Slider, Button
renderer = hv.renderer('bokeh').instance(mode='server')
# Create the holoviews app again
def sine(phase):
xs = np.linspace(0, np.pi*4)
return hv.Curve((xs, np.sin(xs+phase))).opts(width=800)
stream = hv.streams.Stream.define('Phase', phase=0.)()
dmap = hv.DynamicMap(sine, streams=[stream])
# Define valid function for FunctionHandler
# when deploying as script, simply attach to curdoc
def modify_doc(doc):
# Create HoloViews plot and attach the document
hvplot = renderer.get_plot(dmap, doc)
# Create a slider
def slider_update(attrname, old, new):
# Notify the HoloViews stream of the slider update
stream.event(phase=new)
start, end = 0, np.pi*2
slider = Slider(start=start, end=end, value=start, step=0.2, title="Phase")
slider.on_change('value', slider_update)
# Combine the holoviews plot and widgets in a layout
plot = layout([
[hvplot.state],
[slider]], sizing_mode='fixed')
doc.add_root(plot)
return doc
# To display in the notebook
show(modify_doc, notebook_url='localhost:8888')
# To display in a script
doc = modify_doc(curdoc())
# To deploy to separate server using Panel (attempt, doesn't work. Just displays #"<bokeh.document.document.Document object at 0x00000193EC5FFE80>":
graph = pn.Row (doc)
graph.show()
There is some mixing of very different APIs going on in your example. Panel is meant to simplify some of Bokeh's APIs so a lot of what you're doing here isn't necessary. That said I'll provide a few versions which are either using only Panel components or combining Panel and bokeh components.
To start with this is how I might write this example using just Panel:
import numpy as np
import panel as pn
import holoviews as hv
pn.extension()
start, end = 0, np.pi*2
slider = pn.widgets.FloatSlider(start=start, end=end, value=start, step=0.2, name="Phase")
#pn.depends(phase=slider.param.value)
def sine(phase):
xs = np.linspace(0, np.pi*4)
return hv.Curve((xs, np.sin(xs+phase))).opts(width=800)
dmap = hv.DynamicMap(sine)
row = pn.Row(dmap, slider)
# Show in notebook
row.app('localhost:8888')
# Open a server
row.show()
# To deploy this using `panel serve` or `bokeh serve`
row.servable()
In your example you instead use various bokeh components, this is also possible and might be desirable if you've already got bokeh code.
import numpy as np
import holoviews as hv
import panel as pn
from bokeh.models import Slider, Button
# Create the holoviews app again
def sine(phase):
xs = np.linspace(0, np.pi*4)
return hv.Curve((xs, np.sin(xs+phase))).opts(width=800)
stream = hv.streams.Stream.define('Phase', phase=0.)()
dmap = hv.DynamicMap(sine, streams=[stream])
def slider_update(attrname, old, new):
# Notify the HoloViews stream of the slider update
stream.event(phase=new)
start, end = 0, np.pi*2
slider = Slider(start=start, end=end, value=start, step=0.2, title="Phase")
slider.on_change('value', slider_update)
graph = pn.Row(dmap, slider)
# Show in notebook
row.app('localhost:8888')
# Open a server
row.show()
# To deploy this using `panel serve` or `bokeh serve`
row.servable()
If you want to serve these apps to multiple people I'd definitely recommend using panel serve but if you really want to make a script you can run with python script.py you should do this:
def app():
start, end = 0, np.pi*2
slider = pn.widgets.FloatSlider(start=start, end=end, value=start, step=0.2, name="Phase")
#pn.depends(phase=slider.param.value)
def sine(phase):
xs = np.linspace(0, np.pi*4)
return hv.Curve((xs, np.sin(xs+phase))).opts(width=800)
dmap = hv.DynamicMap(sine)
return pn.Row(dmap, slider)
pn.serve({'/': app})
This requires latest Panel, but ensures that even if you run the app as a script that each user gets a new instance of the app which does not share state with all others.

How to align widget buttons in IPython notebook

I have the following peace of code
from ipywidgets import widgets
from IPython.display import display
import numpy as np
class Test(object):
def __init__(self, arraylen):
self.a = np.random.randn(arraylen)
self.button = widgets.Button(description = 'Show')
self.button.on_click(self.show)
display(self.button)
self.button1 = widgets.Button(description = 'Show1')
self.button1.on_click(self.show)
display(self.button1)
def show(self, ev = None):
np.savetxt('test',self.a)
self.button.disabled = True
test = Test(10)
The output is two buttons in a column as shown here:
Would it also be possible, to embed the buttons in a HTML table (where I could choose them to be in a row), or any other organization scheme? Maybe it could look like this:
You could use (a very basic example):
from IPython.display import display
from ipywidgets import widgets
button1 = widgets.Button(description = 'Button1')
button2 = widgets.Button(description = 'Button2')
display(widgets.HBox((button1, button2)))
Here you can find basic and more complete examples about the use of the widgets. If you are using Jupyter you should adapt some info (from ipywidgets import widgets instead from IPython.html import widgets,...).

vaadin + scala : automatic push makes me waiting

I would like to perform a simple change of the text of a label, using vaadin 7 & scala.
here is my UI:
package com.example.scaladinchat
import com.github.nscala_time.time.Imports._
import vaadin.scala.UI
import vaadin.scala.VerticalLayout
import vaadin.scala.Label
import vaadin.scala.server.ScaladinRequest
import vaadin.scala.Button
import metier.Objets.Rdv
import models.{ oracle => myOracle }
import vaadin.scala.PushMode
class N02Parameters extends UI with myOracle { app =>
pushConfiguration.pushMode = PushMode.Automatic
val l = Label("zigouigoui")
def changeLabel{
access{
l.value="roploplo"
}
}
override def init(request: ScaladinRequest) {
content = new VerticalLayout {
add(l)
val b = Button("Click me!", { e =>
changeLabel
})
add(b)
}
}
}
but when I call the page, there is at the top-right of my window an waiting animation, and I wait but nothing happens.
can you tell me what's going wrong?
thanks
As I can not yet comment, I ask as an answer:
You can get the page running using only a label right? Cause I had a problem referring to scala and vaadin in connection with apache tomcat, which looked as you discribed.