QCustomplot的基本使用方法
-
- 一、準備工作
- 二、使用方法
-
- 頭檔案内容
- cpp檔案内容
- 三、總結
最近在寫一個程式需要畫圖,原本使用的是qtcharts,但是有可能是我使用方法沒對,用qtcharts畫圖的效率極其低下,上萬個點時,尤其是可能卡死,後來聽說qcustomplot好用,于是改用qcustomplot,果不其然,一萬多個點,幾乎秒出。
qcustomplot的使用方法與qtchart不太相同,是以記錄一二。
我所使用的qcustomplot版本為2.0版本。
一、準備工作
qcustomplot使用過程中,有如下幾個注意點:
- 有幾種使用方法,我采用的是,将qcustomplot.h與qcustomplot.cpp放置工程檔案下,而後導入;
- 修改pro檔案,添加兩個内容,一個是
,另一個是QT += printsupport
,前者的作用是為了使用該控件,後者的作用是為了讓畫圖過程中使用OpenGL以增加效率,另外,如果你是後來添加的DEFINES += QCUSTOMPLOT_USE_OPENGL
則需要清除工程檔案,重新建構,因為這部分内容需要寫入預編譯産生的檔案中;DEFINES += QCUSTOMPLOT_USE_OPENGL
- 在ui檔案中,添加一個Widget的控件,提升為qcustomplot,這個需要自己手動将剛剛導入進來的qcustomplot添加到提升的類中。
二、使用方法
該部分内容,直接貼代碼,看注釋。這是一個在dialog中通過提升Wdiget實作qcustomplot的方法。
頭檔案内容
#include <QDialog>
namespace Ui {
class precisionPaintDialog;
}
class precisionPaintDialog : public QDialog
{
Q_OBJECT
public:
explicit precisionPaintDialog(QWidget *parent = 0);
~precisionPaintDialog();
void addGraphs();
QVector<double> x1; //圖表1的X軸資料
QVector<double> c1; //圖表1的Y軸資料
QVector<double> x2; //圖表2的X軸資料
QVector<double> c2; //圖表2的X軸資料
public slots:
//圖表1的滑鼠右鍵功能
void mouseReleaseEvent_plot1(QMouseEvent * event);
//圖表2的滑鼠右鍵功能
void mouseReleaseEvent_plot2(QMouseEvent * event);
private:
Ui::precisionPaintDialog *ui;
private slots:
void recover_btn_plot1(); //圖表1的恢複功能
void recover_btn_plot2(); //圖表2的恢複功能
void save_jpg_btn_plot1(); //圖表1的儲存為jpg功能
void save_jpg_btn_plot2(); //圖表2的儲存為jpg功能
};
cpp檔案内容
#include "precisionpaintdialog.h"
#include "ui_precisionpaintdialog.h"
precisionPaintDialog::precisionPaintDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::precisionPaintDialog)
{
ui->setupUi(this);
this->setWindowFlags(Qt::WindowMinMaxButtonsHint);
//圖友善,我就用10000個相同的值的點來示範,反正數值大小無所謂。
for(int i = 0 ; i<10000;i++){
x1.append(i);
c1.append(0.01);
x2.append(i);
c2.append(0.02);
}
//将第一個widget控件的滑鼠釋放的信号與自己定義個一個函數相連接配接,為了友善使用,我自行定義了一個函數。
connect(ui->widget_plot,SIGNAL(mouseRelease(QMouseEvent*)),this,SLOT(mouseReleaseEvent_plot1(QMouseEvent*)));
//将第二個widget控件的滑鼠釋放的信号與自己定義個一個函數相連接配接,為了友善使用,我自行定義了一個函數。
connect(ui->widget_plot_2,SIGNAL(mouseRelease(QMouseEvent*)),this,SLOT(mouseReleaseEvent_plot2(QMouseEvent*)));
//實作添加圖表及圖表的配置,及圖表的資料的函數。
addGraphs();
}
precisionPaintDialog::~precisionPaintDialog()
{
delete ui;
}
//圖表的初始化函數
void precisionPaintDialog::addGraphs()
{
//這個是坐标軸的固有屬性的一個政策類,利用該政策,可以實作指定坐标軸的一些屬性,比如刻度步長,刻度數目等等。
QSharedPointer<QCPAxisTickerFixed> ticker(new QCPAxisTickerFixed);
//設定刻度步長為0.004
ticker.data()->setTickStep(0.004);
//設定坐标軸有9個刻度值
ticker.data()->setTickCount(9);
//新增一個圖表
ui->widget_plot->addGraph();
//設定圖表的名稱
ui->widget_plot->graph()->setName("通道A随機誤差");
//将橫軸和縱軸的值指派給坐标軸
ui->widget_plot->graph()->setData(x1, c1);
//設定X軸的标簽
ui->widget_plot->xAxis->setLabel("相對時(秒)");
//設定Y軸的标簽
ui->widget_plot->yAxis->setLabel("通道A随機誤差");
//設定X軸的值的範圍
ui->widget_plot->xAxis->setRange(x1.first(),x1.last());
//設定Y軸的值的範圍
ui->widget_plot->yAxis->setRange(0,0.032);
//将剛生成的坐标軸的政策,設定到Y軸上
ui->widget_plot->yAxis->setTicker(ticker);
//設定該坐标軸可拖動,可縮放
ui->widget_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
//設定使用opengl畫圖
ui->widget_plot->setOpenGl(true);
//畫圖
ui->widget_plot->replot();
//圖表2與圖表1一模一樣,不贅述
ui->widget_plot_2->addGraph();
ui->widget_plot_2->yAxis->ticker().data()->setTickCount(9);
ui->widget_plot_2->graph()->setName("通道B随機誤差");
ui->widget_plot_2->graph()->setData(x2, c2);
ui->widget_plot_2->xAxis->setLabel("相對時(秒)");
ui->widget_plot_2->yAxis->setLabel("通道B随機誤差");
ui->widget_plot_2->xAxis->setRange(x2.first(),x2.last());
ui->widget_plot_2->yAxis->setRange(0,0.032);
ui->widget_plot_2->yAxis->setTicker(ticker);
ui->widget_plot_2->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
ui->widget_plot_2->setOpenGl(true);
ui->widget_plot_2->replot();
}
//右鍵時顯示右鍵菜單欄,并實作按鈕功能
void precisionPaintDialog::mouseReleaseEvent_plot1(QMouseEvent *event)
{
if(event->button()==Qt::RightButton)
{
//建立一個菜單
QMenu *pMenu=new QMenu(ui->widget_plot);
//建立菜單中的按鈕
QAction *act_Reset=new QAction(tr("複位"),ui->widget_plot);
QAction *act_Save_jpg=new QAction(tr("儲存為jpg"),ui->widget_plot);
//将按鈕添加到菜單
pMenu->addAction(act_Reset);
pMenu->addAction(act_Save_jpg);
//将按鈕與實作的功能函數相綁定
connect(act_Reset,SIGNAL(triggered(bool)),this,SLOT(recover_btn_plot1()));
connect(act_Save_jpg,SIGNAL(triggered(bool)),this,SLOT(save_jpg_btn_plot1()));
//在右鍵點選的位置顯示菜單
pMenu->exec(cursor().pos());
//釋放記憶體
QList<QAction*>list=pMenu->actions();
foreach (QAction* pAction, list) {
delete pAction;
}
delete pMenu;
}
}
//與上述一緻
void precisionPaintDialog::mouseReleaseEvent_plot2(QMouseEvent *event)
{
if(event->button()==Qt::RightButton)
{
QMenu *pMenu=new QMenu(ui->widget_plot_2);
QAction *act_Reset=new QAction(tr("複位"),ui->widget_plot_2);
QAction *act_Save_jpg=new QAction(tr("儲存為jpg"),ui->widget_plot_2);
pMenu->addAction(act_Reset);
pMenu->addAction(act_Save_jpg);
connect(act_Reset,SIGNAL(triggered(bool)),this,SLOT(recover_btn_plot2()));
connect(act_Save_jpg,SIGNAL(triggered(bool)),this,SLOT(save_jpg_btn_plot2()));
pMenu->exec(cursor().pos());
QList<QAction*>list=pMenu->actions();
foreach (QAction* pAction, list) {
delete pAction;
}
delete pMenu;
}
}
//實作恢複圖表初始化界面的功能
void precisionPaintDialog::recover_btn_plot1()
{
ui->widget_plot->xAxis->setRange(x1.first(),x1.last());
ui->widget_plot->yAxis->setRange(0,0.032);
ui->widget_plot->replot();
}
//實作儲存為圖輸出的功能
void precisionPaintDialog::save_jpg_btn_plot1()
{
//儲存的位置,如果不存在,則建立檔案夾
QString path=QCoreApplication::applicationDirPath()+"/SavePicture/precision";
QDir dir(path);
if(!dir.exists()){
dir.mkpath(path);
}
QString pathA = path +"/channelA_"+QTime::currentTime().toString().replace(":","")+".jpg";
//儲存為jps輸出,也可以儲存為bmp,pdf,png等格式輸出,相應的函數分别為saveBmp,savePdf,savePng。
if(ui->widget_plot->saveJpg(pathA)){
int click=QMessageBox::warning(this,"提示","圖檔已儲存!是否打開儲存目錄?",QMessageBox::Yes,QMessageBox::No);
//打開圖檔所在目錄的檔案夾
if(click==QMessageBox::Yes){
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}
}else{
QMessageBox::information(this,"提示","圖檔儲存失敗!");
}
}
//同上類似
void precisionPaintDialog::recover_btn_plot2()
{
ui->widget_plot_2->xAxis->setRange(x2.first(),x2.last());
ui->widget_plot_2->yAxis->setRange(0,0.032);
ui->widget_plot_2->replot();
}
//同上類似
void precisionPaintDialog::save_jpg_btn_plot2()
{
QString path=QCoreApplication::applicationDirPath()+"/SavePicture/precision";
QDir dir(path);
if(!dir.exists()){
dir.mkpath(path);
}
QString pathB = path +"/channelB_"+QTime::currentTime().toString().replace(":","")+".jpg";
if(ui->widget_plot->saveJpg(pathB)){
int click=QMessageBox::warning(this,"提示","圖檔已儲存!是否打開儲存目錄?",QMessageBox::Yes,QMessageBox::No);
if(click==QMessageBox::Yes){
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}
}else{
QMessageBox::information(this,"提示","圖檔儲存失敗!");
}
}
三、總結
實作了如下功能:
- 實作在一個dialog中使用多個qcustomplot提升的widget控件;
- 實作指定坐标軸的刻度的步長;
- 實作圖表的縮放,平移;
- 在右鍵添加多按鈕,實作圖表的恢複及輸出。