Введение
В этом практическом занятии вы научитесь создавать приложение на wxPython, которое отображает математический текст в wx.Bitmap для отображения в различных элементах управления на wxPython. Для этого используется библиотека Matplotlib для преобразования текста в изображения и библиотека wxPython для отображения изображений.
Советы по использованию ВМ
После запуска виртуальной машины щелкните в верхнем левом углу, чтобы переключиться на вкладку Ноутбук и получить доступ к Jupyter Notebook для практики.
Иногда вам может потребоваться подождать несколько секунд, пока Jupyter Notebook не загрузится полностью. Проверка операций не может быть автоматизирована из-за ограничений Jupyter Notebook.
Если вы столкнетесь с проблемами во время обучения, не стесняйтесь обращаться к Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.
Установка необходимых библиотек
Для завершения этого практического занятия вам необходимо установить следующие библиотеки:
- wxPython
- Matplotlib
Вы можете установить эти библиотеки с помощью pip.
pip install wxPython
pip install matplotlib
Создайте приложение на wxPython
Создайте новый файл на Python и импортируйте необходимые библиотеки.
import wx
import numpy as np
from io import BytesIO
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
Преобразование текста с математическими символами в wx.Bitmap
Определите функцию, которая преобразует текст с математическими символами в wx.Bitmap. Эта функция использует Matplotlib для рисования текста в позиции (0, 0), а затем relies на facecolor="none" и bbox_inches="tight", pad_inches=0 для получения прозрачной маски, которая затем загружается в wx.Bitmap.
def mathtext_to_wxbitmap(s):
fig = Figure(facecolor="none")
text_color = (
np.array(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)) / 255)
fig.text(0, 0, s, fontsize=10, color=text_color)
buf = BytesIO()
fig.savefig(buf, format="png", dpi=150, bbox_inches="tight", pad_inches=0)
s = buf.getvalue()
return wx.Bitmap.NewFromPNGData(s, len(s))
Определите функции
Определите список функций, которые будет отображать приложение. Каждая функция определяется математическим текстом и лямбда-функцией, которая принимает входное значение и возвращает выходное значение.
functions = [
(r'$\sin(2 \pi x)$', lambda x: np.sin(2*np.pi*x)),
(r'$\frac{4}{3}\pi x^3$', lambda x: (4/3)*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))
]
Создайте рамку для холста
Создайте новый класс, наследующийся от wx.Frame. Этот класс создает холст, на котором отображается выбранная функция.
class CanvasFrame(wx.Frame):
def __init__(self, parent, title):
super().__init__(parent, -1, title, size=(550, 350))
self.figure = Figure()
self.axes = self.figure.add_subplot()
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.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):
self.toolbar = NavigationToolbar2Wx(self.canvas)
self.toolbar.Realize()
self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
self.toolbar.update()
Измените график
Определите функцию, которая изменяет график в зависимости от выбранной функции. Эта функция принимает plot_number в качестве входных данных и изменяет график в соответствии с ними.
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()
Создайте приложение
Создайте новый класс, наследующийся от wx.App. Этот класс создает рамку и запускает цикл событий.
class MyApp(wx.App):
def OnInit(self):
frame = CanvasFrame(None, "wxPython mathtext demo app")
self.SetTopWindow(frame)
frame.Show(True)
return True
Запустите приложение
Запустите приложение, создав экземпляр класса MyApp.
if __name__ == "__main__":
app = MyApp()
app.MainLoop()
Резюме
В этом практическом занятии вы узнали, как создать приложение на wxPython, которое отображает математический текст в wx.Bitmap. Вы использовали библиотеку Matplotlib для преобразования текста в изображения и библиотеку wxPython для отображения изображений. Также вы узнали, как создать панель кнопок и панель инструментов в приложении и как изменить график в зависимости от выбранной функции.