QQuickPaintedItem和QwtPlotPicker:如何强制它们一起工作

时间:2018-03-24 06:27:04

标签: c++ qt qml qtquick2 qwt

继承了QQuickPaintedItem并包含QwtPlot的类(为了在QML中使用它):

class QmlQwtPlot : public QQuickPaintedItem
{
    Q_OBJECT

public:
    QmlQwtPlot(QQuickItem* parent = 0);
    ~QmlQwtPlot();

    void paint(QPainter *painter) override;

    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent* event) override;
    void mouseReleaseEvent(QMouseEvent* event) override;
    void wheelEvent(QWheelEvent *event) override;

private:
    QwtPlot* qwtPlot;
    QwtPlotPanner* panner;
    bool isDragging;
    QPoint previousPosition;
    QwtPlotPicker* picker;
};

例如,通过使用鼠标事件处理和QwtPlotPanner信号实现平移绘图:

void QmlQwtPlot::mouseMoveEvent(QMouseEvent* event) {
    if (isDragging) {  // if the mouse button has been pressed
        QPoint currentPosition = event->pos();
        QPoint diff = currentPosition - previousPosition;
        emit panner->panned(diff.x(),diff.y());
        previousPosition = event->pos();
        update();
    }
}

QwtPlotPicker是一个Qwt库类,可在绘图画布上提供选择。使用QwtPlotPicker QWidget效果很好(带有x,y坐标的光标和带光标的交叉线)QQuickPaintedItem,但它不能与/* QWidget's child constructor (the same is in QQuickPaintedItem's one) */ PlottingWidget::PlottingWidget(QWidget *parent) : QWidget(parent) { // ... d_picker = new QwtPlotPicker( QwtPlot::xBottom, QwtPlot::yLeft, QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn, plot->canvas() ); d_picker->setRubberBandPen( QColor( Qt::red ) ); d_picker->setTrackerPen( QColor( Qt::black ) ); d_picker->setStateMachine( new QwtPickerTrackerMachine() ); // ... } 一起使用不同的工作原则。

QwtPlotPicker

如何强制QQuickPaintedItem使用public class MapRipple { private GoogleMap mGoogleMap; private LatLng mLatLng, mPrevLatLng; private BitmapDescriptor mBackgroundImageDescriptor; private float mTransparency = 0.5f; private volatile double mDistance = 100; private int mNumberOfRipples = 1; private int mFillColor = Color.TRANSPARENT; private int mStrokeColor = Color.BLACK; private int mStrokeWidth = 5; private long mDurationBetweenTwoRipples = 1000; private long mRippleDuration = 2000; private ValueAnimator mAnimators[]; private Handler mHandlers[]; private GroundOverlay mGroundOverlays[]; private GradientDrawable mBackground; private boolean isAnimationRunning = false; public MapRipple(GoogleMap googleMap, LatLng latLng, Context context) { mGoogleMap = googleMap; mLatLng = latLng; mPrevLatLng = latLng; mBackground = (GradientDrawable) ContextCompat.getDrawable(context, R.drawable.map_background); mAnimators = new ValueAnimator[4]; mHandlers = new Handler[4]; mGroundOverlays = new GroundOverlay[4]; } public MapRipple withTransparency(float transparency) { mTransparency = transparency; return this; } public MapRipple withDistance(double distance) { mDistance = distance; return this; } public MapRipple withLatLng(LatLng latLng) { mPrevLatLng = mLatLng; mLatLng = latLng; return this; } public MapRipple withNumberOfRipples(int numberOfRipples) { if (numberOfRipples > 4 || numberOfRipples < 1) { numberOfRipples = 4; } mNumberOfRipples = numberOfRipples; return this; } public MapRipple withFillColor(int fillColor) { mFillColor = fillColor; return this; } public MapRipple withStrokeColor(int strokeColor) { mStrokeColor = strokeColor; return this; } @Deprecated public void withStrokewidth(int strokeWidth) { mStrokeWidth = strokeWidth; } public MapRipple withStrokeWidth(int strokeWidth) { mStrokeWidth = strokeWidth; return this; } public MapRipple withDurationBetweenTwoRipples(long durationBetweenTwoRipples) { mDurationBetweenTwoRipples = durationBetweenTwoRipples; return this; } public boolean isAnimationRunning() { return isAnimationRunning; } public MapRipple withRippleDuration(long rippleDuration) { mRippleDuration = rippleDuration; return this; } private final Runnable mCircleOneRunnable = new Runnable() { @Override public void run() { mGroundOverlays[0] = mGoogleMap.addGroundOverlay(new GroundOverlayOptions() .position(mLatLng, (int) mDistance) .transparency(mTransparency) .image(mBackgroundImageDescriptor)); startAnimation(0); } }; private final Runnable mCircleTwoRunnable = new Runnable() { @Override public void run() { mGroundOverlays[1] = mGoogleMap.addGroundOverlay(new GroundOverlayOptions() .position(mLatLng, (int) mDistance) .transparency(mTransparency) .image(mBackgroundImageDescriptor)); startAnimation(1); } }; private final Runnable mCircleThreeRunnable = new Runnable() { @Override public void run() { mGroundOverlays[2] = mGoogleMap.addGroundOverlay(new GroundOverlayOptions() .position(mLatLng, (int) mDistance) .transparency(mTransparency) .image(mBackgroundImageDescriptor)); startAnimation(2); } }; private final Runnable mCircleFourRunnable = new Runnable() { @Override public void run() { mGroundOverlays[3] = mGoogleMap.addGroundOverlay(new GroundOverlayOptions() .position(mLatLng, (int) mDistance) .transparency(mTransparency) .image(mBackgroundImageDescriptor)); startAnimation(3); } }; private void startAnimation(final int numberOfRipple) { ValueAnimator animator = ValueAnimator.ofInt(0, (int) mDistance); animator.setRepeatCount(ValueAnimator.INFINITE); animator.setRepeatMode(ValueAnimator.RESTART); animator.setDuration(mRippleDuration); animator.setEvaluator(new IntEvaluator()); animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { int animated = (int) valueAnimator.getAnimatedValue(); mGroundOverlays[numberOfRipple].setDimensions(animated); if (mDistance - animated <= 10) { if (mLatLng != mPrevLatLng) { mGroundOverlays[numberOfRipple].setPosition(mLatLng); } } } }); animator.start(); mAnimators[numberOfRipple] = animator; } private void setDrawableAndBitmap() { mBackground.setColor(mFillColor); mBackground.setStroke(UiUtil.dpToPx(mStrokeWidth), mStrokeColor); mBackgroundImageDescriptor = UiUtil.drawableToBitmapDescriptor(mBackground); } public void stopRippleMapAnimation() { if (isAnimationRunning) { try { for (int i = 0; i < mNumberOfRipples; i++) { if (i == 0) { mHandlers[i].removeCallbacks(mCircleOneRunnable); mAnimators[i].cancel(); mGroundOverlays[i].remove(); } if (i == 1) { mHandlers[i].removeCallbacks(mCircleTwoRunnable); mAnimators[i].cancel(); mGroundOverlays[i].remove(); } if (i == 2) { mHandlers[i].removeCallbacks(mCircleThreeRunnable); mAnimators[i].cancel(); mGroundOverlays[i].remove(); } if (i == 3) { mHandlers[i].removeCallbacks(mCircleFourRunnable); mAnimators[i].cancel(); mGroundOverlays[i].remove(); } } } catch (Exception e) { //no need to handle it } } isAnimationRunning = false; } public void startRippleMapAnimation() { if (!isAnimationRunning) { setDrawableAndBitmap(); for (int i = 0; i < mNumberOfRipples; i++) { if (i == 0) { mHandlers[i] = new Handler(); mHandlers[i].postDelayed(mCircleOneRunnable, mDurationBetweenTwoRipples * i); } if (i == 1) { mHandlers[i] = new Handler(); mHandlers[i].postDelayed(mCircleTwoRunnable, mDurationBetweenTwoRipples * i); } if (i == 2) { mHandlers[i] = new Handler(); mHandlers[i].postDelayed(mCircleThreeRunnable, mDurationBetweenTwoRipples * i); } if (i == 3) { mHandlers[i] = new Handler(); mHandlers[i].postDelayed(mCircleFourRunnable, mDurationBetweenTwoRipples * i); } } } isAnimationRunning = true; } }

0 个答案:

没有答案