将Mayavi嵌入pyqt5时出错

时间:2018-08-22 11:44:27

标签: python pyqt4 pyqt5 mayavi

我有一个mayavi图,我想将其嵌入到pyqt5制成的gui中。奇怪的是,有时它可以正常工作,而我得到的图形用户界面包括剧情,有​​时却不行。然后我得到这个错误:

runfile('C:/Users/xxx/Desktop/gui_mayavi.py', wdir='C:/Users/xxx/Desktop')
Traceback (most recent call last):

  File "<ipython-input-5-9addd1570dd6>", line 1, in <module>
    runfile('C:/Users/xxx/Desktop/gui_mayavi.py', wdir='C:/Users/xxx/Desktop')

  File "C:\Users\xxx\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
    execfile(filename, namespace)

  File "C:\Users\xxx\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/xxx/Desktop/gui_mayavi.py", line 23, in <module>
    from traitsui.api import View, Item

  File "C:\Users\xxx\Anaconda3\lib\site-packages\traitsui\api.py", line 36, in <module>
    from .editors.api import ArrayEditor

  File "C:\Users\xxx\Anaconda3\lib\site-packages\traitsui\editors\__init__.py", line 23, in <module>
    from .api import ArrayEditor

  File "C:\Users\xxx\Anaconda3\lib\site-packages\traitsui\editors\api.py", line 24, in <module>
    from .code_editor import CodeEditor

  File "C:\Users\xxx\Anaconda3\lib\site-packages\traitsui\editors\code_editor.py", line 37, in <module>
    class ToolkitEditorFactory(EditorFactory):

  File "C:\Users\xxx\Anaconda3\lib\site-packages\traitsui\editors\code_editor.py", line 49, in ToolkitEditorFactory
    mark_color = Color(0xECE9D8)

  File "C:\Users\xxx\Anaconda3\lib\site-packages\traits\traits.py", line 522, in __call__
    return self.maker_function( *args, **metadata )

  File "C:\Users\xxx\Anaconda3\lib\site-packages\traits\traits.py", line 1236, in Color
    return ColorTrait( *args, **metadata )

  File "C:\Users\xxx\Anaconda3\lib\site-packages\traitsui\toolkit_traits.py", line 8, in ColorTrait
    return toolkit().color_trait(*args, **traits)

  File "C:\Users\xxx\Anaconda3\lib\site-packages\traitsui\toolkit.py", line 109, in toolkit
    _toolkit = find_toolkit('traitsui.toolkits')

  File "C:\Users\xxx\Anaconda3\lib\site-packages\pyface\base_toolkit.py", line 263, in find_toolkit
    return import_toolkit(ETSConfig.toolkit, entry_point)

  File "C:\Users\xxx\Anaconda3\lib\site-packages\pyface\base_toolkit.py", line 209, in import_toolkit
    raise RuntimeError(msg)

RuntimeError: No traitsui.toolkits plugin found for toolkit qt5

当它起作用时,我关闭Spyder(Python 3.6),然后再次打开它并尝试运行代码,它突然不再起作用了。我试图将pyqt5降级为pyqt4,但这没有帮助。再次重新安装pyqt5后,它突然工作了。但是,当我关闭spyder并再次打开时,它不再起作用。我正在尝试的代码是这样的:

# First, and before importing any Enthought packages, set the ETS_TOOLKIT
# environment variable to qt4, to tell Traits that we will use Qt.
import os
os.environ['ETS_TOOLKIT'] = 'qt5'
# By default, the PySide binding will be used. If you want the PyQt bindings
# to be used, you need to set the QT_API environment variable to 'pyqt'
#os.environ['QT_API'] = 'pyqt'

# To be able to use PySide or PyQt4 and not run in conflicts with traits,
# we need to import QtGui and QtCore from pyface.qt
from pyface.qt import QtGui, QtCore
# Alternatively, you can bypass this line, but you need to make sure that
# the following lines are executed before the import of PyQT:
#   import sip
#   sip.setapi('QString', 2)

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


################################################################################
#The actual visualization
class Visualization(HasTraits):
    scene = Instance(MlabSceneModel, ())

    @on_trait_change('scene.activated')
    def update_plot(self):
        # This function is called when the view is opened. We don't
        # populate the scene when the view is not yet open, as some
        # VTK features require a GLContext.

        # We can do normal mlab calls on the embedded scene.
        self.scene.mlab.test_points3d()

    # the layout of the dialog screated
    view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene),
                     height=250, width=300, show_label=False),
                resizable=True # We need this to resize with the parent widget
                )


################################################################################
# The QWidget containing the visualization, this is pure PyQt4 code.
class MayaviQWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        layout = QtGui.QVBoxLayout(self)
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(0)
        self.visualization = Visualization()

        # If you want to debug, beware that you need to remove the Qt
        # input hook.
        #QtCore.pyqtRemoveInputHook()
        #import pdb ; pdb.set_trace()
        #QtCore.pyqtRestoreInputHook()

        # The edit_traits call will generate the widget to embed.
        self.ui = self.visualization.edit_traits(parent=self,
                                                 kind='subpanel').control
        layout.addWidget(self.ui)
        self.ui.setParent(self)


if __name__ == "__main__":
    # Don't create a new QApplication, it would unhook the Events
    # set by Traits on the existing QApplication. Simply use the
    # '.instance()' method to retrieve the existing one.
    app = QtGui.QApplication.instance()
    container = QtGui.QWidget()
    container.setWindowTitle("Embedding Mayavi in a PyQt4 Application")
    # define a "complex" layout to test the behaviour
    layout = QtGui.QGridLayout(container)

    # put some stuff around mayavi
    label_list = []
    for i in range(3):
        for j in range(3):
            if (i==1) and (j==1):continue
            label = QtGui.QLabel(container)
            label.setText("Your QWidget at (%d, %d)" % (i,j))
            label.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
            layout.addWidget(label, i, j)
            label_list.append(label)
    mayavi_widget = MayaviQWidget(container)

    layout.addWidget(mayavi_widget, 1, 1)
    container.show()
    window = QtGui.QMainWindow()
    window.setCentralWidget(container)
    window.show()

    # Start the main event loop.
    app.exec_()

0 个答案:

没有答案