PyQt中图表的建立与显示(完整过程演示)
建议先看这个,再来呀:http://t.csdn.cn/Oatgb
里面包含的知识点这里不重复讲了
在PyQt中建立了如图窗口:

对于窗口的ui文件,我放在百度网盘中:
链接:https://pan.baidu.com/s/1nXqx0xbKHVkbyrtr6gBvyw
提取码:cyss
还有对应的图标文件:
链接:https://pan.baidu.com/s/1LHvmRr9QFIlwCiRWhP3cUw
提取码:cyss
1.创建下图所示的数据表:
2.新建appMain文件,用于显示主窗体:
import sysfrom PyQt6.QtWidgets import QApplication
from myMainWindow import QmyMainWindowapp=QApplication(sys.argv)#构造GUI应用程序
mainform=QmyMainWindow() #创建主窗体
mainform.show() #显示主窗体sys.exit(app.exec())
3.新建myChartView文件:
QChart 和 QChartView 是基于 Graphics View 结构的绘图类。要对一个 QChart 图表进行鼠标和按键操作,需要在 QChartView 类里对鼠标和按键事件进行处理,这就需要自定义一个从QChartView 继承的类。 QmyChartView 类是从 QChartView 类继承的用作图表的视图组件,实现了鼠标、按键事件的处理,能够在鼠标移动时发射信号 mouseMove(),鼠标框选中一个矩形区域时放大显示此区域,通过按键进行图表缩放和移动操作。from PyQt6.QtWidgets import QGraphicsView
from PyQt6.QtCore import pyqtSignal, QPoint, Qt, QRectF
from PyQt6.QtCharts import QChartViewclass QmyChartView(QChartView):mouseMove=pyqtSignal(QPoint)##鼠标移动def __init__(self, parent=None):super().__init__(parent)self.setDragMode(QGraphicsView.DragMode.RubberBandDrag)self.__beginPoint=QPoint()self.__endPoint=QPoint()def mousePressEvent(self, event):##鼠标单击if event.button()==Qt.MouseButton.LeftButton:self.__beginPoint=event.pos()super().mousePressEvent(event)def mouseMoveEvent(self, event):##鼠标移动point=event.pos()self.mouseMove.emit(point)super().mouseMoveEvent(event)def mouseReleaseEvent(self, event):##鼠标框选放大,右键恢复if event.button()==Qt.MouseButton.LeftButton:self.__endPoint=event.pos()rectF=QRectF()rectF.setTopLeft(self.__beginPoint.toPointF())rectF.setBottomRight(self.__endPoint.toPointF())self.chart().zoomIn(rectF)elif event.button()==Qt.MouseButton.RightButton:self.chart().zoomReset()#鼠标右键释放,resetZoon (1)mousePressEvent:在鼠标左键或右键按下时触发的事件函数。self.__beginPoint 记录左键按下时,鼠标在视图组件中的位置。 (2)mouseMoveEvent: 鼠标在图表上移动时触发的事件函数,通过 event.pos()获取鼠标在视图组件中的坐标 point,然后发射信号 mouseMove(point)。在使用 QmyChartView 类组件的主窗口里,可以定义槽函数与此信号关联,通过传递的参数将视图坐标变换为图表的坐 标,从而实现鼠标光标处的坐标数值实时显示。
(3)mouseReleaseEvent:在鼠标左键或右键释放时触发的事件函数。若是鼠标左键释放,则用 self.__endPoint 记录鼠标位置坐标。self.__beginPoint 和 self.__endPoint 就定义了鼠标框选的矩形区域,用关联的 QChart 组件的 zoomIn(QRectF)函数对这个矩形区域进行放大。注意这里rectF的类型是QRectF,所以需要用toPointF将__beginPoint和__endPoint从QPoint类型转换为 QPointF 类型。 def keyPressEvent(self, event):key=event.key()if key ==Qt.Key.Key_Plus:# +self.chart().zoom(1.2)elif key ==Qt.Key.Key_Minus:# -self.chart().zoom(0.8)elif key==Qt.Key.Key_Left: #向左self.chart().scroll(10, 0)elif key ==Qt.Key.Key_Right:#向右self.chart().scroll(-10, 0)elif key==Qt.Key.Key_Up:#向上self.chart().scroll(0, -10)elif key==Qt.Key.Key_Down:#向下self.chart(0, 10)elif key==Qt.Key.Key_PageUp:#pageupself.chart().scroll(0, -50)elif key==Qt.Key.Key_PageDown:#pagedownself.chart().scroll(0, 50)elif key ==Qt.Key.Key_Home:#homeself.chart().zoomReset()super().mouseReleaseEvent(event) keyPressEvent 是键盘按键按下时触发的事件函数,从 event.key()可以获得按下按键的名称,判断按键然后做出缩放、移动等动作。 4.myMainWindow文件: import sys
from PyQt6.QtWidgets import QApplication,QMainWindow, QMessageBox
from PyQt6.QtCore import pyqtSlot, Qt
from PyQt6.QtSql import QSqlDatabase, QSqlQuery
from PyQt6.QtGui import QStandardItemModel, QStandardItem, QPen, QPainter
from PyQt6.QtCharts import (QChart, QBarSet, QBarSeries, QHorizontalBarSeries, QBarCategoryAxis, QValueAxis, QLineSeries, QAbstractBarSeries, QStackedBarSeries, QHorizontalStackedBarSeries, QPercentBarSeries, QHorizontalPercentBarSeries, QPieSeries)
from Ui_MainWindow import Ui_MainWindowclass QmyMainWindow(QMainWindow):def __init__(self, parent=None):super().__init__(parent)#调用父类构造函数,创建窗体self.ui=Ui_MainWindow()#创建UI对象self.ui.setupUi(self)#构造UI界面self.setWindowTitle("三国志")self.ui.tableView.setAlternatingRowColors(True)self.ui.treeWidget.setAlternatingRowColors(True)self.setStyleSheet("QTreeWidget,QTableView{""alternate-background-color:rgb(170,241,190)}")self.dataModel=QStandardItemModel(self)#数据模型self.ui.tableView.setModel(self.dataModel)#设置数据模型self.__openDB()#打开数据库self.__generateData()#初始化数据self.__surveyData()#数据统计self.__iniBarChart()#柱状图初始化self.__iniStackedBar()#堆叠状图初始化self.__iniPercentBar()#百分比柱状图初始化self.__iniPieChart()#饼图初始化##=====page 1.柱状图=========@pyqtSlot()def __iniBarChart(self):chart =QChart()chart.setTitle("Barchart 演示")chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)self.ui.chartViewBar.setChart(chart)#为ChartView设置chartself.ui.chartViewBar.setRenderHint(QPainter.RenderHint.Antialiasing)#反走样self.ui.chartViewBar.setCursor(Qt.CursorShape.CrossCursor)#设置鼠标指针为十字星##绘制柱状图,或水平柱状图def draw_barChart(self, isVertical=True):chart = self.ui.chartViewBar.chart()chart.removeAllSeries() #删除所有序列for axis in chart.axes():chart.removeAxis(axis) #删除坐标轴if isVertical:chart.setTitle("Barchart 演示")chart.legend().setAlignment(Qt.AlignmentFlag.AlignBottom)else:chart.setTitle("Horizontal Barchart 演示")chart.legend().setAlignment(Qt.AlignmentFlag.AlignRight)setTongshuai = QBarSet("统帅")setWuli = QBarSet("武力")setZhili=QBarSet("智力")setZhengzhi=QBarSet("政治")setMeili = QBarSet("魅力")seriesLine = QLineSeries()seriesLine.setName("平均分")pen=QPen(Qt.GlobalColor.red)pen.setWidth(2)seriesLine.setPen(pen)seriesLine.setPointLabelsVisible(True)if isVertical:seriesLine.setPointLabelsFormat("@yPoint")else:seriesLine.setPointLabelsFormat("@xPoint")font=seriesLine.pointLabelsFont()font.setPointSize(10)font.setBold(True)seriesLine.setPointLabelsFont(font)stud_Count=self.dataModel.rowCount()nameList=[]#学生姓名列表,用于QBarCategoryAxis类坐标轴for i in range(stud_Count): #从数据模型中获取数据item=self.dataModel.item(i, 0)#第0列姓名nameList.append(item.text())#姓名,用作坐标轴标签item=self.dataModel.item(i, 1)#第一列统帅setTongshuai.append(float(item.text()))item=self.dataModel.item(i, 2)#第二列武力setWuli.append(float(item.text()))item=self.dataModel.item(i, 3)#第三列智力setZhili.append(float(item.text()))item=self.dataModel.item(i, 4)#第四列政治setZhengzhi.append(float(item.text()))item=self.dataModel.item(i, 5)#第五列魅力setMeili.append(float(item.text()))item=self.dataModel.item(i, 6)if isVertical:seriesLine.append(i, float(item.text()))#平均分,用于柱状图else:seriesLine.append(float(item.text()), i)#平均分,用于水平柱状图#创建一个序列QBarSeries,并添加数据集if isVertical:seriesBar =QBarSeries()#柱状图else:seriesBar=QHorizontalBarSeries()#水平柱状图seriesBar.append(setTongshuai)#添加数据集seriesBar.append(setWuli)seriesBar.append(setZhili)seriesBar.append(setZhengzhi)seriesBar.append(setMeili)#数据点标签可见seriesBar.setLabelsVisible(True)#数据点标签可见seriesBar.setLabelsFormat("@value")#显示数值标签seriesBar.setLabelsPosition(QAbstractBarSeries.LabelsPosition.LabelsCenter)#数据标签显示位置seriesBar.hovered.connect(self.do_barSeries_Hovered)#hovered信号seriesBar.clicked.connect(self.do_barSeries_Clicked)#clicked信号chart.addSeries(seriesBar)#添加柱状图序列chart.addSeries(seriesLine)#添加折线图序列##学生姓名坐标轴axisStud=QBarCategoryAxis()axisStud.append(nameList)#添加横坐标文字列表axisStud.setRange(nameList[0], nameList[stud_Count-1])#坐标轴范围#数值型坐标轴axisValue=QValueAxis()axisValue.setRange(0, 100)axisValue.setTitleText("分数")axisValue.setTickCount(6) #刻度线数量axisValue.applyNiceNumbers() #让刻度线更好看if isVertical:chart.addAxis(axisStud, Qt.AlignmentFlag.AlignBottom)seriesBar.attachAxis(axisStud)seriesLine.attachAxis(axisStud)chart.addAxis(axisValue, Qt.AlignmentFlag.AlignLeft)seriesBar.attachAxis(axisValue)seriesLine.attachAxis(axisValue)else:chart.addAxis(axisStud, Qt.AlignmentFlag.AlignLeft)seriesBar.attachAxis(axisStud)seriesLine.attachAxis(axisStud)chart.addAxis(axisValue, Qt.AlignmentFlag.AlignBottom)seriesBar.attachAxis(axisValue)seriesLine.attachAxis(axisValue)for marker in chart.legend().markers():#QLegendMarker类型列表marker.clicked.connect(self.do_LegendMarkerClicked)@pyqtSlot()def on_btnBuildBarChart_clicked(self):self.draw_barChart()@pyqtSlot() ##绘制水平柱状图def on_btnBuildBarChartH_clicked(self):self.draw_barChart(False)#与seriesBar.hovered.connect(self.do_barSeries_Hovered)关联def do_barSeries_Hovered(self, status, index, barset):hint = "hovered barset="+barset.label()if status:hint=hint+",index=%d,value=%.2f"%(index, barset.at(index))else:hint=""self.ui.statusbar.showMessage(hint)def do_barSeries_Clicked(self, index, barset):hint="clicked barSet="+barset.label()hint=hint+",count=%d,sum=%.2f"%(barset.count(), barset.sum())self.ui.statusbar.showMessage(hint)@pyqtSlot()def __openDB(self):self.DB=QSqlDatabase.addDatabase("QODBC")self.DB.setHostName("localhost")self.DB.setDatabaseName("pyqt")self.DB.setUserName("pyqt")self.DB.setPassword("pyqt123456")if not self.DB.open():QMessageBox.warning(self, "错误", "打开数据库失败")@pyqtSlot()def __generateData(self):self.dataModel.clear()headerList=["姓名", "统帅", "武力", "智力", "政治", "魅力", "平均分"]self.dataModel.setHorizontalHeaderLabels(headerList)#设置头文字qryStudList = QSqlQuery(self.DB)#学生信息列表qryStudList.exec("select 姓名,统帅,武力,智力,政治,魅力 from sanguozhi")qryStudList.first()while(qryStudList.isValid()):itemList=[]studName=qryStudList.value("姓名")item=QStandardItem(studName)item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)itemList.append(item)avgScore=0studTongshuai=qryStudList.value("统帅")item =QStandardItem("%.0f"%studTongshuai)item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))itemList.append(item)avgScore=avgScore+studTongshuai #其实这里只是求和,用于计算平均值studWuli =qryStudList.value("武力")item =QStandardItem("%.0f"%studWuli)item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))itemList.append(item)avgScore=avgScore+studWulistudZhili =qryStudList.value("智力")item =QStandardItem("%.0f"%studZhili)item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))itemList.append(item)avgScore=avgScore+studZhilistudZhengzhi =qryStudList.value("政治")item =QStandardItem("%.0f"%studZhengzhi)item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))itemList.append(item)avgScore=avgScore+studZhengzhistudMeili =qryStudList.value("魅力")item =QStandardItem("%.0f"%studMeili)#创建itemitem.setTextAlignment(Qt.AlignmentFlag.AlignCenter)item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))itemList.append(item)avgScore=avgScore+studMeiliitem =QStandardItem("%1.f"%(avgScore/5.0))#创建平均分itemitem.setTextAlignment(Qt.AlignmentFlag.AlignCenter)item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))#平均分不允许编辑itemList.append(item)#添加到列表self.dataModel.appendRow(itemList)#添加数据模型if not qryStudList.next():#移动到下一条记录,并判断是否到末尾了breakfor i in range(0, 6):self.ui.tableView.setColumnWidth(i, 50)self.ui.tableView.setColumnWidth(6, 80)#个性化的列设置@pyqtSlot()def __surveyData(self):for i in range(1, 6):#0姓名 1统帅 2武力 3智力 4政治 5魅力,range(1,6)即1到5cnt50, cnt60, cnt70, cnt80, cnt90=0, 0, 0, 0, 0for j in range(self.dataModel.rowCount()):#行数表示人数val=float(self.dataModel.item(j, i).text())#分数if val<60:cnt50=cnt50+1elif (val>=60 and val<70):cnt60=cnt60+1elif(val>=70 and val<80):cnt70=cnt70+1elif (val>=80 and val<90):cnt80=cnt80+1else:cnt90=cnt90+1#统计分数item=self.ui.treeWidget.topLevelItem(0)#第一行,<60item.setText(i,str(cnt50))#第i列item.setTextAlignment(i, Qt.AlignmentFlag.AlignCenter)item=self.ui.treeWidget.topLevelItem(1)#第二行,[60~70]item.setText(i,str(cnt60))#第i列item.setTextAlignment(i, Qt.AlignmentFlag.AlignCenter)item=self.ui.treeWidget.topLevelItem(2)#第三行,[70~80]item.setText(i,str(cnt70))#第i列item.setTextAlignment(i, Qt.AlignmentFlag.AlignCenter)item=self.ui.treeWidget.topLevelItem(3)#第四行,[80~90]item.setText(i,str(cnt80))#第i列item.setTextAlignment(i, Qt.AlignmentFlag.AlignCenter)item=self.ui.treeWidget.topLevelItem(4)#第五行,[90~100]item.setText(i,str(cnt90))#第i列item.setTextAlignment(i, Qt.AlignmentFlag.AlignCenter)self.ui.treeWidget.setColumnWidth(0, 80)#个性化列宽设置for i in range(1, 6):self.ui.treeWidget.setColumnWidth(i, 50)@pyqtSlot()def do_LegendMarkerClicked(self):marker = self.sender()#QLendMarkermarker.series().setVisible(not marker.series().isVisible())marker.setVisible(True)alpha= 1.0#对比度if not marker.series().isVisible():alpha= 0.5brush = marker.labelBrush()#QBrushcolor =brush.color()color.setAlphaF(alpha)brush.setColor(color)marker.setLabelBrush(brush)brush=marker.brush()color = brush.color()color.setAlphaF(alpha)brush.setColor(color)marker.setBrush(brush)pen=marker.pen()color=pen.color()color.setAlphaF(alpha)pen.setColor(color)marker.setPen(pen)##======page 2.StackedBar==========@pyqtSlot()##初始化堆叠柱状图def __iniStackedBar(self):chart = QChart()chart.setTitle("StackedBar 演示")self.ui.chartViewStackedBar.setChart(chart)self.ui.chartViewStackedBar.setRenderHint(QPainter.RenderHint.Antialiasing)#反走样self.ui.chartViewStackedBar.setCursor(Qt.CursorShape.CrossCursor)#设置鼠标指针为十字星@pyqtSlot()##绘制StackedBardef on_btnBuildStackedBar_clicked(self):self.draw_stackedBar()@pyqtSlot()##绘制水平StackedBardef on_btnBuildStackedBarH_clicked(self):self.draw_stackedBar(False)def draw_stackedBar(self,isVertical=True):chart=self.ui.chartViewStackedBar.chart()chart.removeAllSeries() #删除所有序列for axis in chart.axes():chart.removeAxis(axis)#删除坐标轴if isVertical:chart.setTitle("Stackedchart 演示")chart.legend().setAlignment(Qt.AlignmentFlag.AlignBottom)#图标放于底部else:chart.setTitle("Horizontal Stackedchart 演示")chart.legend().setAlignment(Qt.AlignmentFlag.AlignRight)#图标放于右侧setTongshuai = QBarSet("统帅")setWuli = QBarSet("武力")setZhili=QBarSet("智力")setZhengzhi=QBarSet("政治")setMeili = QBarSet("魅力")stud_Count=self.dataModel.rowCount()nameList=[]#学生姓名列表,用于QBarCategoryAxis类坐标轴for i in range(stud_Count): #从数据模型中获取数据item=self.dataModel.item(i, 0)#第0列姓名nameList.append(item.text())#姓名,用作坐标轴标签item=self.dataModel.item(i, 1)#第一列统帅setTongshuai.append(float(item.text()))item=self.dataModel.item(i, 2)#第二列武力setWuli.append(float(item.text()))item=self.dataModel.item(i, 3)#第三列智力setZhili.append(float(item.text()))item=self.dataModel.item(i, 4)#第四列政治setZhengzhi.append(float(item.text()))item=self.dataModel.item(i, 5)#第五列魅力setMeili.append(float(item.text()))##创建序列if isVertical:seriesBar =QStackedBarSeries()else:seriesBar=QHorizontalStackedBarSeries()#水平柱状图seriesBar.append(setTongshuai)#添加数据集seriesBar.append(setWuli)seriesBar.append(setZhili)seriesBar.append(setZhengzhi)seriesBar.append(setMeili)#数据点标签可见seriesBar.setLabelsVisible(True)#数据点标签可见seriesBar.setLabelsFormat("@value")#显示数值标签seriesBar.setLabelsPosition(QAbstractBarSeries.LabelsPosition.LabelsCenter)#数据标签显示位置seriesBar.hovered.connect(self.do_barSeries_Hovered)#hovered信号seriesBar.clicked.connect(self.do_barSeries_Clicked)#clicked信号chart.addSeries(seriesBar)#添加柱状图序列axisStud=QBarCategoryAxis()axisStud.append(nameList)#添加横坐标文字列表axisStud.setRange(nameList[0], nameList[stud_Count-1])#坐标轴范围#数值型坐标轴axisValue=QValueAxis()axisValue.setRange(0, 500)axisValue.setTitleText("总分")axisValue.setTickCount(6) #刻度线数量axisValue.applyNiceNumbers() #让刻度线更好看if isVertical:chart.addAxis(axisStud, Qt.AlignmentFlag.AlignBottom)seriesBar.attachAxis(axisStud)#添加轴chart.addAxis(axisValue, Qt.AlignmentFlag.AlignLeft)seriesBar.attachAxis(axisValue)else:chart.addAxis(axisStud, Qt.AlignmentFlag.AlignLeft)seriesBar.attachAxis(axisStud)chart.addAxis(axisValue, Qt.AlignmentFlag.AlignBottom)seriesBar.attachAxis(axisValue)for marker in chart.legend().markers():#QLegendMarker类型列表marker.clicked.connect(self.do_LegendMarkerClicked)##===========page3.百分比柱状图=================@pyqtSlot()##初始化百分比柱状图def __iniPercentBar(self):chart=QChart()chart.setTitle("PercentBar 演示")self.ui.chartViewPercentBar.setChart(chart)self.ui.chartViewPercentBar.setRenderHint(QPainter.RenderHint.Antialiasing)#反走样self.ui.chartViewPercentBar.setCursor(Qt.CursorShape.CrossCursor)#设置鼠标指针为十字星@pyqtSlot()##绘制PercentBardef on_btnBuildPercentBar_clicked(self):self.draw_percentBar()@pyqtSlot()##绘制水平PercentBardef on_btnBuildPercentBarH_clicked(self):self.draw_percentBar(False)def draw_percentBar(self, isVertical=True):chart=self.ui.chartViewPercentBar.chart()chart.removeAllSeries()for axis in chart.axes():chart.removeAxis(axis)#删除坐标轴chart.legend().setAlignment(Qt.AlignmentFlag.AlignRight)if isVertical:chart.setTitle("PercentBar 演示")else:chart.setTitle("Horizontal PercentBar 演示")scoreBarSets=[] #QBarSet对象列表sectionCount=5 #5个分数段,分数段是数据集for i in range(sectionCount):item=self.ui.treeWidget.topLevelItem(i)barSet=QBarSet(item.text(0)) #一个分数段scoreBarSets.append(barSet) #QBarSet对象列表categories=["统帅", "武力", "智力", "政治", "魅力"]courseCount=5 #5门课程for i in range(sectionCount): #5个分数段item=self.ui.treeWidget.topLevelItem(i) #treeWidget第i行barSet=scoreBarSets[i] #某个分数段的QBarSetfor j in range(courseCount): #课程是categorybarSet.append(float(item.text(j+1)))if isVertical:seriesBar=QPercentBarSeries()#序列else:seriesBar=QHorizontalPercentBarSeries()#序列seriesBar.append(scoreBarSets)#添加一个QBarset对象列表seriesBar.setLabelsVisible(True)#显示百分比seriesBar.hovered.connect(self.do_barSeries_Hovered)#hovered信号seriesBar.clicked.connect(self.do_barSeries_Clicked)#clicked信号chart.addSeries(seriesBar)axisSection= QBarCategoryAxis()#分类坐标axisSection.append(categories)axisSection.setTitleText("分数段")axisSection.setRange(categories[0], categories[courseCount-1])axisValue= QValueAxis()#数值坐标axisValue.setRange(0, 100)axisValue.setTitleText("累积百分比")axisValue.setTickCount(6)axisValue.setLabelFormat("%.0f%")#标签格式axisValue.applyNiceNumbers()if isVertical:chart.addAxis(axisSection, Qt.AlignmentFlag.AlignBottom)seriesBar.attachAxis(axisSection)chart.addAxis(axisValue, Qt.AlignmentFlag.AlignLeft)seriesBar.attachAxis(axisValue)else:chart.addAxis(axisSection, Qt.AlignmentFlag.AlignLeft)seriesBar.attachAxis(axisSection)chart.addAxis(axisValue, Qt.AlignmentFlag.AlignBottom)seriesBar.attachAxis(axisValue)for marker in chart.legend().markers():#QLegendMarker类型列表marker.clicked.connect(self.do_LegendMarkerClicked)##===============page 4.饼图============== @pyqtSlot()##初始化饼图def __iniPieChart(self):chart=QChart()chart.setTitle("Piechart 演示")self.ui.chartViewPie.setChart(chart)#为ChartView设置chartself.ui.chartViewPie.setRenderHint(QPainter.RenderHint.Antialiasing)#反走样self.ui.chartViewPie.setCursor(Qt.CursorShape.CrossCursor)#设置鼠标指针为十字星@pyqtSlot()#绘制饼图def on_btnDrawPieChart_clicked(self):self.draw_pieChart()@pyqtSlot()def draw_pieChart(self):chart=self.ui.chartViewPie.chart()#获取chart对象chart.legend().setAlignment(Qt.AlignmentFlag.AlignRight)chart.removeAllSeries()colNo=1+self.ui.comboCourse.currentIndex()seriesPie = QPieSeries()seriesPie.setHoleSize(self.ui.spinHoleSize.value())sec_count=5seriesPie.setLabelsVisible(True)for i in range(sec_count):item=self.ui.treeWidget.topLevelItem(i)sliceLabel=item.text(0)+"(%s人)"%item.text(colNo)sliceValue=int(item.text(colNo))seriesPie.append(sliceLabel, sliceValue)seriesPie.setLabelsVisible(True)#只影响当前的slices,必须添加玩slice之后再设置seriesPie.hovered.connect(self.do_pieHovered)#鼠标落在某个分块上时,次分块弹出chart.addSeries(seriesPie)chart.setTitle("Piechart---"+self.ui.comboCourse.currentText())@pyqtSlot(int)def on_comboCourse_currentIndexChanged(self, index):self.draw_pieChart()@pyqtSlot(float)##设置holeSizedef on_spinHoleSize_valueChanged(self, arg1):seriesPie=self.ui.chartViewPie.chart().series()[0]seriesPie.setHoleSize(arg1)@pyqtSlot(float)##设置pieSizedef on_spinPieSize_valueChanged(self, arg1):seriesPie=self.ui.chartViewPie.chart().series()[0]seriesPie.setPieSize(arg1)@pyqtSlot(bool)##显示图例checkboxdef on_chkBoxPieLegend_clicked(self, checked):self.ui.chartViewPie.chart().legend().setVisible(checked)def do_pieHovered(self, pieSlice, state):pieSlice.setExploded(state)#弹回或缩回,具有动态效果if state:#显示带百分数的标签self.__oldLabel=pieSlice.label()#保存原来的labelpieSlice.setLabel(self.__oldLabel+":%.1f%%"%(pieSlice.percentage()*100))else:#显示原来的标签pieSlice.setLabel(self.__oldLabel)##================工具栏按钮============@pyqtSlot()##重新生成数据def on_toolBtn_GenData_clicked(self):self.__generateData()self.__surveyData()@pyqtSlot()##重新统计def on_toolBtn_Counting_clicked(self):self.__surveyData()@pyqtSlot()##获取当前Qchart对象def __getCurrentChart(self):page=self.ui.tabWidget.currentIndex()if page ==0:chart=self.ui.chartViewBar.chart()elif page==1:chart=self.ui.chartViewStackedBar.chart()elif page==2:chart=self.ui.chartViewPercentBar.chart()else:chart=self.ui.chartViewPie.chart()return chart@pyqtSlot(int)def on_comboTheme_currentIndexChanged(self, index):chart=self.__getCurrentChart()chart.setTheme(QChart.ChartTheme(index))@pyqtSlot(int)##图表动画def on_comboAnimation_currentIndexChanged(self, index):chart=self.__getCurrentChart()chart.setAnimationOptions(QChart.AnimationOption(index))if __name__=="__main__":#用于当前窗体测试app=QApplication(sys.argv)#创建GUI应用程序form=QmyMainWindow()#创建窗体form.show()sys.exit(app.exec()) 这里的特别说一下饼图:
饼图是根据窗口左下角的 treeWidget 里面的数据绘制的。饼图只能表示一种能力的各个 分数段的人数和百分比,所以在饼图界面需要选择相关能力。HoleSize 用于设置饼图中心空 心圆的相对大小,数值在 0 到 1 之间。PieSize 用于设置饼图与图表视图的相对大小,数值 在 0 到 1 之间。
向饼图中添加动画效果
chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations) 
添加饼图操作的效果:
@pyqtSlot(int)def on_comboCourse_currentIndexChanged(self, index):self.draw_pieChart()@pyqtSlot(float)##设置holeSizedef on_spinHoleSize_valueChanged(self, arg1):seriesPie=self.ui.chartViewPie.chart().series()[0]seriesPie.setHoleSize(arg1)@pyqtSlot(float)##设置pieSizedef on_spinPieSize_valueChanged(self, arg1):seriesPie=self.ui.chartViewPie.chart().series()[0]seriesPie.setPieSize(arg1)@pyqtSlot(bool)##显示图例checkboxdef on_chkBoxPieLegend_clicked(self, checked):self.ui.chartViewPie.chart().legend().setVisible(checked) holesize的效果:

