我有一个QChart,上面有一些QLineSeries。
我已经创建了我自己的图表类CPlotView,它是从QChartView模拟出来的,并且重写了mousePressEvent、mouseMoveEvent和mouseReleaseEvent,如下所示。
我想分别实现橡皮筋缩放和橡皮筋选择,我可以根据可校验的QPushButtons (代码未显示,但它只是CPlotView的一个成员)选择要做的事情,该成员持有一个枚举值,该值定义了its的“模式”(缩放或选择)。
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中,我试图捕获橡皮筋rect中所有选定的QGraphicsItems (我希望这是QGraphicsView::items(PlotRubberBand->rect(), Qt::IntersectsItemShape);返回的内容),但我不知道如何检测数据序列(实际上是QLineSeries和QScatterSeries的混合体)。
有些QGraphicsItems是由QGraphicsView::items(PlotRubberBand->rect(), Qt::IntersectsItemShape);返回的,即使我没有将橡皮筋与我的任何数据相交,所以它显然是在返回场景中的其他项目。
我试着做了一个dynamic_cast,QGraphicsView::items返回给一个QLineSeries,但这不起作用。我情不自禁地认为这件事比我应该做的更复杂。
UPDATE1: I还尝试捕捉在橡皮筋选择期间鼠标悬停在数据序列上时发出的信号:
connect(line_series, SIGNAL(hovered(const QPointF &, bool)), this, SLOT(OnDataHovered(const QPointF&, bool)));但是,当橡皮筋拖动时,信号不会发出(也许当鼠标左键关闭时,它就不会启动?)。:(
更新2: --我已经尝试在mouseReleaseEvent()调用中设置selectionArea,并且再次以选中的方式返回其中的一些,比调用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);
}
}
}发布于 2018-07-19 01:49:51
您遇到的问题是,当启用橡皮筋模式时,QChartView重新实现MousePressEvent并接受事件。由于事件只向上传播,所以QLineSeries ( QChart和QChartView的子级)永远得不到备忘。
解决方案是安装一个QEventFilter,这样您就可以在QChartView接受事件之前拦截它;但是,我还没有弄清楚如何检测单击的是否实际上是QLineSeries。
发布于 2019-01-22 08:40:55
“我尝试执行QGraphicsView::items返回给一个dynamic_cast的QLineSeries,但这不起作用。”
下面是如何获得QGraphicsItem表示的QLineSeries。
QChart ch;
QLineSeries srs;
QList<QGraphicsItem*> bf{ch.childItems()};
ch.addSeries(&srs);
QList<QGraphicsItem*> af{ch.childItems()};
QGraphicsItem * mf;
for(auto e: af)
if(!bf.contains(e))
mf = e;
qDebug().operator<<(mf->isUnderMouse());https://stackoverflow.com/questions/50448672
复制相似问题