Я пытался обновить свой код с python 2.7 до 3.7.4. Кроме того, серверная часть matplotlib изменилась с qt4 на qt5. В коде я проверяю с помощью sip.isdeleted () , удален ли холст matplotlib или нет в качестве обходного пути для обернутого объекта C / C ++ типа QAction был удален ошибка.
В python 2.7 и с использованием qt4 это сработало.
После обновления кода выдается ошибка в sip.isdeleted () :
Exception occurred in traits notification handler for object: <lasers.profiles.AnsysSag object at 0x000001BA34014828>, trait: raw_series, old value: None, new value: <lasers.series.Series object at 0x000001BA30789D68>
Traceback (most recent call last):
File "C:\Users\pujoel\AppData\Local\Continuum\anaconda3\lib\site-packages\traits\trait_notifiers.py", line 591, in _dispatch_change_event
self.dispatch(handler, *args)
File "C:\Users\pujoel\AppData\Local\Continuum\anaconda3\lib\site-packages\traits\trait_notifiers.py", line 553, in dispatch
handler(*args)
File "C:\Users\pujoel\Documents\LaserS\src\python\lasers\profiles.py", line 151, in plot
if canvas is not None and not sip.isdeleted(canvas):
TypeError: isdeleted() argument 1 must be sip.simplewrapper, not FigureCanvasBase
Раздел кода, где эта ошибка вызывается, показан ниже. Raw_series и series являются классами признаков с двумя массивами data и base в качестве свойств.
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import sip
class Profile(ABCHasTraits):
raw_series = Instance(HasTraits)
series = Property()
_figure = Instance(Figure)
figure = Property(depends_on='_figure')
def __init__(self, parent=None):
ABCHasTraits.__init__(self)
self._init_figure()
def _init_figure(self):
self._figure = Figure()
ax = self.figure.add_subplot(111)
ax.grid(which='both')
def plot(self):
series = self.series
if series:
axes = self.figure.axes
for ax in axes:
ax.clear()
ax.grid(which='both')
axes[0].plot(series.base, series.data)
canvas = self.figure.canvas
#if viewer is not the active tab in the tree, the QT object is deleted, leaving an empty wrapper. Calling draw() then gives an error
if canvas is not None and not sip.isdeleted(canvas):
canvas.draw()
def traits_view(self):
return View(Item('name'),
Group(
UItem('figure', editor=MPLFigureEditor()),
show_border=True, visible_when='detrend_data==False'),
resizable=True,
width=.5,
id='lasers.profiles')
Редактор фигур matplotlib, используемый в представлении, определяется следующим образом:
matplotlib.use('Qt5Agg')
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT
from matplotlib.figure import Figure
from traits.api import Instance
from traitsui.qt4.editor import Editor
from traitsui.qt4.basic_editor_factory import BasicEditorFactory
class _MPLFigureEditor(Editor):
scrollable = True
def init(self, parent):
self.control = self._create_canvas(parent)
self.set_tooltip()
def update_editor(self):
pass
def _create_canvas(self, parent):
""" Create the MPL canvas. """
# matplotlib commands to create a canvas
frame = QtGui.QWidget()
mpl_canvas = FigureCanvas(self.value)
mpl_toolbar = NavigationToolbar2QT(mpl_canvas, frame)
vbox = QtGui.QVBoxLayout()
vbox.addWidget(mpl_toolbar)
vbox.addWidget(mpl_canvas)
frame.setLayout(vbox)
class MPLFigureEditor(BasicEditorFactory):
klass = _MPLFigureEditor
До сих пор я пытался обновить sip до PyQt5.sip, а также пропустить sip completeley. Оба действия не решили ошибку. Полное отсутствие sip приводит к удалению обернутого объекта C / C ++ типа QAction * ошибка 1025 * ( PyQt: RuntimeError: обернутый объект C / C ++ был удален ).
Пока что я не нашел решения этой проблемы и буду очень признателен за вашу помощь.