QCustomPlot的使用之四-响应鼠标移动和弹起事件
在项目中使用QCustomPlot过程中,会有新的需求需要满足,比如在显示的数据表格中,鼠标移动到数据线上的时候,需要实时显示当前显示的线上点的具体数据;点击这条线的时候,弹出对话框展现出数据线段的详细信息。解决思路:在不改变QCustomPlot的前提下,在其外层封装一层类,使其外层实现相应的功能。需要到的类图继续关系图:先看实现的效果:首先要找到QCustomPlot的相应的鼠标信...
在项目中使用QCustomPlot过程中,会有新的需求需要满足,比如在显示的数据表格中,鼠标移动到数据线上的时候,需要实时显示当前显示的线上点的具体数据;点击这条线的时候,弹出对话框展现出数据线段的详细信息。
解决思路:在不改变QCustomPlot的前提下,在其外层封装一层类,使其外层实现相应的功能。
需要到的类图继续关系图:
先看实现的效果:
首先要找到QCustomPlot的相应的鼠标信息:鼠标移动和鼠标弹起。
void QCustomPlot::mouseMoveEvent(QMouseEvent *event) {
emit mouseMove(event);
if (!mMouseHasMoved && (mMousePressPos - event->pos()).manhattanLength() > 3)
mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release
if (mSelectionRect && mSelectionRect->isActive())
mSelectionRect->moveSelection(event);
else if (mMouseEventLayerable) // call event of affected layerable:
mMouseEventLayerable->mouseMoveEvent(event, mMousePressPos);
event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event.
}
void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) {
emit mouseRelease(event);
if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click
{
if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here
mSelectionRect->cancel();
if (event->button() == Qt::LeftButton)
processPointSelection(event);
...
在鼠标弹起事情中可以看到,当按键书鼠标左键的时候调用函数
processPointSelection(event);
然后看看这个函数的定义:
void QCustomPlot::processPointSelection(QMouseEvent *event) {
QVariant details;
QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details);
...
通过调用layerableAt(event->pos(), true, &details);来获取当前鼠标选中的是哪个图层,返回值就是选中的图层。既然已经找到了选中的图层,剩下的就是做出相应判断了,但是咱们的前提是不能在文件中修改,所用需要重新定义一个新类继承自QCustomPlot;
class MYCUSTOMPLOT_EXPORT MyCustomPlot :public QCustomPlot {
public:
MyCustomPlot();
//注册鼠标操作
void registerMouse(IPlotMouse* mouse);
private:
virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
private:
IPlotMouse* _mousePlot = nullptr;
};
MyCustomPlot::MyCustomPlot()
:QCustomPlot(nullptr) {
}
void MyCustomPlot::registerMouse(IPlotMouse* mouse) {
_mousePlot = mouse;
}
void MyCustomPlot::mousePressEvent(QMouseEvent *event) {
QCustomPlot::mousePressEvent(event);
}
void MyCustomPlot::mouseMoveEvent(QMouseEvent *event) {
QCustomPlot::mouseMoveEvent(event);
QVariant details;
QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details);
if (clickedLayerable != nullptr) {
double xValue = 0.0;
double yValue = 0.0;
if (dynamic_cast<QCPGraph*>(clickedLayerable) != 0) {
((QCPGraph*)clickedLayerable)->pixelsToCoords(event->pos(), xValue, yValue);
if (_mousePlot != nullptr){
_mousePlot->plotMouseMove(event->pos().x(), event->pos().y(), xValue, yValue, (QCPGraph*)clickedLayerable);
}
}
}
}
void MyCustomPlot::mouseReleaseEvent(QMouseEvent *event) {
QCustomPlot::mouseReleaseEvent(event);
if (event->button() == Qt::LeftButton) {
QVariant details;
QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details);
if (clickedLayerable != nullptr) {
double xValue = 0.0;
double yValue = 0.0;
if (dynamic_cast<QCPGraph*>(clickedLayerable) != 0) {
((QCPGraph*)clickedLayerable)->pixelsToCoords(event->pos(), xValue, yValue);
if (_mousePlot != nullptr) {
_mousePlot->plotMouseRelease(event->pos().x(), event->pos().y(), xValue, yValue, (QCPGraph*)clickedLayerable);
}
}
}
}
}
新类已经定义完了,新类中同样也需要实现鼠标事情:
virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
在实现自定义类的鼠标函数中,首先要调用QCustomPlot中的鼠标函数,之后才可以实现自己新添加的功能。
在新添加的类中,注册了一个新的接口,这个接口用来对外通信的。比如我想让其他的界面响应鼠标事件,就需要其他的界面来继承这个接口并且实现相应的接口函数。如果不要相应那就不用调用下面这个注册函数就可以了
//注册鼠标操作
void registerMouse(IPlotMouse* mouse);
注册接口:
_horRightAnglePlot = new /*QCustomPlot*/MyCustomPlot;
_horRightAnglePlot->registerMouse(this);
实现接口响应:
void RadarDirectGraph::plotMouseRelease(double xPixel, double yPixel, double xValue, double yValue, void*graph) {
QtGuiDirectDetail* guiDetail = new QtGuiDirectDetail;
guiDetail->show();
}
void RadarDirectGraph::plotMouseMove(double xPixel, double yPixel, double xValue, double yValue, void*graph) {
QString msg = QStringLiteral("(%1:%2)").arg(xValue).arg(yValue);
QToolTip::showText(QCursor::pos(), msg);
}
aaa
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)