Skip to content

Commit 3ad2a30

Browse files
committed
Add WX client example.
1 parent 63e5ad1 commit 3ad2a30

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

notebooks/ipkernel_wxapp.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env python
2+
"""Example integrating an IPython kernel into a GUI App.
3+
4+
This trivial GUI application internally starts an IPython kernel, to which Qt
5+
consoles can be connected either by the user at the command line or started
6+
from the GUI itself, via a button. The GUI can also manipulate one variable in
7+
the kernel's namespace, and print the namespace to the console.
8+
9+
Play with it by running the script and then opening one or more consoles, and
10+
pushing the 'Counter++' and 'Namespace' buttons.
11+
12+
Upon exit, it should automatically close all consoles opened from the GUI.
13+
14+
Consoles attached separately from a terminal will not be terminated, though
15+
they will notice that their kernel died.
16+
17+
Ref: Modified from wxPython source code wxPython/samples/simple/simple.py
18+
"""
19+
#-----------------------------------------------------------------------------
20+
# Imports
21+
#-----------------------------------------------------------------------------
22+
import sys
23+
24+
import wx
25+
26+
from internal_ipkernel import InternalIPKernel
27+
28+
#-----------------------------------------------------------------------------
29+
# Functions and classes
30+
#-----------------------------------------------------------------------------
31+
32+
class MyFrame(wx.Frame, InternalIPKernel):
33+
"""
34+
This is MyFrame. It just shows a few controls on a wxPanel,
35+
and has a simple menu.
36+
"""
37+
38+
def __init__(self, parent, title):
39+
wx.Frame.__init__(self, parent, -1, title,
40+
pos=(150, 150), size=(350, 285))
41+
42+
# Create the menubar
43+
menuBar = wx.MenuBar()
44+
45+
# and a menu
46+
menu = wx.Menu()
47+
48+
# add an item to the menu, using \tKeyName automatically
49+
# creates an accelerator, the third param is some help text
50+
# that will show up in the statusbar
51+
menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample")
52+
53+
# bind the menu event to an event handler
54+
self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT)
55+
56+
# and put the menu on the menubar
57+
menuBar.Append(menu, "&File")
58+
self.SetMenuBar(menuBar)
59+
60+
self.CreateStatusBar()
61+
62+
# Now create the Panel to put the other controls on.
63+
panel = wx.Panel(self)
64+
65+
# and a few controls
66+
text = wx.StaticText(panel, -1, "Hello World!")
67+
text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
68+
text.SetSize(text.GetBestSize())
69+
qtconsole_btn = wx.Button(panel, -1, "Qt Console")
70+
ns_btn = wx.Button(panel, -1, "Namespace")
71+
count_btn = wx.Button(panel, -1, "Count++")
72+
close_btn = wx.Button(panel, -1, "Quit")
73+
74+
# bind the button events to handlers
75+
self.Bind(wx.EVT_BUTTON, self.new_qt_console, qtconsole_btn)
76+
self.Bind(wx.EVT_BUTTON, self.print_namespace, ns_btn)
77+
self.Bind(wx.EVT_BUTTON, self.count, count_btn)
78+
self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, close_btn)
79+
80+
# Use a sizer to layout the controls, stacked vertically and with
81+
# a 10 pixel border around each
82+
sizer = wx.BoxSizer(wx.VERTICAL)
83+
for ctrl in [text, qtconsole_btn, ns_btn, count_btn, close_btn]:
84+
sizer.Add(ctrl, 0, wx.ALL, 10)
85+
panel.SetSizer(sizer)
86+
panel.Layout()
87+
88+
# Start the IPython kernel with gui support
89+
self.init_ipkernel('wx')
90+
91+
def OnTimeToClose(self, evt):
92+
"""Event handler for the button click."""
93+
print("See ya later!")
94+
sys.stdout.flush()
95+
self.cleanup_consoles(evt)
96+
self.Close()
97+
# Not sure why, but our IPython kernel seems to prevent normal WX
98+
# shutdown, so an explicit exit() call is needed.
99+
sys.exit()
100+
101+
102+
class MyApp(wx.App):
103+
def OnInit(self):
104+
frame = MyFrame(None, "Simple wxPython App")
105+
self.SetTopWindow(frame)
106+
frame.Show(True)
107+
self.ipkernel = frame.ipkernel
108+
return True
109+
110+
#-----------------------------------------------------------------------------
111+
# Main script
112+
#-----------------------------------------------------------------------------
113+
114+
if __name__ == '__main__':
115+
app = MyApp(redirect=False, clearSigInt=False)
116+
117+
# Very important, IPython-specific step: this gets GUI event loop
118+
# integration going, and it replaces calling app.MainLoop()
119+
app.ipkernel.start()

0 commit comments

Comments
 (0)