Выбор чертежа и прямоугольники фокуса вокруг QCPAxisRect - PullRequest
0 голосов
/ 04 марта 2019

Мы пытаемся использовать QCustomPlot для настройки нашего внутреннего инструмента сравнения.Фреймворк довольно приятный и простой в использовании.

Теперь на одном графике часто располагаются несколько QCPAxisRect, аккуратно расположенных, чтобы пользователь мог сравнивать разные кривые.

Для интерактивной настройки свойств QCPAxisRect пользователь должен интерактивновыберите их прямо в виджете QCustomPlot.Это легко сделать с помощью функции axisRectAt.

А теперь наступает момент, который мне не удалось решить.Я просто хотел отобразить текущее выделение внутри QCustomPlot, нарисовав простой прямоугольник вокруг выделенного элемента.Я хотел использовать QCPItemRect для этой цели, но я не смог заставить его работать.(Особенно он вырезан внутри QCPAxisRect, но я хотел нарисовать прямоугольник снаружи.)

Самое близкое, что я мог получить, было следующее решение, которое просто меняет цвет фона моего QCPAxisRect.Мне действительно не нравится это решение, так как пользователь раздражается, и его / ее стили кривой могут быть более невидимыми.

PlotWidget.h

#pragma once

#include <QWidget>
#include "ifmQCustomPlot/qcustomplot.h"

class PlotWidget : public QWidget {
    Q_OBJECT

public:
    PlotWidget(QWidget* parent=nullptr);
private:
    QCustomPlot* mPlot{ nullptr };

private:
    QString mCurrentSelection;
};

PlotWidget.cpp

#include "PlotWidget.h"
#include <QVBoxLayout>
#include <QDebug>

PlotWidget::PlotWidget(QWidget* parent/*=nullptr*/) : QWidget(parent)
{
    mPlot = new QCustomPlot;
    resize(3*400, 400);
    setLayout(new QVBoxLayout);
    layout()->addWidget(mPlot);
    auto layout = mPlot->plotLayout();
    layout->clear();
    auto rect1 = new QCPAxisRect(mPlot);
    rect1->setObjectName("R1");
    auto rect2 = new QCPAxisRect(mPlot);
    rect2->setObjectName("R2");
    auto rect3 = new QCPAxisRect(mPlot);
    rect3->setObjectName("R3");
    layout->setColumnSpacing(20);
    layout->addElement(rect1);
    layout->addElement(rect2);
    layout->addElement(rect3);

    mPlot->rescaleAxes();
    mPlot->replot(QCustomPlot::rpImmediateRefresh);
    connect(mPlot, &QCustomPlot::mouseMove, [this](auto event ) {
        QBrush noSelectionBrush(QColor("#00ffffff"));
        QBrush hasFocusBrush(QBrush(QColor("#ff00ff80")));
        QBrush isSelectedBrush(QBrush(QColor("#ff000080")));

        for (auto iter : mPlot->axisRects()) {
            iter->setBackground(noSelectionBrush); // Transparent
        }

        if (auto rect = mPlot->axisRectAt(event->pos())) {
            rect->setBackground(hasFocusBrush);
        }
        auto children = mPlot->findChildren<QCPAxisRect*>(mCurrentSelection);
        if (children.size()==1) {
            children[0]->setBackground(isSelectedBrush);
        }
        mPlot->replot(QCustomPlot::rpImmediateRefresh);
    });
    connect(mPlot, &QCustomPlot::mouseDoubleClick, [this](auto event) {
        QBrush noSelectionBrush(QColor("#00ffffff"));
        QBrush hasFocusBrush(QBrush(QColor("#ff00ff80")));
        QBrush isSelectedBrush(QBrush(QColor("#ff000080")));

        for (auto iter : mPlot->axisRects()) {
            iter->setBackground(noSelectionBrush);
        }

        if (auto rect = mPlot->axisRectAt(event->pos())) {
            rect->setBackground(isSelectedBrush);
            mCurrentSelection = rect->objectName();
        }
        else {
            mCurrentSelection = "";
        }
        mPlot->replot(QCustomPlot::rpImmediateRefresh);
    });
}

main.cpp

#include <QApplication>
#include "PlotWidget.h"

int main(int argc, char** args) {
    QApplication app(argc, args);
    auto w = new PlotWidget;
    w->show();
    app.exec();
}

То, что я хотел, выглядит примерно так:

Desired Selection Behavior

На снимке выбран самый левый QCPLayoutElement, а самый правый имеет фокус (будет выбран двойным щелчком).

Выделение / Фокус указывается простым рисованием прямоугольника вокруг QCPAxisRect.

Теперь, есть ли способ добиться такого поведения?

...