WX中的数学文本

演示如何将数学文本转换为wx.Bitmap,以便在wxPython的各种控件中显示。

1
2
3
4
5
6
7
8
9
10
11
import matplotlib
matplotlib.use("WxAgg")
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
import numpy as np

import wx

IS_GTK = 'wxGTK' in wx.PlatformInfo
IS_WIN = 'wxMSW' in wx.PlatformInfo

This is where the “magic” happens.

1
2
3
4
5
6
7
8
9
from matplotlib.mathtext import MathTextParser
mathtext_parser = MathTextParser("Bitmap")


def mathtext_to_wxbitmap(s):
ftimage, depth = mathtext_parser.parse(s, 150)
return wx.Bitmap.FromBufferRGBA(
ftimage.get_width(), ftimage.get_height(),
ftimage.as_rgba_str())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
functions = [
(r'$\sin(2 \pi x)$', lambda x: np.sin(2*np.pi*x)),
(r'$\frac{4}{3}\pi x^3$', lambda x: (4.0/3.0)*np.pi*x**3),
(r'$\cos(2 \pi x)$', lambda x: np.cos(2*np.pi*x)),
(r'$\log(x)$', lambda x: np.log(x))
]


class CanvasFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, size=(550, 350))

self.figure = Figure()
self.axes = self.figure.add_subplot(111)

self.canvas = FigureCanvas(self, -1, self.figure)

self.change_plot(0)

self.sizer = wx.BoxSizer(wx.VERTICAL)
self.add_buttonbar()
self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
self.add_toolbar() # comment this out for no toolbar

menuBar = wx.MenuBar()

# File Menu
menu = wx.Menu()
m_exit = menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample")
menuBar.Append(menu, "&File")
self.Bind(wx.EVT_MENU, self.OnClose, m_exit)

if IS_GTK or IS_WIN:
# Equation Menu
menu = wx.Menu()
for i, (mt, func) in enumerate(functions):
bm = mathtext_to_wxbitmap(mt)
item = wx.MenuItem(menu, 1000 + i, " ")
item.SetBitmap(bm)
menu.Append(item)
self.Bind(wx.EVT_MENU, self.OnChangePlot, item)
menuBar.Append(menu, "&Functions")

self.SetMenuBar(menuBar)

self.SetSizer(self.sizer)
self.Fit()

def add_buttonbar(self):
self.button_bar = wx.Panel(self)
self.button_bar_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.sizer.Add(self.button_bar, 0, wx.LEFT | wx.TOP | wx.GROW)

for i, (mt, func) in enumerate(functions):
bm = mathtext_to_wxbitmap(mt)
button = wx.BitmapButton(self.button_bar, 1000 + i, bm)
self.button_bar_sizer.Add(button, 1, wx.GROW)
self.Bind(wx.EVT_BUTTON, self.OnChangePlot, button)

self.button_bar.SetSizer(self.button_bar_sizer)

def add_toolbar(self):
"""Copied verbatim from embedding_wx2.py"""
self.toolbar = NavigationToolbar2Wx(self.canvas)
self.toolbar.Realize()
# By adding toolbar in sizer, we are able to put it at the bottom
# of the frame - so appearance is closer to GTK version.
self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
# update the axes menu on the toolbar
self.toolbar.update()

def OnChangePlot(self, event):
self.change_plot(event.GetId() - 1000)

def change_plot(self, plot_number):
t = np.arange(1.0, 3.0, 0.01)
s = functions[plot_number][1](t)
self.axes.clear()
self.axes.plot(t, s)
self.canvas.draw()

def OnClose(self, event):
self.Destroy()


class MyApp(wx.App):
def OnInit(self):
frame = CanvasFrame(None, "wxPython mathtext demo app")
self.SetTopWindow(frame)
frame.Show(True)
return True

app = MyApp()
app.MainLoop()

下载这个示例