这篇文章主要介绍了python如何生成excel图表,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。
Source code download: 本文相关源码
建议先看这个,再来呀: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 sys
from PyQt6.QtWidgets import QApplication
from myMainWindow import QmyMainWindow
app=QApplication(sys.argv)#构造GUI应用程序
mainform=QmyMainWindow() #创建主窗体
mainform.show() #显示主窗体
sys.exit(app.exec())
3.新建myChartView文件:
from PyQt6.QtWidgets import QGraphicsView
from PyQt6.QtCore import pyqtSignal, QPoint, Qt, QRectF
from PyQt6.QtCharts import QChartView
class 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
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:#pageup
self.chart().scroll(0, -50)
elif key==Qt.Key.Key_PageDown:#pagedown
self.chart().scroll(0, 50)
elif key ==Qt.Key.Key_Home:#home
self.chart().zoomReset()
super().mouseReleaseEvent(event)
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_MainWindow
class 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设置chart
self.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=0
studTongshuai=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+studWuli
studZhili =qryStudList.value("智力")
item =QStandardItem("%.0f"%studZhili)
item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))
itemList.append(item)
avgScore=avgScore+studZhili
studZhengzhi =qryStudList.value("政治")
item =QStandardItem("%.0f"%studZhengzhi)
item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))
itemList.append(item)
avgScore=avgScore+studZhengzhi
studMeili =qryStudList.value("魅力")
item =QStandardItem("%.0f"%studMeili)#创建item
item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))
itemList.append(item)
avgScore=avgScore+studMeili
item =QStandardItem("%1.f"%(avgScore/5.0))#创建平均分item
item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsEditable))#平均分不允许编辑
itemList.append(item)#添加到列表
self.dataModel.appendRow(itemList)#添加数据模型
if not qryStudList.next():#移动到下一条记录,并判断是否到末尾了
break
for 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到5
cnt50, cnt60, cnt70, cnt80, cnt90=0, 0, 0, 0, 0
for j in range(self.dataModel.rowCount()):#行数表示人数
val=float(self.dataModel.item(j, i).text())#分数
if val<60:
cnt50=cnt50+1
elif (val>=60 and val<70):
cnt60=cnt60+1
elif(val>=70 and val<80):
cnt70=cnt70+1
elif (val>=80 and val<90):
cnt80=cnt80+1
else:
cnt90=cnt90+1
#统计分数
item=self.ui.treeWidget.topLevelItem(0)#第一行,<60
item.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()#QLendMarker
marker.series().setVisible(not marker.series().isVisible())
marker.setVisible(True)
alpha= 1.0#对比度
if not marker.series().isVisible():
alpha= 0.5
brush = marker.labelBrush()#QBrush
color =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()##绘制StackedBar
def on_btnBuildStackedBar_clicked(self):
self.draw_stackedBar()
@pyqtSlot()##绘制水平StackedBar
def 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()##绘制PercentBar
def on_btnBuildPercentBar_clicked(self):
self.draw_percentBar()
@pyqtSlot()##绘制水平PercentBar
def 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] #某个分数段的QBarSet
for j in range(courseCount): #课程是category
barSet.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设置chart
self.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=5
seriesPie.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)##设置holeSize
def on_spinHoleSize_valueChanged(self, arg1):
seriesPie=self.ui.chartViewPie.chart().series()[0]
seriesPie.setHoleSize(arg1)
@pyqtSlot(float)##设置pieSize
def on_spinPieSize_valueChanged(self, arg1):
seriesPie=self.ui.chartViewPie.chart().series()[0]
seriesPie.setPieSize(arg1)
@pyqtSlot(bool)##显示图例checkbox
def 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()#保存原来的label
pieSlice.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())
这里的特别说一下饼图:
向饼图中添加动画效果
chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
添加饼图操作的效果:
@pyqtSlot(int)
def on_comboCourse_currentIndexChanged(self, index):
self.draw_pieChart()
@pyqtSlot(float)##设置holeSize
def on_spinHoleSize_valueChanged(self, arg1):
seriesPie=self.ui.chartViewPie.chart().series()[0]
seriesPie.setHoleSize(arg1)
@pyqtSlot(float)##设置pieSize
def on_spinPieSize_valueChanged(self, arg1):
seriesPie=self.ui.chartViewPie.chart().series()[0]
seriesPie.setPieSize(arg1)
@pyqtSlot(bool)##显示图例checkbox
def 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()#保存原来的label
pieSlice.setLabel(self.__oldLabel+":%.1f%%"
%(pieSlice.percentage()*100))
else:#显示原来的标签
pieSlice.setLabel(self.__oldLabel)
设置图表主题:
![](https://i-blog.csdnimg.cn/blog_migrate/cc4b52d1fb0a5f7e45645fbce21e52a9.png)
设置图表的动画:
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
这样才能在运行窗口中显示图标
这是老师布置的作业,但是感觉学到很多,也分享给大家啦!