Как избежать загрязнения трубопровода Майяви? - PullRequest
0 голосов
/ 24 сентября 2018

Ниже приведен минимальный код, который полностью демонстрирует то, что я называю «загрязнением трубопровода».Каждый раз, когда вы нажимаете кнопку «Рисование», редактор MayaviScene (доступ к которому осуществляется через верхнюю левую кнопку на рисунке) обновляет фигуру, а также создает «оболочку» новой сцены, которая задерживается в конвейере (как показано в прикрепленном файле).image).

Я беспокоюсь, что в моем более сложном проекте это нагромождение будет иметь негативные последствия.

Может, кто-нибудь подскажет, как лучше всего настроить эту сцену Mayavi, чтобы она просто обновлялась без чрезмерного накопления?Я прочитал тонны онлайн-материалов, но все еще не понимаю логику разработчика.

Pipeline Pollution

import sys, os
import numpy as np

from pyface.qt import QtGui, QtCore
os.environ['ETS_TOOLKIT'] = 'qt4'

from traits.api import HasTraits,Instance,on_trait_change
from traitsui.api import View,Item
from mayavi import mlab
from mayavi.core.ui.api import MayaviScene, MlabSceneModel, SceneEditor

class Mayavi_Scene(HasTraits):
    scene = Instance(MlabSceneModel, ())

    def update_scene(self):
        Mayavi_Scene.fig1 = mlab.figure(1, bgcolor=(.5,.5,.5))
        self.scene.mlab.clf(figure=Mayavi_Scene.fig1)

        splot = mlab.points3d(P1.x, P1.y, P1.z,
                              scale_factor=0.05, figure=Mayavi_Scene.fig1)

    view = View(Item('scene', editor = SceneEditor(scene_class=MayaviScene),
                    height=300, width=300, show_label=False),
                resizable=True,
                )

class P1(QtGui.QWidget):
    # data starts out empty, wait for user input (below, via 'draw()'):
    x = []
    y = []
    z = []

    def __init__(self, parent=None):
        super(P1, self).__init__(parent)
        layout = QtGui.QGridLayout(self)
        layout.setContentsMargins(20,20,20,20)
        layout.setSpacing(10)

        self.viz1 = Mayavi_Scene()
        self.ui1 = self.viz1.edit_traits(parent=self, kind='subpanel').control
        layout.addWidget(self.ui1, 0, 0, 1, 1)

        def draw(): #a sample user input, could have been a custom data file, etc.
            P1.x = np.random.random((100,))
            P1.y = np.random.random((100,))
            P1.z = np.random.random((100,))
            Mayavi_Scene().update_scene()
            #repeated presses pollute MayaviScene pipeline

        # button to draw data:
        self.btn1 = QtGui.QPushButton('Draw',self)
        self.connect(self.btn1, QtCore.SIGNAL('clicked()'), draw)
        layout.addWidget(self.btn1, 1, 0, 1, 1)
        self.btn1.show()


class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.window = P1(self) 
        self.setCentralWidget(self.window)
        self.show()

if __name__ == '__main__':
    app = QtGui.QApplication.instance()
    w = MainWindow()
    sys.exit(app.exec_())

1 Ответ

0 голосов
/ 09 октября 2018

Возможно, причиной является строка, содержащая Mayavi_Scene().update_scene() во внутренней функции draw.Каждый раз, когда вызывается draw, создается новый Mayavi_Scene.Следующий класс P1 вместо этого определяет draw как метод, который напрямую обращается к self.viz1.Я также заменил ссылку на draw ссылкой на self.draw

class P1(QtGui.QWidget):
    # data starts out empty, wait for user input (below, via 'draw()'):
    x = []
    y = []
    z = []

    def __init__(self, parent=None):
        super(P1, self).__init__(parent)
        layout = QtGui.QGridLayout(self)
        layout.setContentsMargins(20,20,20,20)
        layout.setSpacing(10)

        self.viz1 = Mayavi_Scene()
        self.ui1 = self.viz1.edit_traits(parent=self, kind='subpanel').control
        layout.addWidget(self.ui1, 0, 0, 1, 1)

        # button to draw data:
        self.btn1 = QtGui.QPushButton('Draw',self)
        # Connect the widget's draw method and the button
        self.connect(self.btn1, QtCore.SIGNAL('clicked()'), self.draw)
        layout.addWidget(self.btn1, 1, 0, 1, 1)
        self.btn1.show()

    def draw(self): #a sample user input, could have been a custom data file, etc.
        P1.x = np.random.random((100,))
        P1.y = np.random.random((100,))
        P1.z = np.random.random((100,))
        # Update the current scene without creating a new one.
        self.viz1.update_scene()
...