效果图如下
概述
QCustomPlot版本为2.0.1,瀑布图上一篇文章已经详细介绍了,不懂的可以看这里:Qt 画瀑布图,热力图,雨图 ,这篇文章主要介绍如何设置游标,并使用双游标方式选取一段数据。
最终实现功能:
1.鼠标单击生成游标(两个游标在一起),并随着鼠标移动而移动。
2.鼠标双击固定第一个游标,第二个游标仍可随着鼠标移动而移动。
3.鼠标再次双击固定第二个游标。
4.起始,结束编辑框分别显示第一个游标和第二个游标的位置信息。
开始
头文件添加两个游标对象,画图函数和三个鼠标点击,双击,移动槽函数如下:
class CursorDialog : public QDialog
{
Q_OBJECT
public:
explicit CursorDialog(QWidget *parent = nullptr);
~CursorDialog();
void PlotWaterfall(QCustomPlot* customPlot);
QCustomPlot* customPlot;
QCPColorMap* cpColorMap;
QCPItemTracer* tracer1;
QCPItemTracer* tracer2;
bool bTracer1;
bool bTracer2;
private slots:
void mousePress(QMouseEvent* e);
void mouseDoubleClick(QMouseEvent* e);
void mouseMove(QMouseEvent *e);
private:
Ui::CursorDialog *ui;
};
构造函数中初始化变量,链接信号和槽函数
CursorDialog::CursorDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::CursorDialog)
{
ui->setupUi(this);
ui->lineEditStart->setText("0");
ui->lineEditEnd->setText("0");
customPlot = ui->widget;
PlotWaterfall(customPlot);
bTracer1 = false;
bTracer2 = false;
//信号连接槽函数
connect(customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress(QMouseEvent*)));
connect(customPlot, SIGNAL(mouseDoubleClick(QMouseEvent*)), this, SLOT(mouseDoubleClick(QMouseEvent*)));
connect(customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMove(QMouseEvent*)));
}
画图函数PlotWaterfall(QCustomPlot* customPlot)中初始化两个游标
//构造游标1
tracer1 = new QCPItemTracer(customPlot);
tracer1->setPen(QPen(Qt::SolidLine)); //实线游标
tracer1->setStyle(QCPItemTracer::tsCrosshair);//十字星线
tracer1->setSize(2.0);
tracer1->setVisible(false);
//构建游标2
tracer2 = new QCPItemTracer(customPlot);
tracer2->setPen(QPen(Qt::SolidLine)); //实线游标
tracer2->setStyle(QCPItemTracer::tsCrosshair);//十字星线
tracer2->setSize(2.0);
tracer2->setVisible(false);
鼠标单击事件的函数实现如下:
/**
* @brief 鼠标点击事件
* @param e
*/
int clickNum = 0; //用于判断是偶数双击还是单数双击
void CursorDialog::mousePress(QMouseEvent* e)
{
QCustomPlot *curCustomPlot = qobject_cast<QCustomPlot *>(sender());
if(curCustomPlot == customPlot)
{
if(e->button() == Qt::LeftButton)
{
bTracer1 = true;
tracer1->setVisible(true);
bTracer2 = true;
tracer2->setVisible(true);
}
if(e->button() == Qt::RightButton)
{
bTracer1 = false;
tracer1->setVisible(false);
bTracer2 = false;
tracer2->setVisible(false);
clickNum = 0;
}
curCustomPlot->replot();
}
}
鼠标双击事件的实现代码如下:
/**
* @brief 鼠标双击事件
* @param e
*/
void CursorDialog::mouseDoubleClick(QMouseEvent* e)
{
QCustomPlot *curCustomPlot = qobject_cast<QCustomPlot *>(sender());
if(curCustomPlot == customPlot)
{
if(clickNum%2 == 0)
{
bTracer1 = false;
tracer1->setVisible(true);
}
else
{
bTracer2 = false;
tracer2->setVisible(true);
bTracer1 = false; //双击时会先触发单击事件,单击时会把bTracer1置为true,所以这里重新设置为false
}
clickNum++;
}
}
鼠标移动的槽函数实现代码如下:
/**
* @brief 鼠标移动事件
* @param e
*/
void CursorDialog::mouseMove(QMouseEvent *e)
{
QCustomPlot *curCustomPlot = qobject_cast<QCustomPlot *>(sender());
if(curCustomPlot == customPlot)
{
if(bTracer1)
{
int x = curCustomPlot->xAxis->pixelToCoord(e->pos().x());
int pos = x;
if(pos < 0)
{
return ;
}
qDebug() << "POS:" << pos;
tracer1->position->setCoords(pos, 0);
tracer1->setVisible(true);
curCustomPlot->replot();
ui->lineEditStart->setText(QString("%1").arg(x));
}
if(bTracer2)
{
int x = curCustomPlot->xAxis->pixelToCoord(e->pos().x());
int pos = x;
if(pos < 0)
{
return ;
}
tracer2->position->setCoords(pos, 0);
tracer2->setVisible(true);
curCustomPlot->replot();
ui->lineEditEnd->setText(QString("%1").arg(x));
}
}
}
启动程序后可实现单击生成游标,第一次双击固定起始游标,第二次双击固定第二个游标。
有疑问的可以直接后去源码:https://github.com/woniu201/qt-examples/tree/master/qcustomplot-example