Ситуация №1: Нужно оконное приложение, написанное на библиотеке tkinter, способное отображать как обычный текст, так и математические формулы, переданные в виде latex-кода.
Решение №1: написать latex-виджет, способный на это.
Ситуация №2: так как отображаемые данным приложением математические формулы могут занимать несколько строк или быть слишком длинными, места на экране может не хватить.
Решение №2:
1) Установить достаточно большие размеры latex-виджета;
2) Использовать полосы прокрутки.
Ситуация №3: при использовании полос прокрутки часть математических формул не видна, так как вместо них отображается серый фон.
Решение №3: ???
import tkinter as tk
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
matplotlib.use('TkAgg')
plt.rcParams['text.usetex'] = True # https://stackoverflow.com/questions/71250205/matplotlib-runtime-error-latex-was-not-able-to-process-the-following-string
plt.rc('text.latex', preamble=r'''\usepackage{amsmath} \usepackage[english,russian]{babel} \usepackage{amssymb}''')
class Main_App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# region Развернуть окно
self.state('zoomed')
# endregion
# region Создаём внутри окна Глобальный холст self.global_canvas (и размещаем его слева)
self.global_canvas = tk.Canvas(master=self)
# self.global_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# endregion
# region Создаём self.frm внутри self.global_canvas; На нём будет размещаться всё
self.frm = tk.Frame(master=self.global_canvas, bg='orange')
self.frm.grid()
# endregion
# region Создаём Scrollbar внутри окна (и размещаем его справа)
self.vertical_scrollbar = tk.Scrollbar(master=self, command=self.global_canvas.yview)
self.vertical_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# endregion
# region Настройка Scrollbar-а. Она там как-то внутри работает. НЕХОРОШО, что не разбираюсь в этом полностью
self.global_canvas.configure(yscrollcommand=self.vertical_scrollbar.set)
for event in ('Configure', 'MouseWheel'):
self.frm.bind(f'<{event}>', lambda event: self.global_canvas.configure(scrollregion=self.global_canvas.bbox('all')))
self.global_canvas.create_window((10, 10), window=self.frm, anchor='nw')
# endregion
# region Создаём Scrollbar внутри окна (и размещаем его снизу)
self.horizontal_scrollbar = tk.Scrollbar(master=self, orient=tk.HORIZONTAL, command=self.global_canvas.xview)
self.horizontal_scrollbar.pack(side=tk.BOTTOM, fill=tk.X)
# endregion
# region Настройка Scrollbar-а. Она там как-то внутри работает. НЕХОРОШО, что не разбираюсь в этом полностью
self.global_canvas.configure(xscrollcommand=self.horizontal_scrollbar.set)
for event in ('Configure', 'MouseWheel'):
self.frm.bind(f'<{event}>', lambda event: self.global_canvas.configure(scrollregion=self.global_canvas.bbox('all')))
self.global_canvas.create_window((10, 10), window=self.frm, anchor='nw')
# endregion
self.global_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # важно именно здесь!
class LateXLbl(tk.Label):
"""link = 'https://stackoverflow.com/questions/36636185/is-it-possible-for-python-to-display-latex-in-real-time-in-a-text-box'"""
def __init__(
self,
sides_size: tuple[int | float, int | float],
dpi: int,
fontsize: int,
x_indent, y_indent,
*args, **kwargs
) -> None:
"""dpi - увеличение"""
super().__init__(*args, **kwargs)
# region Инициализация полей класса
for attr_name in ('fontsize', 'x_indent', 'y_indent'):
setattr(self, attr_name, eval(attr_name))
self._cur_latex_code: str = ''
# endregion
self.fig = matplotlib.figure.Figure(figsize=sides_size, dpi=dpi)
self.ax = self.fig.add_subplot(111)
self.canvas = FigureCanvasTkAgg(self.fig, master=self)
self.canvas.get_tk_widget().pack(side="top", fill="both", expand=True)
self.canvas._tkcanvas.pack(side="top", fill="both", expand=True)
# region Отключаем прорисовку осей
self.ax.get_xaxis().set_visible(False)
self.ax.get_yaxis().set_visible(False)
self.ax.spines['top'].set_visible(False)
self.ax.spines['right'].set_visible(False)
self.ax.spines['bottom'].set_visible(False)
self.ax.spines['left'].set_visible(False)
# endregion
def write(self, tmptext: str) -> None:
self._cur_latex_code: str = tmptext
self.ax.text(self.x_indent, self.y_indent, tmptext, fontsize=self.fontsize)
self.canvas.draw()
def _clear(self) -> None:
self.ax.clear()
def clear(self) -> None:
self._cur_latex_code: str = ''
self._clear()
text = property(fget=lambda self: self._cur_latex_code, fset=write)
root = Main_App()
ltx = LateXLbl(master=root.frm, sides_size=(20, 20), dpi=100, fontsize=100, x_indent=0.1, y_indent=0.1)
ltx.pack()
ltx.text = '$\\sum_{i=0}^5(x_i); $' * 10
root.mainloop()