继承qcustomplot自定义了一个类,该类包含游标和标签,想要实现功能:
点击曲线上某点,对该点作标记(游标和标签一直显示),再次点击该点,标记消失(游标和标签隐藏)。
目前标记功能已实现,取消标记的思路是:
再次点击标记点,触发自定义类的鼠标点击事件,进行游标和标签的隐藏。
问题是:
再次点击标记点,无法进入鼠标点击事件。后经测试发现,任何鼠标事件都无法进入,如何解决?
同时望分享更好的解决思路。
代码如下:
自定义类:
MyQCPItemTracer::MyQCPItemTracer(QCustomPlot *parent) : QCustomPlot(parent)
{
//*******
//生成游标
tracer = new QCPItemTracer(parent);
tracer->setPen(QPen(Qt::white));//圆圈轮廓颜色
tracer->setBrush(QBrush(Qt::black));//圆圈圈内颜色
tracer->setStyle(QCPItemTracer::tsCircle);//圆圈
tracer->setSize(8);//设置大小
//******
//游标说明
tracerLabel = new QCPItemText(parent); //生成游标说明
tracerLabel->setLayer("overlay");//设置图层为overlay,因为需要频繁刷新
tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop);//左上
tracerLabel->position->setParentAnchor(tracer->position);//将游标说明锚固在tracer位置处,实现自动跟随
QFont font;
font.setBold(1);
font.setFamily("微软雅黑");
font.setPointSize(10);
tracerLabel->setFont(font);
tracerLabel->setColor(QColor(22, 161, 255));
tracerLabel->setBrush(QColor(250,250,255));
tracerLabel->setPadding(QMargins(3,3,3,3));
tracerLabel->setPen(QPen(QColor(130, 130, 130), 1, Qt::DotLine));//设置游标说明颜色
qDebug()<<tr("new a pair ");
}
以下两个事件均无法进入:
void MyQCPItemTracer::mousePressEvent(QMouseEvent *e)
{
//QCustomPlot::mousePressEvent(e);//父类的函数
tracer->setVisible(0);
tracerLabel->setVisible(0);
qDebug()<<tr("hide a pair ");
}
void MyQCPItemTracer::mouseMoveEvent(QMouseEvent *e)
{
qDebug()<<tr("hide a pair ");
}
MyQCustomPlot:
void MyQCustomPlot::mouseTracetoCoord(QMouseEvent *e)
{
//获取鼠标坐标点
QPointF ChickedPoint;
ChickedPoint = e->pos();
//myTracer->tracer->setVisible(1);
//排除区间外点
if(this->viewport().contains(e->pos()))
{
//鼠标点击的后位置转换到下坐标轴对应坐标
double current_Rx = this->xAxis->pixelToCoord(ChickedPoint.x());
double current_Ry = this->yAxis->pixelToCoord(ChickedPoint.y());
//获取实部y轴的显示范围
double y_range = (this->yAxis->range().size()) / 100;
double x_range = (this->xAxis->range().size()) / 50;
//myTracer->tracer->setVisible(1);
if(!yData.empty())
{
for(int i = 0; i < yData.size(); i++)//对我的数据集进行遍历
{
if((abs(current_Ry - yData.at(i)) <= y_range) && (abs(current_Rx - xData.at(i)) <= x_range))
{
myTracer->tracerLabel->setVisible(1);
myTracer->tracerLabel->position->setCoords(xData.at(i),yData.at(i));//标签绘图位置在曲线上
QString strText;
strText = "X %1\nY %2";
myTracer->tracerLabel->setText(strText.arg(xData.at(i)).arg(yData.at(i)));//设置游标说明内容
emit sig_sendDisplayMark(current_Rx,current_Ry,xData.at(i),yData.at(i));
break;
}
}
this->replot();
}
}
else return;
}
void MyQCustomPlot::slot_displayMark(double current_Rx, double current_Ry, double actualX, double actualY)
{
MyQCPItemTracer *disMyTrace = new MyQCPItemTracer(this);
disMyTrace->tracer->position->setCoords(actualX,actualX);
disMyTrace->tracer->setVisible(1);
QString strTextTemp;
strTextTemp = "X %1\nY %2";
disMyTrace->tracerLabel->setText(strTextTemp.arg(actualX).arg(actualX));//设置游标说明内容
disMyTrace->tracerLabel->position->setCoords(actualX,actualY);//标签绘图位置在曲线上
disMyTrace->tracerLabel->setVisible(1);
}
MyQCPItemTracer
派生于QCustomPlot
,在构造函数里它的两个成员tracer
和tracerLabel
的父对象设的是parent,因此这两个成员其实和MyQCPItemTracer
没啥关系。如果鼠标点击tracer
,而tracer
默认没有处理该事件,该事件进而传递给其父对象,但是tracer
的父对象并不是MyQCPItemTracer
,因此它也就收不到鼠标点击事件。其实你的程序里MyQCPItemTracer
完全是多余,你应该把tracer
和tracerLabel
直接添加到MyQCustomPlot
类中,一开始它们是隐藏的。第一次点击时显示它们在鼠标点击的位置,第二次点击它们,隐藏它们。你可以在MyQCustomPlot
通过installEventFilter()
监听tracer
的事件来捕捉点击事件。也可以试试QCPAbstractItem::selectionChanged()
的消息