赞
踩
表面图是数据可视化的另一种常见显示形式,本文演示如何使用交互方式控制三维表面图显示。
一、示例程序的基本功能
本文演示如何使用Q3Dsurface来创建一个简单的3D表面图,并使用一些控件来交互调节,以使3D达到合适的质量效果。这个实例程序演示了一下一些功能:
二、示例程序分析
演示程序包括两部分,我们将曲面的交互功能部分封装在类DemoWidget中, 首先调用QWidget::createWindowContainer()创建窗口容器。然后创建水平和垂直布局管理,将图形和垂直布局添加到一个水平布局中,垂直布局中用于添加交互部件。水平布局设置为DemoWidget的布局。
创建另一个类SurfaceGraph来处理数据添加以及与图形的其他交互。
现在简要分析SurfaceGraph类的功能:
设置代理(Proxy)和数据
首先,我们创建一个QSurfaceDataProxy实例,并将其附加到一个新创建的QSurface3DSeries上:
- self.sqrtSinProxy = QSurfaceDataProxy()
- self.sqrtSinSeries = QSurface3DSeries(self.sqrtSinProxy)
然后我们用简单的平方根和正弦波数据填充代理。这是通过创建一个新实例并向其中添加元素。
- def fillSqrtSinProxy(self):
- stepX = (sampleMax - sampleMin) / float(sampleCountX - 1)
- stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1)
-
- dataArray = []
- index = 0
- for i in range(sampleCountZ):
- z = min(sampleMax, i * stepZ + sampleMin)
- x_arr = []
- for j in range(sampleCountX):
- x = min(sampleMax, j * stepX + sampleMin)
- R = math.sqrt(z * z + x * x) + 0.01
- y = (math.sin(R) / R + 0.24) * 1.61
- x_arr.append(QSurfaceDataItem(QVector3D(x, y, z)))
- dataArray.append(x_arr)
-
- self.sqrtSinProxy.resetArray(dataArray)
高度映射是通过实例化一个QHeightMapSurfaceDataProxy和一个包含高度数据的QImage来创建的。QHeightMapSurfaceDataProxy::setValueRanges()方法用于定义映射的值范围。在我们的例子中,地图的假想位置为34.0°N - 40.0°N和18.0°E - 24.0°E。这些值用于显示和定位地图到轴线。
- heightMapImage = QImage(':/maps/mountain')
- self.heightMapProxy = QHeightMapSurfaceDataProxy(heightMapImage)
- self.heightMapSeries = QSurface3DSeries(self.heightMapProxy)
- self.heightMapSeries.setItemLabelFormat('(@xLabel, @zLabel): @yLabel')
- self.heightMapProxy.setValueRanges(34.0, 40.0, 18.0, 24.0)
为了演示不同的Proxy,这个示例有两个单选按钮,用户可以使用它们在Serial之间切换。当用户选择”Sqrt & Sin”单选按钮时,所选Serial将使用以下代码激活。
- self.sqrtSinSeries.setDrawMode(QSurface3DSeries.DrawSurfaceAndWireframe)
- self.sqrtSinSeries.setFlatShadingEnabled(True)
-
- self.graph.axisX().setLabelFormat('%.2f')
- self.graph.axisZ().setLabelFormat('%.2f')
- self.graph.axisX().setRange(sampleMin, sampleMax)
- self.graph.axisY().setRange(0.0, 2.0)
- self.graph.axisZ().setRange(sampleMin, sampleMax)
- self.graph.axisX().setLabelAutoRotation(30)
- self.graph.axisY().setLabelAutoRotation(90)
- self.graph.axisZ().setLabelAutoRotation(30)
-
- self.graph.removeSeries(self.heightMapSeries)
- self.graph.addSeries(self.sqrtSinSeries)
当用户选择”高度地图”单选按钮时,所选Serial将使用以下代码激活。
- self.heightMapSeries.setDrawMode(QSurface3DSeries.DrawSurface)
- self.heightMapSeries.setFlatShadingEnabled(False)
-
- self.graph.axisX().setLabelFormat('%.1f N')
- self.graph.axisZ().setLabelFormat('%.1f E')
- self.graph.axisX().setRange(34.0, 40.0)
- self.graph.axisY().setAutoAdjustRange(True)
- self.graph.axisZ().setRange(18.0, 24.0)
-
- self.graph.axisX().setTitle('纬度')
- self.graph.axisY().setTitle('高度')
- self.graph.axisZ().setTitle('经度')
-
- self.graph.removeSeries(self.sqrtSinSeries)
- self.graph.addSeries(self.heightMapSeries)
选择模式
Q3Dsurface支持三种不同的选择模式。示例中使用单选按钮演示了这些功能,用户可以使用单选按钮激活合适的选择模式。
- def toggleModeNone(self):
- self.graph.setSelectionMode(QAbstract3DGraph.SelectionNone)
-
- def toggleModeItem(self):
- self.graph.setSelectionMode(QAbstract3DGraph.SelectionItem)
-
- def toggleModeSliceRow(self):
- self.graph.setSelectionMode(QAbstract3DGraph.SelectionItemAndRow | QAbstract3DGraph.SelectionSlice)
- def toggleModeSliceColumn(self):
- self.graph.setSelectionMode(QAbstract3DGraph.SelectionItemAndColumn | QAbstract3DGraph.SelectionSlice)
图形的坐标轴范围
示例有四个滑块控件,用于调整X和Z轴的最小值和最大值。
- #为Sqrt&Sin 重新设置滑动条范围
- self.rangeMinX = sampleMin
- self.rangeMinZ = sampleMin
- self.stepX = (sampleMax - sampleMin) / float(sampleCountX - 1)
- self.stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1)
- self.axisMinSliderX.setMaximum(sampleCountX - 2)
- self.axisMinSliderX.setValue(0)
- self.axisMaxSliderX.setMaximum(sampleCountX - 1)
- self.axisMaxSliderX.setValue(sampleCountX - 1)
- self.axisMinSliderZ.setMaximum(sampleCountZ - 2)
- self.axisMinSliderZ.setValue(0)
- self.axisMaxSliderZ.setMaximum(sampleCountZ - 1)
- self.axisMaxSliderZ.setValue(sampleCountZ - 1)
主题
Q3DSurface支持所有Qt数据可视化的主题。本示例有一个用于选择主题的下拉菜单。下面的方法连接到菜单以激活所选主题。将主题类型更改为另一个预定义主题,该主题将所有主题属性覆盖为预定义值
- def changeTheme(self, theme):
- self.graph.activeTheme().setType(theme)
自定义表面渐变
示例程序演示了使用两个按钮的自定义表面渐变。渐变可以用QLinearGradient定义,其中所需的颜色被设置为位置。下面的代码展示了如何创建示例渐变并将其设置为系列。注意,还需要将颜色样式更改为Q3DTheme::ColorStyleRangeGradient来实际使用渐变。
- gr = QLinearGradient()
- gr.setColorAt(0.0, Qt.black)
- gr.setColorAt(0.33, Qt.blue)
- gr.setColorAt(0.67, Qt.red)
- gr.setColorAt(1.0, Qt.yellow)
-
- self.graph.seriesList()[0].setBaseGradient(gr)
- self.graph.seriesList()[0].setColorStyle(Q3DTheme.ColorStyleRangeGradient)
surfacegraph.py完整代码:
- import math
- from PyQt5.QtCore import Qt, QObject
- from PyQt5.QtGui import QVector3D, QImage, QLinearGradient
- from PyQt5.QtDataVisualization import (Q3DSurface, QSurface3DSeries, QSurfaceDataProxy, QSurfaceDataItem,
- QAbstract3DSeries, QValue3DAxis, QAbstract3DGraph, Q3DCamera,
- Q3DTheme, QHeightMapSurfaceDataProxy)
-
- sampleCountX = 50
- sampleCountZ = 50
- heightMapGridStepX = 6
- heightMapGridStepZ = 6
- sampleMin = -8.0
- sampleMax = 8.0
-
- class SurfaceGraph(QObject):
- def __init__(self, surface):
- super(SurfaceGraph, self).__init__()
-
- self.graph = surface
-
- self.graph.setAxisX(QValue3DAxis())
- self.graph.setAxisY(QValue3DAxis())
- self.graph.setAxisZ(QValue3DAxis())
-
- self.sqrtSinProxy = QSurfaceDataProxy()
- self.sqrtSinSeries = QSurface3DSeries(self.sqrtSinProxy)
- self.fillSqrtSinProxy()
-
- heightMapImage = QImage(':/maps/mountain')
- self.heightMapProxy = QHeightMapSurfaceDataProxy(heightMapImage)
- self.heightMapSeries = QSurface3DSeries(self.heightMapProxy)
- self.heightMapSeries.setItemLabelFormat('(@xLabel, @zLabel): @yLabel')
- self.heightMapProxy.setValueRanges(34.0, 40.0, 18.0, 24.0)
-
- self.heightMapWidth = heightMapImage.width()
- self.heightMapHeight = heightMapImage.height()
-
- def toggleModeNone(self):
- self.graph.setSelectionMode(QAbstract3DGraph.SelectionNone)
-
- def toggleModeItem(self):
- self.graph.setSelectionMode(QAbstract3DGraph.SelectionItem)
-
- def toggleModeSliceRow(self):
- self.graph.setSelectionMode(QAbstract3DGraph.SelectionItemAndRow | QAbstract3DGraph.SelectionSlice)
-
- def toggleModeSliceColumn(self):
- self.graph.setSelectionMode(QAbstract3DGraph.SelectionItemAndColumn | QAbstract3DGraph.SelectionSlice)
-
- def setAxisMinSliderX(self, slider):
- self.axisMinSliderX = slider
-
- def setAxisMaxSliderX(self, slider):
- self.axisMaxSliderX = slider
-
- def setAxisMinSliderZ(self, slider):
- self.axisMinSliderZ = slider
-
- def setAxisMaxSliderZ(self, slider):
- self.axisMaxSliderZ = slider
-
- def fillSqrtSinProxy(self):
- stepX = (sampleMax - sampleMin) / float(sampleCountX - 1)
- stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1)
-
- dataArray = []
- index = 0
- for i in range(sampleCountZ):
- z = min(sampleMax, i * stepZ + sampleMin)
- x_arr = []
- for j in range(sampleCountX):
- x = min(sampleMax, j * stepX + sampleMin)
- R = math.sqrt(z * z + x * x) + 0.01
- y = (math.sin(R) / R + 0.24) * 1.61
- x_arr.append(QSurfaceDataItem(QVector3D(x, y, z)))
- dataArray.append(x_arr)
-
- self.sqrtSinProxy.resetArray(dataArray)
-
- def enableSqrtSinModel(self, enable):
- if not enable:
- return
-
- self.sqrtSinSeries.setDrawMode(QSurface3DSeries.DrawSurfaceAndWireframe)
- self.sqrtSinSeries.setFlatShadingEnabled(True)
-
- self.graph.axisX().setLabelFormat('%.2f')
- self.graph.axisZ().setLabelFormat('%.2f')
- self.graph.axisX().setRange(sampleMin, sampleMax)
- self.graph.axisY().setRange(0.0, 2.0)
- self.graph.axisZ().setRange(sampleMin, sampleMax)
- self.graph.axisX().setLabelAutoRotation(30)
- self.graph.axisY().setLabelAutoRotation(90)
- self.graph.axisZ().setLabelAutoRotation(30)
-
- self.graph.removeSeries(self.heightMapSeries)
- self.graph.addSeries(self.sqrtSinSeries)
-
- #为Sqrt&Sin 重新设置滑动条范围
- self.rangeMinX = sampleMin
- self.rangeMinZ = sampleMin
- self.stepX = (sampleMax - sampleMin) / float(sampleCountX - 1)
- self.stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1)
- self.axisMinSliderX.setMaximum(sampleCountX - 2)
- self.axisMinSliderX.setValue(0)
- self.axisMaxSliderX.setMaximum(sampleCountX - 1)
- self.axisMaxSliderX.setValue(sampleCountX - 1)
- self.axisMinSliderZ.setMaximum(sampleCountZ - 2)
- self.axisMinSliderZ.setValue(0)
- self.axisMaxSliderZ.setMaximum(sampleCountZ - 1)
- self.axisMaxSliderZ.setValue(sampleCountZ - 1)
-
- def enableHeightMapModel(self, enable):
- if not enable:
- return
-
- self.heightMapSeries.setDrawMode(QSurface3DSeries.DrawSurface)
- self.heightMapSeries.setFlatShadingEnabled(False)
-
- self.graph.axisX().setLabelFormat('%.1f N')
- self.graph.axisZ().setLabelFormat('%.1f E')
- self.graph.axisX().setRange(34.0, 40.0)
- self.graph.axisY().setAutoAdjustRange(True)
- self.graph.axisZ().setRange(18.0, 24.0)
-
- self.graph.axisX().setTitle('纬度')
- self.graph.axisY().setTitle('高度')
- self.graph.axisZ().setTitle('经度')
-
- self.graph.removeSeries(self.sqrtSinSeries)
- self.graph.addSeries(self.heightMapSeries)
-
- #重新设置滚动条的范围
- mapGridCountX = self.heightMapWidth / heightMapGridStepX
- mapGridCountZ = self.heightMapHeight / heightMapGridStepZ
- self.rangeMinX = 34.0
- self.rangeMinZ = 18.0
- self.stepX = 6.0 / float(mapGridCountX - 1)
- self.stepZ = 6.0 / float(mapGridCountZ - 1)
- self.axisMinSliderX.setMaximum(mapGridCountX - 2)
- self.axisMinSliderX.setValue(0)
- self.axisMaxSliderX.setMaximum(mapGridCountX - 1)
- self.axisMaxSliderX.setValue(mapGridCountX - 1)
- self.axisMinSliderZ.setMaximum(mapGridCountZ - 2)
- self.axisMinSliderZ.setValue(0)
- self.axisMaxSliderZ.setMaximum(mapGridCountZ - 1)
- self.axisMaxSliderZ.setValue(mapGridCountZ - 1)
-
- def adjustXMin(self, minVal):
- minX = self.stepX * minVal + self.rangeMinX
-
- maxVal = self.axisMaxSliderX.value()
- if minVal >= maxVal:
- maxVal = minVal + 1
- self.axisMaxSliderX.setValue(maxVal)
- maxX = self.stepX * maxVal + self.rangeMinX
-
- self.setAxisXRange(minX, maxX)
-
- def adjustXMax(self, maxVal):
- maxX = self.stepX * maxVal + self.rangeMinX
-
- minVal = self.axisMinSliderX.value()
- if maxVal <= minVal:
- minVal = maxVal - 1
- self.axisMinSliderX.setValue(minVal)
- minX = self.stepX * minVal + self.rangeMinX
-
- self.setAxisXRange(minX, maxX)
-
- def adjustZMin(self, minVal):
- minZ = self.stepZ * minVal + self.rangeMinZ
-
- maxVal = self.axisMaxSliderZ.value()
- if minVal >= maxVal:
- maxVal = minVal + 1
- self.axisMaxSliderZ.setValue(maxVal)
- maxZ = self.stepZ * maxVal + self.rangeMinZ
-
- self.setAxisZRange(minZ, maxZ)
-
- def adjustZMax(self, maxVal):
- maxZ = self.stepZ * maxVal + self.rangeMinZ
-
- minVal = self.axisMinSliderZ.value()
- if maxVal <= minVal:
- minVal = maxVal - 1
- self.axisMinSliderZ.setValue(minVal)
- minZ = self.stepZ * minVal + self.rangeMinZ
-
- self.setAxisZRange(minZ, maxZ)
-
- def setAxisXRange(self, minVal, maxVal):
- self.graph.axisX().setRange(minVal, maxVal)
-
- def setAxisZRange(self, minVal, maxVal):
- self.graph.axisZ().setRange(minVal, maxVal)
-
- def changeTheme(self, theme):
- self.graph.activeTheme().setType(theme)
-
- def setBlackToYellowGradient(self):
- gr = QLinearGradient()
- gr.setColorAt(0.0, Qt.black)
- gr.setColorAt(0.33, Qt.blue)
- gr.setColorAt(0.67, Qt.red)
- gr.setColorAt(1.0, Qt.yellow)
-
- self.graph.seriesList()[0].setBaseGradient(gr)
- self.graph.seriesList()[0].setColorStyle(Q3DTheme.ColorStyleRangeGradient)
-
- def setGreenToRedGradient(self):
- gr = QLinearGradient()
- gr.setColorAt(0.0, Qt.darkGreen)
- gr.setColorAt(0.5, Qt.yellow)
- gr.setColorAt(0.8, Qt.red)
- gr.setColorAt(1.0, Qt.darkRed)
-
- self.graph.seriesList()[0].setBaseGradient(gr)
- self.graph.seriesList()[0].setColorStyle(Q3DTheme.ColorStyleRangeGradient)
surfacedemo.py 完整代码:
- import sys
- from PyQt5 import QtCore, QtGui, QtWidgets
- from PyQt5.QtCore import Qt, QSize
- from PyQt5.QtGui import QLinearGradient, QPixmap, QPainter, QBrush, QIcon
- from PyQt5.QtWidgets import (QApplication, QWidget, QMessageBox, QSizePolicy,
- QHBoxLayout, QVBoxLayout, QComboBox, QPushButton,
- QCheckBox, QSlider, QGroupBox, QLabel, QRadioButton)
- from PyQt5.QtDataVisualization import (Q3DSurface, QAbstract3DSeries, QAbstract3DGraph)
-
- from surfacegraph import SurfaceGraph
- import surface_rc
- class DemoWidget(QWidget):
- def __init__(self, parent=None):
- super(DemoWidget, self).__init__(parent)
-
- # 设置窗口标题
- self.setWindowTitle('实战 Qt for Python: 三维表面图演示')
- # 设置窗口大小
- self.resize(640, 480)
-
- self.initUi()
-
- def initUi(self):
-
- widgetgraph = Q3DSurface()
- container = QWidget.createWindowContainer(widgetgraph)
- if not widgetgraph.hasContext():
- msgBox = QMessageBox()
- msgBox.setText('不能初始化OpenGL上下文')
- msgBox.exec()
- return;
- screenSize = widgetgraph.screen().size()
- container.setMinimumSize(QSize(int(screenSize.width() / 2.0), int(screenSize.height() / 1.5)))
- container.setMaximumSize(screenSize)
- container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- container.setFocusPolicy(Qt.StrongFocus)
- hLayout = QHBoxLayout()
- vLayout = QVBoxLayout()
- hLayout.addWidget(container, 1) #左边绘图部分
- hLayout.addLayout(vLayout) #右边控制部分
- vLayout.setAlignment(Qt.AlignTop)
- modelGroupBox = QGroupBox('模型')
- sqrtSinModelRB = QRadioButton(self)
- sqrtSinModelRB.setText('Sqrt && Sin')
- sqrtSinModelRB.setChecked(False)
- heightMapModelRB = QRadioButton(self)
- heightMapModelRB.setText('高度地图')
- heightMapModelRB.setChecked(False)
- modelVBox = QVBoxLayout()
- modelVBox.addWidget(sqrtSinModelRB)
- modelVBox.addWidget(heightMapModelRB)
- modelGroupBox.setLayout(modelVBox)
- selectionGroupBox = QGroupBox('选择模式')
- modeNoneRB = QRadioButton(self)
- modeNoneRB.setText('无选择')
- modeNoneRB.setChecked(False)
- modeItemRB = QRadioButton(self)
- modeItemRB.setText('条目')
- modeItemRB.setChecked(False)
- modeSliceRowRB = QRadioButton(self)
- modeSliceRowRB.setText('Row Slice')
- modeSliceRowRB.setChecked(False)
- modeSliceColumnRB = QRadioButton(self)
- modeSliceColumnRB.setText('Column Slice')
- modeSliceColumnRB.setChecked(False)
- selectionVBox = QVBoxLayout()
- selectionVBox.addWidget(modeNoneRB)
- selectionVBox.addWidget(modeItemRB)
- selectionVBox.addWidget(modeSliceRowRB)
- selectionVBox.addWidget(modeSliceColumnRB)
- selectionGroupBox.setLayout(selectionVBox)
- axisMinSliderX = QSlider(Qt.Horizontal, self)
- axisMinSliderX.setMinimum(0)
- axisMinSliderX.setTickInterval(1)
- axisMinSliderX.setEnabled(True)
- axisMaxSliderX = QSlider(Qt.Horizontal, self)
- axisMaxSliderX.setMinimum(1)
- axisMaxSliderX.setTickInterval(1)
- axisMaxSliderX.setEnabled(True)
- axisMinSliderZ = QSlider(Qt.Horizontal, self)
- axisMinSliderZ.setMinimum(0)
- axisMinSliderZ.setTickInterval(1)
- axisMinSliderZ.setEnabled(True)
- axisMaxSliderZ = QSlider(Qt.Horizontal, self)
- axisMaxSliderZ.setMinimum(1)
- axisMaxSliderZ.setTickInterval(1)
- axisMaxSliderZ.setEnabled(True)
- #图表主题控制
- themeList = QComboBox(self)
- themeList.addItem('Qt')
- themeList.addItem('Primary Colors')
- themeList.addItem('Digia')
- themeList.addItem('Stone Moss')
- themeList.addItem('Army Blue')
- themeList.addItem('Retro')
- themeList.addItem('Ebony')
- themeList.addItem('Isabelle')
- themeList.setCurrentIndex(6)
- colorGroupBox = QGroupBox('自定义梯度')
- grBtoY = QLinearGradient(0, 0, 1, 100)
- grBtoY.setColorAt(1.0, Qt.black)
- grBtoY.setColorAt(0.67, Qt.blue)
- grBtoY.setColorAt(0.33, Qt.red)
- grBtoY.setColorAt(0.0, Qt.yellow)
- pm = QPixmap(24, 100)
- pmp = QPainter(pm)
- pmp.setBrush(QBrush(grBtoY))
- pmp.setPen(Qt.NoPen)
- pmp.drawRect(0, 0, 24, 100)
- gradientBtoYPB = QPushButton(self)
- gradientBtoYPB.setIcon(QIcon(pm))
- gradientBtoYPB.setIconSize(QSize(24, 100))
- grGtoR = QLinearGradient(0, 0, 1, 100)
- grGtoR.setColorAt(1.0, Qt.darkGreen)
- grGtoR.setColorAt(0.67, Qt.yellow)
- grGtoR.setColorAt(0.33, Qt.red)
- grGtoR.setColorAt(0.0, Qt.darkRed)
- pmp.setBrush(QBrush(grGtoR))
- pmp.setPen(Qt.NoPen)
- pmp.drawRect(0, 0, 24, 100)
- gradientGtoRPB = QPushButton(self)
- gradientGtoRPB.setIcon(QIcon(pm))
- gradientGtoRPB.setIconSize(QSize(24, 100))
- #必须控制先后释放顺序
- del pmp
- del pm
- colorHBox = QHBoxLayout()
- colorHBox.addWidget(gradientBtoYPB)
- colorHBox.addWidget(gradientGtoRPB)
- colorGroupBox.setLayout(colorHBox)
-
- vLayout.addWidget(modelGroupBox)
- vLayout.addWidget(selectionGroupBox)
- vLayout.addWidget(QLabel('列范围'))
- vLayout.addWidget(axisMinSliderX)
- vLayout.addWidget(axisMaxSliderX)
- vLayout.addWidget(QLabel('行范围'))
- vLayout.addWidget(axisMinSliderZ)
- vLayout.addWidget(axisMaxSliderZ)
- vLayout.addWidget(QLabel('主题'))
- vLayout.addWidget(themeList)
- vLayout.addWidget(colorGroupBox)
- self.modifier = SurfaceGraph(widgetgraph)
- heightMapModelRB.toggled.connect(self.modifier.enableHeightMapModel)
- sqrtSinModelRB.toggled.connect(self.modifier.enableSqrtSinModel)
- modeNoneRB.toggled.connect(self.modifier.toggleModeNone)
- modeItemRB.toggled.connect(self.modifier.toggleModeItem)
- modeSliceRowRB.toggled.connect(self.modifier.toggleModeSliceRow)
- modeSliceColumnRB.toggled.connect(self.modifier.toggleModeSliceColumn)
-
- axisMinSliderX.valueChanged.connect(self.modifier.adjustXMin)
- axisMaxSliderX.valueChanged.connect(self.modifier.adjustXMax)
- axisMinSliderZ.valueChanged.connect(self.modifier.adjustZMin)
- axisMaxSliderZ.valueChanged.connect(self.modifier.adjustZMax)
- themeList.currentIndexChanged.connect(self.modifier.changeTheme)
- gradientBtoYPB.pressed.connect(self.modifier.setBlackToYellowGradient)
- gradientGtoRPB.pressed.connect(self.modifier.setGreenToRedGradient)
- self.modifier.setAxisMinSliderX(axisMinSliderX)
- self.modifier.setAxisMaxSliderX(axisMaxSliderX)
- self.modifier.setAxisMinSliderZ(axisMinSliderZ)
- self.modifier.setAxisMaxSliderZ(axisMaxSliderZ)
- sqrtSinModelRB.setChecked(True)
- modeItemRB.setChecked(True)
- themeList.setCurrentIndex(2)
- self.setLayout(hLayout)
-
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- window = DemoWidget()
- window.show()
- sys.exit(app.exec())
运行结果如下图。
3D表面图映射效果
3D表面图交互演示
三、本文知识点
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。