#include "PieEChartWidget.h"
#include "ui_PieEChartWidget.h"
#include <QFile>
#include <QMessageBox>
#include <QTimer>
// QtCreator在msvc下设置编码也或有一些乱码,直接一刀切,避免繁琐的设置
//#define MSVC
#ifdef MSVC
#define QSTRING(s) QString::fromLocal8Bit(s)
#else
#define QSTRING(s) QString(s)
#endif
#include <QDebug>
#include <QDateTime>
//#define LOG qDebug()<<__FILE__<<__LINE__
//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__
//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()
//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")
#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")
PieEChartWidget::PieEChartWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::PieEChartWidget),
_pWebEngineView(0),
_pWebEnginePage(0),
_pWebChannel(0),
_htmlDir("D:/qtProject/echartsDemo/echartsDemo/modules/PieEChartWidget/html"), // 使用了绝对路径,引到html文件夹
_indexFileName("PieEChartWidget.html"),
_pLabelCenterUp(0),
_pLabelCenterDown(0)
ui->setupUi(this);
QString version = "v1.0.0";
setWindowTitle(QString("基于Qt的EChartb饼状图Demo %1(长沙红胖子Qt").arg(version));
// 设置无边框,以及背景透明
// 背景透明,在界面构架时,若为本窗口为其他窗口提升为本窗口时,
// 则再qss会在主窗口第一级添加frame_all,防止其他窗口提升本窗口而冲掉qss设置
// setWindowFlag(Qt::FramelessWindowHint);
// setAttribute(Qt::WA_TranslucentBackground, true);
#if 0
// 这是方法一:让滚动条不出来(通过大小),还有一个方法是在html设置body的overflow: hidden
// resize(600 + 20, 400 + 20);
#endif
initControl();
PieEChartWidget::~PieEChartWidget()
delete ui;
void PieEChartWidget::setPercent(double percent)
if(percent < 0 || percent > 100)
return;
LOG << percent;
if(percent == 100)
_pLabelCenterDown->setText(QSTRING("100%"));
}else{
if(_percent < 10)
_pLabelCenterDown->setText(QSTRING("%1%").arg(percent, 0, 'g', 2));
}else{
_pLabelCenterDown->setText(QSTRING(" %1%").arg(percent, 0, 'g', 2));
QString jsStr = QSTRING(
"option.series[0].data[0].value = %1;"
"option.series[0].data[1].value = %2;"
"myChart.setOption(option, true);")
.arg(percent)
.arg(100 - percent);
LOG << jsStr;
_percent = percent;
runJsScript(jsStr);
void PieEChartWidget::initControl()
_pLabelCenterUp = new QLabel(this);
_pLabelCenterUp->raise();
_pLabelCenterUp->setAlignment(Qt::AlignBottom | Qt::AlignHCenter);
_pLabelCenterUp->setText(QSTRING("开机率"));
_pLabelCenterUp->setStyleSheet("font-size: 36px;"
"font-weight: bold;"
"align: top ;"
"color: rgb(41, 235, 255);"
"padding: 0 30 10 0;");
_pLabelCenterDown = new QLabel(this);
_pLabelCenterDown->raise();
_pLabelCenterDown->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
_pLabelCenterDown->setText(QSTRING("%1%").arg(0));
_pLabelCenterDown->setStyleSheet("font-size: 64px;"
"font-weight: bold;"
"align: center;"
"color: rgb(41, 235, 255);"
"padding: 0 30 0 0;");
_pWebEngineView = new QWebEngineView(this);
_pWebEnginePage = new QWebEnginePage(this);
_pWebChannel = new QWebChannel(this);
QString filePath;
#if 0
// 使用绝对路径
filePath = QString("%1/%2").arg(_htmlDir).arg(_indexFileName);
#else
// 使用资源路径
filePath = "qrc:/pieEChartWidget/html/eChartWidget.html";
#endif
LOG << "file exist:" << QFile::exists(filePath) << filePath;
#if 0
// 打印html文件内容
QFile file(_indexFilePath);
file.open(QIODevice::ReadOnly);
LOG << QString(file.readAll());
file.close();
#endif
connect(_pWebEnginePage, SIGNAL(loadFinished(bool)), this, SLOT(slot_loadFinished(bool)));
_pWebEnginePage->load(QUrl(filePath));
_pWebEnginePage->setWebChannel(_pWebChannel);
_pWebEngineView->setPage(_pWebEnginePage);
// 背景透明
// _pWebEngineView->setStyleSheet("background-color: transparent");
_pWebEnginePage->setBackgroundColor(Qt::transparent);
// 鼠标穿透
_pWebEngineView->setAttribute(Qt::WA_TransparentForMouseEvents, true);
void PieEChartWidget::slot_loadFinished(bool result)
if(result)
initJs();
resizeEvent(0);
void PieEChartWidget::initJs()
_initJsStr = QSTRING(
"var option;"
"option = {"
" legend: {"
" top: '90%',"
" show: false"
" },"
" series: ["
" {"
" selectedMode: 'single', /* 选择模式 */"
" selectedOffset: 0, /* 选取后偏移,需要先设置选择模式才生效 */"
" type: 'pie', /* 图例类型 */"
" radius: ['60%', '90%'], /* 同心圆双边界区域 */"
" itemStyle: { /* 数据项样式 */"
" borderRadius: 0, /* 边界圆角 */"
" borderColor: '#FF0000', /* 边界颜色 */"
" borderWidth: 0 /* 边界宽度 */"
" },"
" avoidLabelOverlap: true,"
" label: {"
" show: false,"
" fontSize: '32',"
" fontWeight: 'bold',"
" formatter: '{b}\\n\\n{d}%',"
" position: 'center'"
" },"
" emphasis: { /* 高亮状态的扇区和标签样式 */"
" label: {"
" show: false,"
" fontSize: '32',"
" fontWeight: 'bold'"
" }"
" },"
" labelLine: {"
" show: false"
" },"
" data: ["
" {"
" value: 0,"
" name: '开机率',"
" selected: true,"
" itemStyle: {"
" color: 'rgba(41, 235, 255, 255)',"
" shadowColor:'rgba(41, 235, 255, 255)',"
" shadowBlur: 10,"
" shadowOffsetX: 0,"
" shadowOffsetY: 0,"
" }"
" },"
" {"
" value: 100,"
" name: '11',"
" itemStyle: {"
" color: 'rgba(45,62,113,255)',"
" shadowColor:'rgba(45,62,113,255)',"
" shadowBlur: 10,"
" shadowOffsetX: 0,"
" shadowOffsetY: 0,"
" }"
" }"
" ]"
" }"
" ]"
"myChart.setOption(option);"
_initValueJsStr = QSTRING(
"var option;"
"option = {"
" legend: {"
" top: '90%',"
" show: false"
" },"
" series: ["
" {"
" selectedMode: 'single', /* 选择模式 */"
" selectedOffset: 0, /* 选取后偏移,需要先设置选择模式才生效 */"
" type: 'pie', /* 图例类型 */"
" radius: ['60%', '90%'], /* 同心圆双边界区域 */"
" itemStyle: { /* 数据项样式 */"
" borderRadius: 0, /* 边界圆角 */"
" borderColor: '#FF0000', /* 边界颜色 */"
" borderWidth: 0 /* 边界宽度 */"
" },"
" avoidLabelOverlap: true,"
" label: {"
" show: false,"
" fontSize: '32',"
" fontWeight: 'bold',"
" formatter: '{b}\\n\\n{d}%',"
" position: 'center'"
" },"
" emphasis: { /* 高亮状态的扇区和标签样式 */"
" label: {"
" show: false,"
" fontSize: '32',"
" fontWeight: 'bold'"
" }"
" },"
" labelLine: {"
" show: false"
" },"
" data: ["
" {"
" value: %1,"
" name: '开机率',"
" selected: true,"
" itemStyle: {"
" color: 'rgba(41, 235, 255, 255)',"
" shadowColor:'rgba(41, 235, 255, 255)',"
" shadowBlur: 10,"
" shadowOffsetX: 0,"
" shadowOffsetY: 0,"
" }"
" },"
" {"
" value: %2,"
" name: '',"
" itemStyle: {"
" color: 'rgba(45, 62, 113, 255)',"
" shadowColor:'rgba(45,62,113,255)',"
" shadowBlur: 10,"
" shadowOffsetX: 0,"
" shadowOffsetY: 0,"
" }"
" }"
" ]"