У меня есть QChart с несколькими QLineSeries.
Я создал свой собственный класс диаграммы CPlotView
, очищенный от QChartView, и переопределил mousePressEvent, mouseMoveEvent и mouseReleaseEvent, как показано ниже.
Я хочу реализовать и масштабирование с резиновой лентой, и выбор резиновой ленты по отдельности, и я могу выбрать, что делать, основываясь на проверяемых QPushButtons (код не показан, но это просто элемент CPlotView, который содержит значение перечисления, которое определяет, в каком «режиме» он находится (Zoom или Select)
void CPlotView::mousePressEvent(QMouseEvent *event)
{
if(PlotRubberBand)
{
if (PlotCursorMode == ECursorMode::eIsolate || PlotCursorMode == ECursorMode::eZoom)
{
QRectF plotArea = chart()->plotArea();
if (PlotRubberBand->isEnabled()
&& event->button() == Qt::LeftButton
&& plotArea.contains(event->pos()))
{
DrawRubberBand = true;
PlotRubberBandOrigin = event->pos();
PlotRubberBand->setVisible(true);
PlotRubberBand->setGeometry(QRect(PlotRubberBandOrigin, QSize()));
event->accept();
}
QGraphicsView::mousePressEvent(event);
}
else
{
QChartView::mousePressEvent(event);
}
}
QChartView::mousePressEvent(event);
}
void CPlotView::mouseMoveEvent(QMouseEvent *event)
{
if (GetPlotCursorMode() == ECursorMode::eIsolate)
{
if (DrawRubberBand && PlotRubberBand->isVisible())
{
QRect rect = chart()->plotArea().toRect();
int width = event->pos().x() - PlotRubberBandOrigin.x();
int height = event->pos().y() - PlotRubberBandOrigin.y();
PlotRubberBand->setGeometry(QRect(PlotRubberBandOrigin.x(), PlotRubberBandOrigin.y(), width, height).normalized());
}
else
{
QGraphicsView::mouseMoveEvent(event);
}
}
else if (GetPlotCursorMode() == ECursorMode::eZoom)
{
if (DrawRubberBand && PlotRubberBand->isVisible())
{
QChartView::mouseMoveEvent(event);
}
else
{
QGraphicsView::mouseMoveEvent(event);
}
}
else if (GetPlotCursorMode() == ECursorMode::eSelect)
{
QGraphicsView::mouseMoveEvent(event);
}
else
{
QChartView::mouseMoveEvent(event);
}
}
void CPlotView::mouseReleaseEvent(QMouseEvent *event)
{
if (PlotRubberBand->isVisible())
{
if (PlotCursorMode == ECursorMode::eIsolate)
{
DrawRubberBand = false;
PlotRubberBand->setVisible(false);
QGraphicsView::mouseReleaseEvent(event);
QList<QGraphicsItem *> selected_items = QGraphicsView::items(PlotRubberBand->rect(), Qt::IntersectsItemShape);
qDebug() << "found " << selected_items.size() << " items"; // this appears to show a number of items, but how do I detect which items are my data series, if any are?
for (auto& item : selected_items)
{
// detect which are my data series and highlight them as selected
}
}
else
{
DrawRubberBand = false;
PlotRubberBand->setVisible(false);
QChartView::mouseReleaseEvent(event);
}
}
}
Теперь у меня работает режим масштабирования - нажатие кнопки режима масштабирования, затем перетаскивание резиновой ленты на графике увеличивает масштаб в этой области. Нажатие кнопки выбора режима рисует резинку, ноне изменяет масштаб. Теперь я хочу выбрать все серии данных в резиновой ленте в режиме выбора.
В mouseReleaseEvent
в режиме выбора я пытаюсь захватить все выбранные QGraphicsItems
внутри прямоугольника резиновой ленты (IЯ надеюсь, что это то, что возвращает QGraphicsView::items(PlotRubberBand->rect(), Qt::IntersectsItemShape);
), но я не знаю, как определить мой ряд данных(У меня на самом деле есть смесь QLineSeries и QScatterSeries.
Есть некоторые QGraphicsItems
, возвращаемые QGraphicsView::items(PlotRubberBand->rect(), Qt::IntersectsItemShape);
, даже когда я не пересекаю резинку с какими-либо из моих данных, поэтому она, очевидно, возвращает некоторые другиепредметы на сцене.
Я пытался сделать dynamic_cast
того, что возвращается QGraphicsView::items
в QLineSeries
, но это не сработало.Я не могу помочь, но думаю, что я делаю это более сложным, чем это должно быть.
ОБНОВЛЕНИЕ 1: Я также пытался захватывать сигналы, запускаемые при наведении курсора мыши на ряд данных во времярезиновая полоса выбирается с помощью:
connect(line_series, SIGNAL(hovered(const QPointF &, bool)), this, SLOT(OnDataHovered(const QPointF&, bool)));
, но сигнал не срабатывает при перетаскивании резиновой ленты (возможно, когда левая кнопка мыши нажата, она не срабатывает?).: (
ОБНОВЛЕНИЕ 2: Я попытался установить selectionArea в вызове mouseReleaseEvent (), и, опять же, некоторые из них возвращаются как выбранные, гораздо меньше, чем вызов QGraphicsView::items()
, но немоя серия, насколько я могу судить:
void ewbearinghistorychart::CEwBearingHistoryChartView::mouseReleaseEvent(QMouseEvent *event)
{
if (PlotRubberBand->isVisible())
{
if (PlotCursorMode == ECursorMode::eIsolate)
{
DrawRubberBand = false;
PlotRubberBand->setVisible(false);
QRect rubberband_rect = PlotRubberBand->rect();
QGraphicsView::mouseReleaseEvent(event);
// ************** new code **************
QPolygonF p = chart()->mapToScene(PlotRubberBand->rect().normalized());
QPainterPath path;
path.addPolygon(p);
chart()->scene()->setSelectionArea(path, Qt::IntersectsItemShape);
QList<QGraphicsItem *> selected_items = chart()->scene()->selectedItems();
qDebug() << "selected items: " << selected_items.size();
// ************** /new code **************
}
else
{
DrawRubberBand = false;
PlotRubberBand->setVisible(false);
QChartView::mouseReleaseEvent(event);
}
}
}