一、QCharts概述
Qt图表提供了:折线图、样条曲线图、面积图、散点图、条形图、饼图、方块胡须图、蜡烛图、极坐标图。
1、QChart介绍
Qt Charts基于Qt的QGraphics View架构,其核心组件是QChartView和QChart
- QChartView是显示图标的视图,基类为QGraphicsView
- QChart的基类是QGraphicsItem
QGraphicsItem
QGraphicsObject
QGraphicsWidget
QChart
2、使用
(1)项目管理
在使用Qt Charts模块,必须在项目中配置
QT += charts
(2)类中使用QCharts
在类中使用QCharts,需要在头文件或者源文件分别添加:
// using namespace QtCharts;
QT_CHARTS_USE_NAMESPACE // 使用宏代替
3、实现程序
(1)创建项目,基于QMainWindow
(2)实现图表
QT_CHARTS_USE_NAMESPACE
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 创建图标
QChartView *chartView = new QChartView(this);
QChart *chart = new QChart();
chart->setTitle("简单函数曲线");
chartView->setChart(chart);
setCentralWidget(chartView);
// 创建曲线序列
QLineSeries *series0 = new QLineSeries;
QLineSeries *series1 = new QLineSeries;
series0->setName("Sin曲线");
series1->setName("Cos曲线");
chart->addSeries(series0);
chart->addSeries(series1);
qreal y0, y1, t = 0, intv = 0.1/*时间间隔*/;
int cnt = 100;
for (int i = 0; i < cnt; ++i)
{
y0 = qSin(t);
series0->append(t, y0);
y1 = qCos(t);
series1->append(t, y1);
t += intv;
}
//创建坐标轴
QValueAxis *axisX = new QValueAxis;
axisX->setRange(0, 10);
chart->setAxisX(axisX, series0);
chart->setAxisX(axisX, series1);
QValueAxis *axisY = new QValueAxis;
axisY->setRange(-1, 1);
chart->setAxisY(axisY, series0);
chart->setAxisY(axisY, series1);
}
MainWindow::~MainWindow()
{
delete ui;
}
二、QChart绘制折线图
1、类继承关系
(1)数据序列类
QAbractSeries
QAreaSeries
QBoxPlotSeries
QAbstractBarSeries
QBarSeries
QHorizontalBarSeries
QHorizontalStackedBarSeries
QPercentBarSeries
QStackedBarSeries
QPieSeries
QXYSeties
QLineSeries
QSplineSeries
QScatterSeries
(2)坐标轴类
QAbstractAxis
QValuesAxis
QCategoryAxis
QLogValueAxis
QBarCategoryAxis
QDataTimeAxis
2、实现程序
(1)创建项目, 基于QMainwindow
(2)QScrollArea 滚动条
(3)添加组件
(4)添设置画笔的UI和类
DialogPen::DialogPen(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogPen)
{
ui->setupUi(this);
ui->comboBoxLineType->clear();
ui->comboBoxLineType->addItem("NoPen", 0);
ui->comboBoxLineType->addItem("SolidLine", 1);
ui->comboBoxLineType->addItem("DashLine", 2);
ui->comboBoxLineType->addItem("DotLine", 3);
ui->comboBoxLineType->addItem("DashDotLine", 4);
ui->comboBoxLineType->addItem("DashDotDotLine", 5);
ui->comboBoxLineType->addItem("CustomDashLine", 6);
ui->comboBoxLineType->setCurrentIndex(1);
}
DialogPen::~DialogPen()
{
delete ui;
}
QPen DialogPen::getPen()
{
m_pen.setStyle(Qt::PenStyle(ui->comboBoxLineType->currentIndex()));
m_pen.setWidth(ui->spinBoxLineWidth->value());
QColor color = ui->btnLineColor->palette().color(QPalette::Button);
m_pen.setColor(color);
return m_pen;
}
QPen DialogPen::getPen(QPen initPen, bool &ok)
{
QPen pen;
DialogPen *dlg = new DialogPen;
dlg->setPen(initPen);
int ret = dlg->exec();
if(ret == QDialog::Accepted)
{
pen = dlg->getPen();
ok = true;
}
else
{
pen = initPen;
ok = false;
}
delete dlg;
return pen;
}
void DialogPen::setPen(const QPen &pen)
{
m_pen = pen;
ui->spinBoxLineWidth->setValue(pen.width());
int nType = static_cast<int>(pen.style());
ui->comboBoxLineType->setCurrentIndex(nType);
ui->btnLineColor->setAutoFillBackground(true);
QColor color = pen.color();
QString str = QString::asprintf("background-color: rgb(%d,%d,%d)",
color.red(), color.green(), color.blue());
ui->btnLineColor->setStyleSheet(str);
}
void DialogPen::on_btnLineColor_clicked()
{
QColor color = m_pen.color();
color = QColorDialog::getColor(color);
if(color.isValid())
{
QString str = QString::asprintf("background-color: rgb(%d,%d,%d)",
color.red(), color.green(), color.blue());
ui->btnLineColor->setStyleSheet(str);
}
}
(5)初始化图表
void MainWindow::createChart()
{
QChart*chart = new QChart();
chart->setTitle("简单的曲线");
ui->chartView->setChart(chart);
ui->chartView->setRenderHint(QPainter::Antialiasing); // 抗锯齿
QLineSeries *series0 = new QLineSeries;
QLineSeries *series1 = new QLineSeries;
series0->setName("Sin曲线");
series1->setName("Cos曲线");
curSeries = series0;
QPen pen;
pen.setStyle(Qt::DotLine);
pen.setWidth(2);
pen.setColor(Qt::red);
series0->setPen(pen);
pen.setStyle(Qt::SolidLine);
pen.setColor(Qt::blue);
series1->setPen(pen);
chart->addSeries(series0);
chart->addSeries(series1);
QValueAxis *axisX = new QValueAxis;
QValueAxis *axisY = new QValueAxis;
curAxis = axisX;
axisX->setRange(0, 10);
axisX->setLabelFormat("%0.1f");
axisX->setTickCount(11); // 大格间隔数
axisX->setMinorTickCount(4); // 小格间隔数
axisX->setTitleText("time(secs)");
axisY->setRange(-1.2, 1.2);
axisY->setTickCount(3); // 大格间隔数
axisY->setMinorTickCount(4); // 小格间隔数
axisY->setTitleText("value");
chart->setAxisX(axisX, series0);
chart->setAxisX(axisX, series1);
chart->setAxisY(axisY, series0);
chart->setAxisY(axisY, series1);
}```
```bash
void MainWindow::prepareData()
{
QLineSeries *series0 = (QLineSeries*)ui->chartView->chart()->series().at(0);
QLineSeries *series1 = (QLineSeries*)ui->chartView->chart()->series().at(1);
int cnt = 100;
series0->clear();
series1->clear();
qsrand(QTime::currentTime().second());
qreal t = 0, y0 = 0, y1 = 0, intv = 0.1;
qreal rd;
for (int i = 0; i < cnt; ++i)
{
rd = (qrand() % 10 - 5);
y0 = qSin(t) + rd / 50;
series0->append(t, y0);
y1 = qCos(t) + rd / 50;
series1->append(t, y1);
t += intv;
}
}
(6)实现组件功能
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
createChart();
prepareData();
updateFromChart();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::createChart()
{
QChart*chart = new QChart();
chart->setTitle("简单的曲线");
ui->chartView->setChart(chart);
ui->chartView->setRenderHint(QPainter::Antialiasing); // 抗锯齿
QLineSeries *series0 = new QLineSeries;
QLineSeries *series1 = new QLineSeries;
series0->setName("Sin曲线");
series1->setName("Cos曲线");
curSeries = series0;
QPen pen;
pen.setStyle(Qt::DotLine);
pen.setWidth(2);
pen.setColor(Qt::red);
series0->setPen(pen);
pen.setStyle(Qt::SolidLine);
pen.setColor(Qt::blue);
series1->setPen(pen);
chart->addSeries(series0);
chart->addSeries(series1);
QValueAxis *axisX = new QValueAxis;
QValueAxis *axisY = new QValueAxis;
curAxis = axisX;
axisX->setRange(0, 10);
axisX->setLabelFormat("%0.1f");
axisX->setTickCount(11); // 大格间隔数
axisX->setMinorTickCount(4); // 小格间隔数
axisX->setTitleText("time(secs)");
axisY->setRange(-1.2, 1.2);
axisY->setTickCount(3); // 大格间隔数
axisY->setMinorTickCount(4); // 小格间隔数
axisY->setTitleText("value");
chart->setAxisX(axisX, series0);
chart->setAxisX(axisX, series1);
chart->setAxisY(axisY, series0);
chart->setAxisY(axisY, series1);
}
void MainWindow::prepareData()
{
QLineSeries *series0 = (QLineSeries*)ui->chartView->chart()->series().at(0);
QLineSeries *series1 = (QLineSeries*)ui->chartView->chart()->series().at(1);
int cnt = 100;
series0->clear();
series1->clear();
qsrand(QTime::currentTime().second());
qreal t = 0, y0 = 0, y1 = 0, intv = 0.1;
qreal rd;
for (int i = 0; i < cnt; ++i)
{
rd = (qrand() % 10 - 5);
y0 = qSin(t) + rd / 50;
series0->append(t, y0);
y1 = qCos(t) + rd / 50;
series1->append(t, y1);
t += intv;
}
}
void MainWindow::updateFromChart()
{
QChart *chart = ui->chartView->chart();
ui->lineEditTitle->setText(chart->title());
QMargins mg = chart->margins();
ui->spinBoxUp->setValue(mg.top());
ui->spinBoxDown->setValue(mg.bottom());
ui->spinBoxLeft->setValue(mg.left());
ui->spinBoxRight->setValue(mg.right());
}
void MainWindow::on_actZoomIn_triggered()
{
ui->chartView->chart()->zoom(1.2);
}
void MainWindow::on_actZoomOut_triggered()
{
ui->chartView->chart()->zoom(0.8);
}
void MainWindow::on_actDraw_triggered()
{
prepareData();
}
void MainWindow::on_actZoomReset_triggered()
{
ui->chartView->chart()->zoomReset();
}
void MainWindow::on_btnLinePen_clicked()
{
QPen pen = curSeries->pen();
bool ok = false;
pen = DialogPen::getPen(pen, ok);
if(ok)
{
curSeries->setPen(pen);
}
}
void MainWindow::on_btnSetTitle_clicked()
{
QString strTitle = ui->lineEditTitle->text();
QChart *chart = ui->chartView->chart();
chart->setTitle(strTitle);
}
void MainWindow::on_btnSetTitleFont_clicked()
{
QFont font = ui->chartView->chart()->titleFont();
bool ok;
font = QFontDialog::getFont(&ok, font);
if(ok)
{
ui->chartView->chart()->setTitleFont(font);
}
}
void MainWindow::on_rbtnUp_clicked()
{
ui->chartView->chart()->legend()->setAlignment(Qt::AlignTop);
}
void MainWindow::on_rbtnDown_clicked()
{
ui->chartView->chart()->legend()->setAlignment(Qt::AlignBottom);
}
void MainWindow::on_rbtnLeft_clicked()
{
ui->chartView->chart()->legend()->setAlignment(Qt::AlignLeft);
}
void MainWindow::on_rbtnRight_clicked()
{
ui->chartView->chart()->legend()->setAlignment(Qt::AlignRight);
}
void MainWindow::on_checkBoxName_clicked(bool checked)
{
ui->chartView->chart()->legend()->setVisible(checked);
}
void MainWindow::on_checkBoxBack_clicked(bool checked)
{
ui->chartView->chart()->legend()->setBackgroundVisible(checked);
}
void MainWindow::on_btnNameFont_clicked()
{
QFont font = ui->chartView->chart()->legend()->font();
bool ok;
font = QFontDialog::getFont(&ok, font);
if(ok)
{
ui->chartView->chart()->legend()->setFont(font);
}
}
void MainWindow::on_btnNameColor_clicked()
{
QColor color = ui->chartView->chart()->legend()->labelColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
ui->chartView->chart()->legend()->setLabelColor( color);
}
}
void MainWindow::on_btnSetMargin_clicked()
{
QMargins mg;
mg.setTop(ui->spinBoxUp->value());
mg.setBottom(ui->spinBoxDown->value());
mg.setLeft(ui->spinBoxLeft->value());
mg.setRight(ui->spinBoxRight->value());
ui->chartView->chart()->setMargins(mg);
}
void MainWindow::on_comboBoxAction_currentIndexChanged(int index)
{
ui->chartView->chart()->setAnimationOptions((QChart::AnimationOptions)index);
}
void MainWindow::on_comboBoxTheme_currentIndexChanged(int index)
{
ui->chartView->chart()->setTheme((QChart::ChartTheme)index);
}
void MainWindow::on_rbtnSeriesSin_clicked()
{
if( ui->rbtnSeriesSin->isChecked())
{
curSeries = (QLineSeries*)ui->chartView->chart()->series().at(0);
}
else
{
curSeries = (QLineSeries*)ui->chartView->chart()->series().at(1);
}
ui->lineEditLine->setText(curSeries->name());
ui->checkBoxSeries->setChecked(curSeries->isVisible());
ui->checkBoxDataPoint->setChecked(curSeries->pointsVisible());
ui->horizontalSlider->setValue(curSeries->opacity() * 10); // 0-1 => 0-10
ui->checkBoxPointTip->setChecked(curSeries->pointLabelsVisible());
}
void MainWindow::on_rbtnSeriesCos_clicked()
{
if( ui->rbtnSeriesSin->isChecked())
{
curSeries = (QLineSeries*)ui->chartView->chart()->series().at(0);
}
else
{
curSeries = (QLineSeries*)ui->chartView->chart()->series().at(1);
}
ui->lineEditLine->setText(curSeries->name());
ui->checkBoxSeries->setChecked(curSeries->isVisible());
ui->checkBoxDataPoint->setChecked(curSeries->pointsVisible());
ui->horizontalSlider->setValue(curSeries->opacity() * 10); // 0-1 => 0-10
ui->checkBoxPointTip->setChecked(curSeries->pointLabelsVisible());
}
void MainWindow::on_btnLineName_clicked()
{
curSeries->setName(ui->lineEditLine->text());
}
void MainWindow::on_checkBoxSeries_clicked(bool checked)
{
curSeries->setVisible(checked);
}
void MainWindow::on_checkBoxDataPoint_clicked(bool checked)
{
curSeries->setPointLabelsVisible(checked);
}
void MainWindow::on_btnLineColor_clicked()
{
QColor color = curSeries->color();
color = QColorDialog::getColor(color);
if(color.isValid())
{
curSeries->setColor(color);
}
}
void MainWindow::on_horizontalSlider_valueChanged(int value)
{
curSeries->setOpacity(value / 10.0);
}
void MainWindow::on_checkBoxPointTip_clicked(bool checked)
{
curSeries->setPointLabelsVisible(checked);
}
void MainWindow::on_btnPointTipColor_clicked()
{
QColor color = curSeries->pointLabelsColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
curSeries->setPointLabelsColor(color);
}
}
void MainWindow::on_btnPointTipFont_clicked()
{
QFont font = curSeries->pointLabelsFont();
bool ok;
font = QFontDialog::getFont(&ok, font);
if(ok)
{
curSeries->setPointLabelsFont(font);
}
}
void MainWindow::on_rbtnDisplayX_clicked()
{
if(ui->rbtnDisplayX->isChecked())
{
curSeries->setPointLabelsFormat("@yPoint");
}
else
{
curSeries->setPointLabelsFormat("(@xPoint,@yPoint)");
}
}
void MainWindow::on_rbtnDisplayXY_clicked()
{
if(ui->rbtnDisplayX->isChecked())
{
curSeries->setPointLabelsFormat("@yPoint");
}
else
{
curSeries->setPointLabelsFormat("(@xPoint,@yPoint)");
}
}
void MainWindow::on_rbtnSetX_clicked()
{
QList<QAbstractAxis*> axes;
if(ui->rbtnSetX->isChecked())
{
axes = ui->chartView->chart()->axes(Qt::Horizontal);
}
else
{
axes = ui->chartView->chart()->axes(Qt::Vertical);
}
curAxis = (QValueAxis*)axes[0];
ui->doubleSpinBoxMin->setValue(curAxis->min());
ui->doubleSpinBoxMax->setValue(curAxis->max());
ui->lineEditAxisTitle->setText(curAxis->titleText());
ui->checkBoxAxisTitleIsVisibe->setChecked(curAxis->isTitleVisible());
ui->lineEditFormat->setText(curAxis->labelFormat());
ui->checkBoxAxisTitleIsVisibe->setChecked(curAxis->labelsVisible());
ui->checkBoxIsGridLineVisible->setChecked(curAxis->isGridLineVisible());
ui->checkBoxisLineVisible->setChecked(curAxis->isLineVisible());
ui->spinBoxTick->setValue(curAxis->tickCount());
ui->checkBoxisLineVisible->setChecked(curAxis->isLineVisible());
ui->spinBoxMinorTick->setValue(curAxis->minorTickCount());
ui->checkBoxIsMinorGirdLineVisible->setChecked(curAxis->isMinorGridLineVisible());
}
void MainWindow::on_rbtnSetY_clicked()
{
QList<QAbstractAxis*> axes;
if(ui->rbtnSetX->isChecked())
{
axes = ui->chartView->chart()->axes(Qt::Horizontal);
}
else
{
axes = ui->chartView->chart()->axes(Qt::Vertical);
}
curAxis = (QValueAxis*)axes[0];
ui->doubleSpinBoxMin->setValue(curAxis->min());
ui->doubleSpinBoxMax->setValue(curAxis->max());
ui->lineEditAxisTitle->setText(curAxis->titleText());
ui->checkBoxAxisTitleIsVisibe->setChecked(curAxis->isTitleVisible());
ui->lineEditFormat->setText(curAxis->labelFormat());
ui->checkBoxAxisTitleIsVisibe->setChecked(curAxis->labelsVisible());
ui->checkBoxIsGridLineVisible->setChecked(curAxis->isGridLineVisible());
ui->checkBoxisLineVisible->setChecked(curAxis->isLineVisible());
ui->spinBoxTick->setValue(curAxis->tickCount());
ui->checkBoxisLineVisible->setChecked(curAxis->isLineVisible());
ui->spinBoxMinorTick->setValue(curAxis->minorTickCount());
ui->checkBoxIsMinorGirdLineVisible->setChecked(curAxis->isMinorGridLineVisible());
}
void MainWindow::on_checkBoxIsVisible_clicked(bool checked)
{
curAxis->setVisible(checked);
}
void MainWindow::on_btnSetAxisRange_clicked()
{
curAxis->setRange(ui->doubleSpinBoxMin->value(), ui->doubleSpinBoxMax->value());
}
void MainWindow::on_btnSetAxisTitle_clicked()
{
curAxis->setTitleText(ui->lineEditAxisTitle->text());
}
void MainWindow::on_checkBoxAxisTitleIsVisibe_clicked(bool checked)
{
curAxis->setTitleVisible(checked);
}
void MainWindow::on_btnAxisTitleFont_clicked()
{
QFont font = curAxis->titleFont();
bool ok;
font = QFontDialog::getFont(&ok, font);
if(ok)
{
curAxis->setTitleFont(font);
}
}
void MainWindow::on_btnSetFormat_clicked()
{
curAxis->setLabelFormat(ui->lineEditFormat->text());
}
void MainWindow::on_btnSetColor_clicked()
{
QColor color = curAxis->labelsColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
curAxis->setLabelsColor(color);
}
}
void MainWindow::on_btnSetFont_clicked()
{
QFont font = curAxis->labelsFont();
bool ok;
font = QFontDialog::getFont(&ok, font);
if(ok)
{
curAxis->setLabelsFont(font);
}
}
void MainWindow::on_checkBoxlabelVisible_clicked(bool checked)
{
curAxis->setLabelsVisible(checked);
}
void MainWindow::on_checkBoxIsGridLineVisible_clicked(bool checked)
{
curAxis->setLineVisible(checked);
}
void MainWindow::on_btnGridLineColor_clicked()
{
QColor color = curAxis->gridLineColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
curAxis->setGridLineColor(color);
}
}
void MainWindow::on_btnGridLinePen_clicked()
{
QPen pen = curAxis->gridLinePen();
bool ok = false;
pen = DialogPen::getPen(pen, ok);
if(ok)
{
curAxis->setGridLinePen(pen);
}
}
void MainWindow::on_checkBoxIsMinorGirdLineVisible_clicked(bool checked)
{
curAxis->setMinorGridLineVisible(checked);
}
void MainWindow::on_btnMinorGridLineColor_clicked()
{
QColor color = curAxis->minorGridLineColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
curAxis->setMinorGridLineColor(color);
}
}
void MainWindow::on_btnMinorGirdLinePen_clicked()
{
QPen pen = curAxis->minorGridLinePen();
bool ok = false;
pen = DialogPen::getPen(pen, ok);
if(ok)
{
curAxis->setMinorGridLinePen(pen);
}
}
void MainWindow::on_spinBoxMinorTick_valueChanged(int arg1)
{
curAxis->setMinorTickCount(arg1);
}
void MainWindow::on_btnLinePen_2_clicked()
{
QPen pen = curAxis->linePen();
bool ok = false;
pen = DialogPen::getPen(pen, ok);
if(ok)
{
curAxis->setLinePen(pen);
}
}
void MainWindow::on_spinBoxTick_valueChanged(int arg1)
{
curAxis->setTickCount(arg1);
}
void MainWindow::on_btnLinePenColor_clicked()
{
QColor color = curAxis->linePenColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
curAxis->setLinePenColor(color);
}
}
三、QChart常见图表绘制
1、图表与类
(1)柱状图
- QBarSet:数据集
- QBarSeries:一个序列可以包含多个QBarSet
- QBarCategoryAxis:横坐标轴
- QValueAxis:纵坐标轴
(2)饼状图
- QPieSeries:数据序列
- QPieSlice:饼图扇区
(3)堆叠柱状图
- QBarSet:数据集
- QStackedBarSeries:一个序列可以有多个QBarSet
- QBarCategoryAxis:横坐标
- QValueAxis:纵坐标轴
(4)百分比柱状图
- QBarSet:数据集
- QPercentageBarSeries:一个序列可以有多个QBarSet
- QBarCategoryAxis:横坐标
- QValueAxis:纵坐标轴
(5)散点图和光滑曲线
- QSplineSeries、QLineSeries:散点和平滑线
- QValueAxis:坐标轴。
2、实现程序
(1)创建项目,基于QMainWindows
(2)添加图表资源文件,添加工具栏
(3)添加组件
(4)柱状图
void MainWindow::initBarChart()
{
QChart *chart = new QChart;
chart->setTitle("BarChart演示");
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->cvChartBar->setChart(chart);
ui->cvChartBar->setRenderHint(QPainter::Antialiasing);
}
void MainWindow::buildBarChart()
{
QChart *chart = ui->cvChartBar->chart();
chart->removeAllSeries();
if(chart->axisX() != nullptr)
{
chart->removeAxis(chart->axisX());
}
if(chart->axisY() != nullptr)
{
chart->removeAxis(chart->axisY());
}
// 数据集
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());
QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());
QBarSet *setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());
QLineSeries *lineAverage = new QLineSeries;
lineAverage->setName(theModel->horizontalHeaderItem(colNoAverage)->text());
QPen pen;
pen.setColor(Qt::red);
pen.setWidth(2);
lineAverage->setPen(pen);
for (int i = 0; i < theModel->rowCount(); ++i)
{
setMath->append(theModel->item(i, colNoMath)->text().toInt());
setChinese->append(theModel->item(i, colNoChinese)->text().toInt());
setEnglish->append(theModel->item(i, colNoEnglish)->text().toInt());
lineAverage->append(QPointF(i, theModel->item(i, colNoAverage)->text().toFloat()));
}
// 序列
QBarSeries *series = new QBarSeries;
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
chart->addSeries(series);
chart->addSeries(lineAverage);
chart->legend()->setAlignment(Qt::AlignBottom);
QStringList category;
for (int i = 0; i < theModel->rowCount(); ++i)
{
category << theModel->item(i, colNoName)->text();
}
QBarCategoryAxis *axisX = new QBarCategoryAxis;
axisX->setCategories(category);
chart->setAxisX(axisX, series);
chart->setAxisX(axisX, lineAverage);
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 100);
axisY->setTitleText("分数");
chart->setAxisY(axisY, series);
chart->setAxisY(axisY, lineAverage);
}
(5)饼状图
void MainWindow::initPieChart()
{
QChart *chart = new QChart;
chart->setTitle("PieChart演示");
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->cvPieChart->setChart(chart);
ui->cvPieChart->setRenderHint(QPainter::Antialiasing);
}
void MainWindow::buildPieChart()
{
QChart *chart = ui->cvPieChart->chart();
chart->removeAllSeries();
if(chart->axisX() != nullptr)
{
chart->removeAxis(chart->axisX());
}
if(chart->axisY() != nullptr)
{
chart->removeAxis(chart->axisY());
}
QPieSeries *series = new QPieSeries;
series->setHoleSize(ui->dSpinBoxHoleSize->value());
series->setPieSize(ui->dSpinBoxPieSize->value());
int colNo = ui->comboBoxScore->currentIndex() + colNoMath;
for (int i = 0; i < 5; ++i)
{
QTreeWidgetItem *item = ui->treeWidget->topLevelItem(i);
series->append(item->text(0), item->text(colNo).toFloat());
}
QPieSlice *slice;
for (int i = 0; i < 5; ++i)
{
slice = series->slices().at(i);
slice->setLabel(slice->label() + QString::asprintf("%.0f人, %.2f%%",
slice->value(), slice->percentage()));
connect(slice, SIGNAL(hovered(bool)),
this, SLOT(on_SliceHigtLight(bool)));
}
series->setLabelsVisible(true);
chart->setTitle("PieChart --" + ui->comboBoxScore->currentText());
chart->addSeries(series);
chart->legend()->setAlignment(Qt::AlignRight);
}
void MainWindow::on_SliceHigtLight(bool show)
{
// 鼠标到饼图扇区,弹出动画
QPieSlice *slice = (QPieSlice*)sender();
slice->setExploded(show);
}
void MainWindow::on_dSpinBoxHoleSize_valueChanged(double arg1)
{
QPieSeries* series = (QPieSeries*) ui->cvPieChart->chart()->series().at(0);
series->setHoleSize(arg1);
}
void MainWindow::on_dSpinBoxPieSize_valueChanged(double arg1)
{
QPieSeries* series = (QPieSeries*) ui->cvPieChart->chart()->series().at(0);
series->setPieSize(arg1);
}
void MainWindow::on_comboBoxTheme_currentIndexChanged(int index)
{
ui->cvPieChart->chart()->setTheme(QChart::ChartTheme(index));
}
(6)堆叠柱状图
void MainWindow::initStackedBar()
{
QChart *chart = new QChart;
chart->setTitle("StackedBar演示");
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->cvStackedBar->setChart(chart);
ui->cvStackedBar->setRenderHint(QPainter::Antialiasing);
}
void MainWindow::buildStackedBar()
{
QChart *chart = ui->cvStackedBar->chart();
chart->removeAllSeries();
if(chart->axisX() != nullptr)
{
chart->removeAxis(chart->axisX());
}
if(chart->axisY() != nullptr)
{
chart->removeAxis(chart->axisY());
}
// 数据集
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());
QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());
QBarSet *setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());
QStringList categories;
for (int i = 0; i < theModel->rowCount(); ++i)
{
categories << theModel->item(i, colNoName)->text();
setMath->append(theModel->item(i, colNoMath)->text().toFloat());
setChinese->append(theModel->item(i, colNoChinese)->text().toFloat());
setEnglish->append(theModel->item(i, colNoEnglish)->text().toFloat());
}
QStackedBarSeries *series = new QStackedBarSeries;
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
chart->addSeries(series);
QBarCategoryAxis *axisX = new QBarCategoryAxis;
axisX->append(categories);
chart->setAxisX(axisX, series);
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 300);
axisY->setTitleText("总分");
chart->setAxisY(axisY, series);
}
(7)百分比柱状图
void MainWindow::initPercentBar()
{
QChart *chart = new QChart;
chart->setTitle("PercentBar演示");
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->cvPercentBar->setChart(chart);
ui->cvPercentBar->setRenderHint(QPainter::Antialiasing);
}
void MainWindow::buildPercentBar()
{
QChart *chart = ui->cvPercentBar->chart();
chart->removeAllSeries();
if(chart->axisX() != nullptr)
{
chart->removeAxis(chart->axisX());
}
if(chart->axisY() != nullptr)
{
chart->removeAxis(chart->axisY());
}
// 数据集
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());
QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());
QBarSet *setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());
QStringList categories;
for (int i = 0; i < 5; ++i)
{
categories << ui->treeWidget->topLevelItem(i)->text(colNoName);
setMath->append(ui->treeWidget->topLevelItem(i)->text(colNoMath).toFloat());
setChinese->append(ui->treeWidget->topLevelItem(i)->text(colNoChinese).toFloat());
setEnglish->append(ui->treeWidget->topLevelItem(i)->text(colNoEnglish).toFloat());
}
QPercentBarSeries *series = new QPercentBarSeries;
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
chart->addSeries(series);
QBarCategoryAxis *axisX = new QBarCategoryAxis;
axisX->append(categories);
chart->setAxisX(axisX, series);
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 100);
axisY->setTitleText("分数百分比");
chart->setAxisY(axisY, series);
}
(8)散点曲线图
void MainWindow::initScatterChart()
{
QChart *chart = new QChart;
chart->setTitle("ScatterChart演示");
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->cvScatterChart->setChart(chart);
ui->cvScatterChart->setRenderHint(QPainter::Antialiasing);
}
void MainWindow::buildScatterChart()
{
QChart *chart = ui->cvScatterChart->chart();
chart->removeAllSeries();
if(chart->axisX() != nullptr)
{
chart->removeAxis(chart->axisX());
}
if(chart->axisY() != nullptr)
{
chart->removeAxis(chart->axisY());
}
QSplineSeries *seriesLine = new QSplineSeries;
seriesLine->setName("spline");
QPen pen;
pen.setWidth(2);
pen.setColor(Qt::red);
seriesLine->setPen(pen);
QScatterSeries *series0 = new QScatterSeries;
series0->setName("散点");
series0->setMarkerShape(QScatterSeries::MarkerShapeCircle); // 圆形
series0->setBorderColor(Qt::black);
series0->setBrush(QBrush(Qt::blue));
series0->setMarkerSize(12);
for (int i = 0; i < 10; ++i)
{
int x = qrand() % 20;
int y = qrand() % 20;
series0->append(x, y);
seriesLine->append(x, y);
}
chart->addSeries(seriesLine);
chart->addSeries(series0);
chart->createDefaultAxes();
chart->axisX()->setTitleText("X轴");
chart->axisX()->setRange(-5, 25);
chart->axisY()->setTitleText("Y轴");
chart->axisY()->setRange(-5, 25);
}
四、图表其他操作
图表特定鼠标事件操作需要使用继承类实现事件的处理
1、实现程序
(1)创建项目,基于QMainWindow
(2)添加资源文件与图标
(3)添加QChartView派生类
AXBChartView::AXBChartView(QWidget *parent) : QChartView(parent)
{
setMouseTracking(true); //
setDragMode(QGraphicsView::RubberBandDrag); // 框选区域
}
void AXBChartView::keyPressEvent(QKeyEvent *event)
{
switch (event->key())
{
case Qt::Key_Plus:
{
chart()->zoom(1.2);
}
break;
case Qt::Key_Minus:
{
chart()->zoom(0.8);
}
break;
case Qt::Key_Left:
{
chart()->scroll(10, 0);
}
break;
case Qt::Key_Right:
{
chart()->scroll(-10, 0);
}
break;
case Qt::Key_Up:
{
chart()->scroll(0, -10);
}
break;
case Qt::Key_Down:
{
chart()->scroll(0, 10);
}
break;
case Qt::Key_PageUp:
{
chart()->scroll(0, -50);
}
break;
case Qt::Key_PageDown:
{
chart()->scroll(0, 50);
}
break;
case Qt::Key_Home:
{
chart()->zoomReset();
}
break;
default:
QGraphicsView::keyPressEvent(event);
break;
}
}
void AXBChartView::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
beginPoint = event->pos();
}
QChartView::mousePressEvent(event);
}
void AXBChartView::mouseMoveEvent(QMouseEvent *event)
{
QPoint point = event->pos();
emit mouseMovePoint(point);
QChartView::mouseMoveEvent(event);
}
void AXBChartView::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
endPoint = event->pos();
QRectF rectF;
rectF.setTopLeft(beginPoint);
rectF.setBottomRight(endPoint);
if(rectF.width() > 10 || rectF.height() > 10)
{
chart()->zoomIn(rectF);
}
}
else if(event->button() == Qt::RightButton)
{
chart()->zoomReset();
}
QChartView::mouseReleaseEvent(event);
}
(4)实现功能
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->chartView);
labXYValue = new QLabel("坐标X: Y: ");
labXYValue->setMinimumWidth(200);
ui->statusBar->addWidget(labXYValue);
createChart();
prepareData();
connect(ui->chartView, SIGNAL(mouseMovePoint(QPoint)),
this, SLOT(on_mouseMovePoint(QPoint)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::createChart()
{
QChart *chart = new QChart;
chart->setTitle("曲线");
ui->chartView->setChart(chart);
ui->chartView->setRenderHint(QPainter::Antialiasing);
QLineSeries *series0 = new QLineSeries;
QLineSeries *series1 = new QLineSeries;
series0->setName("Sin曲线");
series1->setName("Cos曲线");
QPen pen;
pen.setStyle(Qt::DotLine);
pen.setColor(Qt::green);
pen.setWidth(2);
series0->setPen(pen);
pen.setColor(Qt::red);
series1->setPen(pen);
chart->addSeries(series0);
chart->addSeries(series1);
chart->createDefaultAxes();
chart->axisX()->setRange(0, 10);
chart->axisY()->setRange(-1.5, 1.5);
foreach (auto marker, ui->chartView->chart()->legend()->markers())
{
connect(marker, SIGNAL(clicked()),
this, SLOT(on_legendMarkerClicked()));
}
}
void MainWindow::prepareData()
{
// 准备数据
QLineSeries *series0 = (QLineSeries *)ui->chartView->chart()->series().at(0);
QLineSeries *series1 = (QLineSeries *)ui->chartView->chart()->series().at(1);
qsrand(QTime::currentTime().second());
for (int i = 0; i < 100; ++i)
{
qreal dValue;
dValue = qSin(i * 0.1) + (qrand() % 10 - 5) / 10.0;
series0->append(i * 0.1, dValue);
dValue = qCos(i * 0.1) + (qrand() % 10 - 5) / 10.0;
series1->append(i * 0.1, dValue);
}
}
void MainWindow::on_mouseMovePoint(QPoint point)
{
QPointF pt = ui->chartView->chart()->mapToValue(point);
labXYValue->setText(QString::asprintf("坐标X: %.2f Y: %.2f",
pt.x(), pt.y()));
}
void MainWindow::on_legendMarkerClicked()
{
QLegendMarker *marker = (QLegendMarker*)sender();
marker->series()->setVisible(!marker->series()->isVisible());
marker->setVisible(true);
int alpha = 255;
if(!marker->series()->isVisible())
{
alpha = 120;
}
QBrush brush = marker->labelBrush();
QColor color = brush.color();
color.setAlpha(alpha);
brush.setColor(color);
marker->setLabelBrush(brush);
}
void MainWindow::on_actZoomIn_triggered()
{
ui->chartView->chart()->zoom(1.2);
}
void MainWindow::on_actZoomOut_triggered()
{
ui->chartView->chart()->zoom(0.8);
}
void MainWindow::on_actZoomReset_triggered()
{
ui->chartView->chart()->zoomReset();
}