piesize的效果:

checkbox的效果:

hover用于悬浮饼图:
def do_pieHovered(self, pieSlice, state):pieSlice.setExploded(state)#弹回或缩回,具有动态效果if state:#显示带百分数的标签self.__oldLabel=pieSlice.label()#保存原来的labelpieSlice.setLabel(self.__oldLabel+":%.1f%%"%(pieSlice.percentage()*100))else:#显示原来的标签pieSlice.setLabel(self.__oldLabel) 
设置图表主题:

设置图表的动画:

0:NoAnimation;1:GridAxisAnimations;2:SeriesAnimations;3:AllAnimations
对照一下官网对 AnimationOption 的定义:

效果呈现:
(1)主题:默认light主题

改为Qt主题:


选择 SeriesAnimation,看柱状图,发现有动画效果。坐标轴不动,棒柱从下往上,逐渐长高

选择 AllAnimations,发现坐标轴和棒柱同时发生变化。坐标轴从左上角的原点出发,拉伸到右下角。棒柱从下往上长高。

注:
要在Ui_MainWindow中需加入import res_rc
同时将res_rc.py中的
from PySide6 import QtCore
改为:from PyQt6 import QtCore
这样才能在运行窗口中显示图标
这是老师布置的作业,但是感觉学到很多,也分享给大家啦!
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
