为什么 try 循环不能捕获来自 Matplotlib mathtext 的 ParseException?

问题描述 投票:0回答:1

wxPython 4.2.0 x Matplotlib 3.6.0

我正在开发一个 GUI,用户可以在 textctrl 中写下图形标题,然后将这个标题设置在图形上并显示图形。

我目前的问题是,我不明白为什么当标题是错误的数学文本时,try 循环无法捕获发生的 ParseException。

我的问题的简化代码是:

import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
import wx

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MainFrame(parent=None, title="Test")
        self.frame.Show()
        return True

class MainFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, None, -1, title=title)
        fig = plt.figure()
        fig.suptitle('$$')
        try:
            self.canvas = FigureCanvas(self, 0, fig)
        except:
            self.canvas = FigureCanvas(self, 0, plt.figure())
        plt.close()
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        hbox.Add(self.canvas)
        self.SetSizer(hbox)

if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()

我收到以下错误:

Traceback (most recent call last):
...
    raise exc.with_traceback(None)
pyparsing.exceptions.ParseException: Expected end of text, found '$'  (at char 0), (line:1, col:1)

The above exception was the direct cause of the following exception:
...
...
ValueError:
$$
^
Expected end of text, found '$'  (at char 0), (line:1, col:1)

try 循环应该捕捉到,我错了吗?

例如,我使用了 set_parse_math(False) 方法,因此不会发生错误,但是,我想了解这段代码有什么问题。

matplotlib user-interface canvas try-catch wxpython
1个回答
0
投票

我根据以下讨论找到了解决方案:

在运行时验证 MathText 字符串

这是我的工作代码:

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
import wx

mpl.use('Agg') # important

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MainFrame(parent=None, title="Test")
        self.frame.Show()
        return True

class MainFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, None, -1, title=title)
        self.Maximize()
        self.fig = plt.figure()
        self.fig.add_subplot()
        self.canvas = FigureCanvas(self, 0, self.fig)
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        hbox.Add(self.canvas)
        self.txtctrl = wx.TextCtrl(self)
        self.txtctrl.Bind(wx.EVT_TEXT, self.on_text)
        hbox.Add(self.txtctrl)
        self.SetSizer(hbox)
        plt.close()

    def verif_fig_text(self):
        self.Freeze()
        self.canvas.figure = plt.figure()
        ax = self.canvas.figure.add_subplot() # needed to insert x_label
        self.canvas.draw() # needed to get self.canvas.renderer attr
        valid_txt = True
        try:
            txt = ax.set_xlabel(self.txtctrl.GetValue()) 
            # insert x_label is the only mean to verif correct math text
            txt._get_layout(self.canvas.renderer)
            # indeed _get_layout() doesnt work with lot of stuff - found on Valid Mathtext string at runtime StackOverflow
        except:
            valid_txt = False # can't do much here, by adding anything else, the exception occurs outside the try loop
        plt.close()
        self.Thaw()
        return valid_txt
    
    def on_text(self, event):
        if self.verif_fig_text():
            self.fig.suptitle(self.txtctrl.GetValue())
        else:
            self.fig.suptitle('Wrong math text')
        self.canvas.figure = self.fig
        self.canvas.draw()
        plt.close()



if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()

事实上,当有一个 wx.EVT_TEXT 时,我将一个新的(临时的)图形设置到 self.canvas。在此图中,我添加了一个子图,然后我将 xlabel 值设置为 textctrl 值,我使用 _get_layout() 方法检查文本是否是正确的数学文本,如果是,我将此文本设置为我的标题初始图形,我在 self.canvas.draw() 之前将其设置回 self.canvas.figure()

© www.soinside.com 2019 - 2024. All rights reserved.