Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ QCustomPlot与图形上的单个点交互_C++_Qt_Qcustomplot - Fatal编程技术网

C++ QCustomPlot与图形上的单个点交互

C++ QCustomPlot与图形上的单个点交互,c++,qt,qcustomplot,C++,Qt,Qcustomplot,我正在使用QCustomPlot并在屏幕上绘制多个图形,我希望能够单击并指向,然后能够获取我单击的点的数据或坐标等,我知道,使用QCP::iSelectPlottables可以对整个绘图本身执行此操作,但是否仅对单个点执行此操作,或者是否有人找到了解决方法来实现此操作。没有简单的方法可以做到这一点。至少在QCustomPlot中没有这样的功能 但您可以创建表示单个点的类(例如,从QCPItemEllipse派生)并用鼠标移动它 我的(尚未发布)软件中也有类似的功能,所以请查看并了解。。。它还可以

我正在使用
QCustomPlot
并在屏幕上绘制多个图形,我希望能够单击并指向,然后能够获取我单击的点的数据或坐标等,我知道,使用
QCP::iSelectPlottables
可以对整个绘图本身执行此操作,但是否仅对单个点执行此操作,或者是否有人找到了解决方法来实现此操作。

没有简单的方法可以做到这一点。至少在QCustomPlot中没有这样的功能

但您可以创建表示单个点的类(例如,从
QCPItemEllipse
派生)并用鼠标移动它

我的(尚未发布)软件中也有类似的功能,所以请查看并了解。。。它还可以使用shift修改器移动(仅更改初始位置的一个坐标)。另外,当光标移动到项目(以及它移动到的项目的边框)时,它会更改光标

