Мы пытаемся использовать 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](https://i.stack.imgur.com/NiJar.png)
На снимке выбран самый левый QCPLayoutElement
, а самый правый имеет фокус (будет выбран двойным щелчком).
Выделение / Фокус указывается простым рисованием прямоугольника вокруг QCPAxisRect
.
Теперь, есть ли способ добиться такого поведения?