在PyQt5中使用Mayavi(二):在开发的程序的UI中加入mayavi场景

本文介绍了如何在Qt环境中利用Mayavi创建图形用户界面,包括UI设计、添加Mayavi场景、集成科学绘图功能,并展示了从QtDesigner到Python代码的转换过程。
摘要由CSDN通过智能技术生成

这里Mayavi指Mayavi2

一、UI建立

用qt的designer工具简单建立一个UI,如下图所示。
在这里插入图片描述

对象层级关系为:
在这里插入图片描述

其中,verticalLayout是给mayavi场景预留的位置

保存ui文件,然后用qt的pyuic工具转换为py文件,如下。其中,input.ui是 Qt Designer生成的.ui 文件的路径,output.py是要生成的Python代码文件的路径。-o是一个选项参数,用于指定输出文件的路径。

pyuic5 input.ui -o output.py

转换得到的py文件如下。在通常的开发中,ui需要反复修改,下述py文件会反复生成,所以不要在下述代码中加入任何人工修改内容。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'output.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(12)
        self.groupBox.setFont(font)
        self.groupBox.setObjectName("groupBox")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_3.addLayout(self.verticalLayout)
        self.horizontalLayout.addWidget(self.groupBox)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(12)
        self.pushButton.setFont(font)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        self.horizontalLayout.setStretch(0, 9)
        self.horizontalLayout.setStretch(1, 1)
        self.horizontalLayout_2.addLayout(self.horizontalLayout)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "mayavi_demo"))
        self.groupBox.setTitle(_translate("MainWindow", "mayavi_scene"))
        self.pushButton.setText(_translate("MainWindow", "显示"))

新建立一个py文件来编写逻辑,在下文中称该文件为逻辑文件。在逻辑文件里创建一个继承qt的QMainWindow类的子类,命名为MainWindow,在该子类里实例化我们建立的ui,将其看作MainWindow的一个属性。

from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
from output import Ui_MainWindow

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

运行上述代码可以查看我们刚建立的窗口。
在这里插入图片描述

二、插入mayavi场景

继续修改逻辑文件。先给出完整的需要导入的库。

from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
from output import Ui_MainWindow

from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.core.ui.mayavi_scene import MayaviScene

在逻辑文件里创建一个继承HasTraits类的子类Visualization,

class Visualization(HasTraits):
    scene = Instance(MlabSceneModel, ())
    # the layout of the dialog created
    view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene),
                     height=250, width=300, show_label=False),)

    def __init__(self):
        HasTraits.__init__(self) 

在MainWindow类里建立Visualization的对象,获取mayavi场景,将mayavi场景添加到预留的位置里,修改后的MainWindow类如下。

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.visualization = Visualization()
        self.mayavi_scence = self.visualization.edit_traits().control
        self.ui.verticalLayout.addWidget(self.mayavi_scence)

继续修改MainWindow,建立一个按钮事件来显示科学绘图对象,这里还是来绘制球谐函数的面。修改完的完整MainWindow如下。

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.visualization = Visualization()
        self.mayavi_scence = self.visualization.edit_traits().control
        self.ui.verticalLayout.addWidget(self.mayavi_scence)

        self.ui.pushButton.clicked.connect(self.button_event)

    def button_event(self):
        # Create the data.
        from numpy import pi, sin, cos, mgrid
        dphi, dtheta = pi / 250.0, pi / 250.0
        [phi, theta] = mgrid[0:pi + dphi * 1.5:dphi, 0:2 * pi + dtheta * 1.5:dtheta]
        m0 = 4; m1 = 3; m2 = 2; m3 = 3; m4 = 6; m5 = 2; m6 = 6; m7 = 4;
        r = sin(m0 * phi) ** m1 + cos(m2 * phi) ** m3 + sin(m4 * theta) ** m5 + cos(m6 * theta) ** m7
        x = r * sin(phi) * cos(theta)
        y = r * cos(phi)
        z = r * sin(phi) * sin(theta)

        # View it.
        self.visualization.scene.mlab.mesh(x, y, z)

至此,运行逻辑文件代码。会报一个错误。

在这里插入图片描述
点击报错最后一个文件链接,把下面一行代码的qt4改为qt。

from traitsui.qt4.editor import Editor

再次运行。正常应该再无任何报错了,运行结果如下。
在这里插入图片描述
点击显示按钮来触发按钮事件,结果如下。
在这里插入图片描述

三、逻辑文件完整代码

最后,贴上逻辑文件完整代码。

from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
from output import Ui_MainWindow

from traits.api import HasTraits, Instance
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.core.ui.mayavi_scene import MayaviScene


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.visualization = Visualization()
        self.mayavi_scence = self.visualization.edit_traits().control
        self.ui.verticalLayout.addWidget(self.mayavi_scence)

        self.ui.pushButton.clicked.connect(self.button_event)

    def button_event(self):
        # Create the data.
        from numpy import pi, sin, cos, mgrid
        dphi, dtheta = pi / 250.0, pi / 250.0
        [phi, theta] = mgrid[0:pi + dphi * 1.5:dphi, 0:2 * pi + dtheta * 1.5:dtheta]
        m0 = 4; m1 = 3; m2 = 2; m3 = 3; m4 = 6; m5 = 2; m6 = 6; m7 = 4;
        r = sin(m0 * phi) ** m1 + cos(m2 * phi) ** m3 + sin(m4 * theta) ** m5 + cos(m6 * theta) ** m7
        x = r * sin(phi) * cos(theta)
        y = r * cos(phi)
        z = r * sin(phi) * sin(theta)

        # View it.
        self.visualization.scene.mlab.mesh(x, y, z)


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

    def __init__(self):
        HasTraits.__init__(self)

    # the layout of the dialog created
    view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene),
                     height=250, width=300, show_label=False), )


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

四、最后

一点简单的mayavi应用,如果对你有帮助,就点个赞吧,虽然没啥用,但看到有人点赞还是开心的。

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值