从pyhton 2更改为python 3后使用sip.isdeleted()时出错

2024-09-28 22:25:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试将代码从python 2.7更新到3.7.4。此外,matplotlib后端从qt4更改为qt5。 在代码中,我使用sip.isdeleted()检查matplotlib的画布是否被删除,作为QAction类型的包装的C/C++对象已被删除的解决方法

在Python2.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

触发此错误的代码部分如下所示。原始_系列和系列是特征类,有两个数组数据作为属性

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。这两个操作都没有解决错误。完全省略sip会导致类型为QAction的包装的C/C++对象被删除错误(PyQt: RuntimeError: wrapped C/C++ object has been deleted

到目前为止,我还没有找到任何解决这个问题的办法,我真的非常感谢你的帮助


Tags: infromimportselfobjectmatplotlibinitdef