plotpoint.h
类绘图点:公共QCPItemEllipse
{
Q_对象
公众:
显式绘图点(QCustomPlot*parentPlot,int-halfSize=5);
QPointF pos()常量;
常量QColor&color()常量;
void setColor(常量QColor和color);
无效开始移动(常数点和鼠标点,按下布尔移位键);
公众时段:
无效设置可见(布尔打开);
信号:
void activated();//<鼠标悬停时发出
void disactivated();//<光标离开时发出
无效移动(常量QPointF和pos);
无效停止移动();
公众时段:
无效移动(双x,双y,布尔信号需要=真);
无效移动px(双x,双y);
无效设置激活(bool isActive);
专用插槽:
MouseMove无效(QMouseEvent*事件);
void停止移动();
void moveToWantedPos();
换档状态更改时无效(布尔换档压力);
私人:
QCPItemTracer*mCenterTracer;
QPointF经理;
QPointF mInitialPos;
bool-mischangingonloyonecoordinal;
QList-mHelperItems;
QPointF mLastWantedPos;
QTimer*mMoveTimer;
QPointF mCurWantedPosPx;
};
plotpoint.cpp
PlotPoint::PlotPoint(QCustomPlot*parentPlot,int-halfSize)
:QCPItemEllipse(parentPlot)
,mCenterTracer(新的QCPItemTracer(父图))
,mgripdta()
,mInitialPos()
,mlastwandpos()
,mMoveTimer(新的QTimer(this))
,mCurWantedPosPx()
{
mCenterTracer->setStyle(QCPItemTracer::tsNone);
左上->设置父锚点(mCenterTracer->位置);
右下->设置父锚点(mCenterTracer->位置);
左上->设置类型(QCPItemPosition::ptAbsolute);
右下->设置类型(QCPItemPosition::ptAbsolute);
左上->设置坐标(-halfSize,-halfSize);
右下->设置坐标(半尺寸,半尺寸);
setSelectable(true);//绘图仅移动可选点,请参见绘图::mouseMoveEvent
setColor(QColor(qrand()%256,qrand()%256,qrand()%256,100));
setPen(QPen(Qt::黑色));
设置选择笔(QPen(Qt::黑色,3));
mMoveTimer->setInterval(25);/40fps
连接(mMoveTimer,SIGNAL(timeout()),此,插槽(moveToAnteDPOS());
}
QPointF PlotPoint::pos()常量
{
返回mCenterTracer->position->coords();
}
常量QColor&PlotPoint::color()常量
{
返回笔刷().color();
}
无效绘图点::设置颜色(常量QColor和颜色)
{
挫折感(颜色);
设置选定的笔刷(颜色);
}
无效绘图点::开始移动(常量QPointF和鼠标点,按下布尔移位)
{
setX(parentPlot()->xAxis->coordToPixel(mCenterTracer->position->key())-mousePos.x();
setY(parentPlot()->yAxis->coordToPixel(mCenterTracer->position->value())-mousePos.y();
mInitialPos=pos();
mLastWantedPos=小型LPOS;
mCurWantedPosPx=QPointF();
MISHANGINGONLYONECOCORMATION=移位按下;
mMoveTimer->start();
QCPItemStraightLine*水平=新的QCPItemStraightLine(parentPlot());
水平->设置抗锯齿(假);
水平->点1->设置坐标(mInitialPos.x(),mInitialPos.y());
水平->点2->设置坐标(mInitialPos.x()+1,mInitialPos.y());
parentPlot()->addItem(水平);
QCPItemStraightLine*垂直=新的QCPItemStraightLine(parentPlot());
垂直->设置抗锯齿(假);
垂直->点1->设置坐标(mInitialPos.x(),mInitialPos.y());
垂直->点2->设置坐标(mInitialPos.x(),mInitialPos.y()+1);
parentPlot()->addItem(垂直);
静态常量QPen linesPen(Qt::darkGray,0,Qt::DashLine);
水平->设置笔(linesPen);
垂直->设置笔(linesPen);
mHelpPeritems设置可见(假);
}
连接(parentPlot(),信号(mouseMove(QMouseEvent*)),
这个插槽(onMouseMove(QMouseEvent*));
连接(parentPlot(),信号(mouseRelease(QMouseEvent*)),
此,插槽(停止移动());
连接(parentPlot(),信号(shiftStateChanged(bool)),
这个插槽(onShift StateChanged(bool));
parentPlot()->grabKeyboard();
QApplication::setOverrideCursor(Qt::ClosedHandCursor);
}
无效打印点::设置可见(布尔打开)
{
setSelectable(on);//我们只有在可见时才可移动
QCPItemEllipse::setVisible(打开);
}
void PlotPoint::stopMoving()
{
断开连接(parentPlot(),信号(mouseMove(QMouseEvent*)),
这个插槽(onMouseMove(QMouseEvent*));
断开连接(parentPlot(),信号(mouseRelease(QMouseEvent*)),
此,插槽(停止移动());
断开连接(parentPlot(),信号(shiftStateChanged(bool)),
这个插槽(onShift StateChanged(bool));
mMoveTimer->stop();
移动到antedpos();
如果(!mHelpPerItems.isEmpty()){
而(!mHelperItems.isEmpty()){
QCPAbstractItem*item=mHelpPerItems.takeFirst();
mParentPlot->removeItem(项目);
}
mParentPlot->replot();
}
parentPlot()->releaseKeyboard();
QApplication::restoreOverrideCursor();
发射停止移动();
}
无效绘图点::移动(需要双x、双y、布尔信号)
{
MLASTWANTED位置设置x(x);
mLastWantedPos.setY(y);
if(MishangengOnlyoneCoordination){
双x1=parentPlot()->x
class PlotPoint : public QCPItemEllipse
{
    Q_OBJECT
public:
    explicit PlotPoint(QCustomPlot *parentPlot, int halfSize = 5);

    QPointF pos() const;
    const QColor &color() const;
    void setColor(const QColor &color);
    void startMoving(const QPointF &mousePos, bool shiftIsPressed);

public slots:
    void setVisible(bool on);

signals:
    void activated(); ///< emitted on mouse over
    void disactivated(); ///< emitted when cursor leave us

    void moved(const QPointF &pos);
    void stoppedMoving();

public slots:
    void move(double x, double y, bool signalNeeded = true);
    void movePx(double x, double y);
    void setActive(bool isActive);

private slots:
    void onMouseMove(QMouseEvent *event);
    void stopMoving();
    void moveToWantedPos();
    void onShiftStateChanged(bool shiftPressed);

private:
    QCPItemTracer *mCenterTracer;
    QPointF mGripDelta;
    QPointF mInitialPos;
    bool mIsChangingOnlyOneCoordinate;
    QList<QCPAbstractItem *> mHelperItems;
    QPointF mLastWantedPos;
    QTimer *mMoveTimer;
    QPointF mCurWantedPosPx;
};
PlotPoint::PlotPoint(QCustomPlot *parentPlot, int halfSize)
    : QCPItemEllipse(parentPlot)
    , mCenterTracer(new QCPItemTracer(parentPlot))
    , mGripDelta()
    , mInitialPos()
    , mLastWantedPos()
    , mMoveTimer(new QTimer(this))
    , mCurWantedPosPx()
{
    mCenterTracer->setStyle(QCPItemTracer::tsNone);

    topLeft->setParentAnchor(mCenterTracer->position);
    bottomRight->setParentAnchor(mCenterTracer->position);
    topLeft->setType(QCPItemPosition::ptAbsolute);
    bottomRight->setType(QCPItemPosition::ptAbsolute);

    topLeft->setCoords(-halfSize, -halfSize);
    bottomRight->setCoords(halfSize, halfSize);

    setSelectable(true); // plot moves only selectable points, see Plot::mouseMoveEvent
    setColor(QColor(qrand()%256, qrand()%256, qrand()%256, 100));
    setPen(QPen(Qt::black));
    setSelectedPen(QPen(Qt::black, 3));

    mMoveTimer->setInterval(25); // 40 FPS
    connect(mMoveTimer, SIGNAL(timeout()), this, SLOT(moveToWantedPos()));
}

QPointF PlotPoint::pos() const
{
    return mCenterTracer->position->coords();
}

const QColor &PlotPoint::color() const
{
    return brush().color();
}

void PlotPoint::setColor(const QColor& color)
{
    setBrush(color);
    setSelectedBrush(color);
}

void PlotPoint::startMoving(const QPointF &mousePos, bool shiftIsPressed)
{
    mGripDelta.setX(parentPlot()->xAxis->coordToPixel(mCenterTracer->position->key()) - mousePos.x());
    mGripDelta.setY(parentPlot()->yAxis->coordToPixel(mCenterTracer->position->value()) - mousePos.y());

    mInitialPos = pos();
    mLastWantedPos = mInitialPos;
    mCurWantedPosPx = QPointF();
    mIsChangingOnlyOneCoordinate = shiftIsPressed;

    mMoveTimer->start();

    QCPItemStraightLine *horizontal = new QCPItemStraightLine(parentPlot());
    horizontal->setAntialiased(false);
    horizontal->point1->setCoords(mInitialPos.x(), mInitialPos.y());
    horizontal->point2->setCoords(mInitialPos.x() + 1, mInitialPos.y());
    parentPlot()->addItem(horizontal);

    QCPItemStraightLine *vertical = new QCPItemStraightLine(parentPlot());
    vertical->setAntialiased(false);
    vertical->point1->setCoords(mInitialPos.x(), mInitialPos.y());
    vertical->point2->setCoords(mInitialPos.x(), mInitialPos.y() + 1);
    parentPlot()->addItem(vertical);

    static const QPen linesPen(Qt::darkGray, 0, Qt::DashLine);
    horizontal->setPen(linesPen);
    vertical->setPen(linesPen);

    mHelperItems << vertical << horizontal;

    if (!mIsChangingOnlyOneCoordinate) {
        vertical->setVisible(false);
        horizontal->setVisible(false);
    }

    connect(parentPlot(), SIGNAL(mouseMove(QMouseEvent*)),
            this, SLOT(onMouseMove(QMouseEvent*)));

    connect(parentPlot(), SIGNAL(mouseRelease(QMouseEvent*)),
            this, SLOT(stopMoving()));

    connect(parentPlot(), SIGNAL(shiftStateChanged(bool)),
            this, SLOT(onShiftStateChanged(bool)));

    parentPlot()->grabKeyboard();
    QApplication::setOverrideCursor(Qt::ClosedHandCursor);
}

void PlotPoint::setVisible(bool on)
{
    setSelectable(on);  // we are movable only when visible
    QCPItemEllipse::setVisible(on);
}

void PlotPoint::stopMoving()
{
    disconnect(parentPlot(), SIGNAL(mouseMove(QMouseEvent*)),
            this, SLOT(onMouseMove(QMouseEvent*)));

    disconnect(parentPlot(), SIGNAL(mouseRelease(QMouseEvent*)),
            this, SLOT(stopMoving()));

    disconnect(parentPlot(), SIGNAL(shiftStateChanged(bool)),
            this, SLOT(onShiftStateChanged(bool)));

    mMoveTimer->stop();
    moveToWantedPos();

    if (!mHelperItems.isEmpty()) {
        while (!mHelperItems.isEmpty()) {
            QCPAbstractItem *item = mHelperItems.takeFirst();
            mParentPlot->removeItem(item);
        }

        mParentPlot->replot();
    }

    parentPlot()->releaseKeyboard();
    QApplication::restoreOverrideCursor();

    emit stoppedMoving();
}

void PlotPoint::move(double x, double y, bool signalNeeded)
{
    mLastWantedPos.setX(x);
    mLastWantedPos.setY(y);
    if (mIsChangingOnlyOneCoordinate) {
        double x1 = parentPlot()->xAxis->coordToPixel(x);
        double x2 = parentPlot()->xAxis->coordToPixel(mInitialPos.x());
        double y1 = parentPlot()->yAxis->coordToPixel(y);
        double y2 = parentPlot()->yAxis->coordToPixel(mInitialPos.y());
        if (qAbs(x1 - x2) < qAbs(y1 - y2)) {
            x = mInitialPos.x();
        } else {
            y = mInitialPos.y();
        }
    }

    mCenterTracer->position->setCoords(x, y);

    parentPlot()->replot();

    if(signalNeeded) {
        emit moved(QPointF(x, y));
    }
}

void PlotPoint::movePx(double x, double y)
{
    move(parentPlot()->xAxis->pixelToCoord(x),
        parentPlot()->yAxis->pixelToCoord(y));
}

void PlotPoint::setActive(bool isActive)
{
    setSelected(isActive);
    emit (isActive ? activated() : disactivated());
}

void PlotPoint::onMouseMove(QMouseEvent *event)
{
    mCurWantedPosPx = QPointF(event->localPos().x() + mGripDelta.x(),
                              event->localPos().y() + mGripDelta.y());
}

void PlotPoint::moveToWantedPos()
{
    if (!mCurWantedPosPx.isNull()) {
        movePx(mCurWantedPosPx.x(), mCurWantedPosPx.y());
        mCurWantedPosPx = QPointF();
    }
}

void PlotPoint::onShiftStateChanged(bool shiftPressed)
{
    if (shiftPressed != mIsChangingOnlyOneCoordinate) {
        mIsChangingOnlyOneCoordinate = shiftPressed;
        foreach (QCPAbstractItem *item, mHelperItems) {
            item->setVisible(shiftPressed);
        }
        move(mLastWantedPos.x(), mLastWantedPos.y());
    }
}
void Plot::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && mPointUnderCursor) {
        mPointUnderCursor->startMoving(event->localPos(),
                                       event->modifiers().testFlag(Qt::ShiftModifier));
        return;
    }

    QCustomPlot::mousePressEvent(event);
}

void Plot::mouseMoveEvent(QMouseEvent *event)
{
    QCustomPlot::mouseMoveEvent(event);
    if (event->buttons() == Qt::NoButton) {
        PlotPoint *plotPoint = qobject_cast<PlotPoint*>(itemAt(event->localPos(), true));
        if (plotPoint != mPointUnderCursor) {
            if (mPointUnderCursor == NULL) {
                // cursor moved from empty space to item
                plotPoint->setActive(true);
                setCursor(Qt::OpenHandCursor);
            } else if (plotPoint == NULL) {
                // cursor move from item to empty space
                mPointUnderCursor->setActive(false);
                unsetCursor();
            } else {
                // cursor moved from item to item
                mPointUnderCursor->setActive(false);
                plotPoint->setActive(true);
            }
            mPointUnderCursor = plotPoint;
            replot();
        }
    }
}

void Plot::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Shift) {
        emit shiftStateChanged(true);
    }
    QCustomPlot::keyPressEvent(event);
}

void Plot::keyReleaseEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Shift) {
        emit shiftStateChanged(false);
    }
    QCustomPlot::keyReleaseEvent(event);
}