gpt4 book ai didi

qt - 在 QChartView 上实现选择

转载 作者:行者123 更新时间:2023-12-03 01:04:49 24 4
gpt4 key购买 nike

我想实现基于QChart的图表选择和 QChartView 。类里的家庭有很大的优势- easy use of openGLanimations ,例如:

QLineSeries *series = new QLineSeries();
series->setUseOpenGL(true); // <==

QChart *chart = new QChart();
chart->addSeries(series);
chart->setAnimationOptions(QChart::AllAnimations); // <==

QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);

QChartView类提供有用的缩放功能 - QChartView::setRubberBand() :

chartView->setRubberBand(QChartView::RectangleRubberBand);

enter image description here

主要问题是橡皮筋只能用于缩放,但我需要将其实现为不缩放的水平选择,因为该功能通常在音频编辑器中实现: enter image description here

现在,当我继承了 QChartView 后,我可以在选择后禁用缩放:

class ChartView : public QChartView
...
bool m_drawRubberBand;
QRubberBand m_rubberBand;
...

ChartView::ChartView(QChart *chart, QWidget *parent)
: QChartView(chart, parent)
{
setRubberBand(QChartView::HorizontalRubberBand);
}
...

// Just copy-paste from the Qt 5 sources - file \Src\qtcharts\src\charts\qchartview.cpp:
/*!
If the rubber band rectangle is displayed in the press event specified by
\a event, the event data is used to update the rubber band geometry.
Otherwise, the default QGraphicsView::mouseMoveEvent() implementation is called.
*/
void ChartView::mouseMoveEvent(QMouseEvent *event)
{
if (m_drawRubberBand && m_rubberBand.isVisible())
{
QRect rect = chart()->plotArea().toRect();
int width = event->pos().x() - m_rubberBandOrigin.x();
int height = event->pos().y() - m_rubberBandOrigin.y();
if (!rubberBand().testFlag(VerticalRubberBand))
{
m_rubberBandOrigin.setY(rect.top());
height = rect.height();
}
if (!rubberBand().testFlag(HorizontalRubberBand))
{
m_rubberBandOrigin.setX(rect.left());
width = rect.width();
}
m_rubberBand.setGeometry(QRect(m_rubberBandOrigin.x(), m_rubberBandOrigin.y(), width, height).normalized());
}
else
{
QGraphicsView::mouseMoveEvent(event);
}
}

那么我可以不在鼠标键释放事件上实现缩放操作:

void ChartView::mouseReleaseEvent(QMouseEvent *event)
{
if (m_rubberBand.isVisible())
{
if (event->button() == Qt::LeftButton)
{
m_drawRubberBand = false;
do_nothing(); // <==
}

}
}

所以,我现在的问题是:

  1. 如何将视觉橡皮筋的边界映射到真实图表的坐标。即,如何将选择映射到图表上的线系列?现在我收到同样的错误坐标:

      void MyView::resizeEvent(QResizeEvent *event) 
    {
    QChartView::resizeEvent(event);

    QRect rct(QPoint(10, 10), QPoint(20, 20));
    qDebug() << mapToScene(rct); <==
    }

输出:

QPolygonF(QPointF(10,10)QPointF(21,10)QPointF(21,21)QPointF(10,21))
QPolygonF(QPointF(10,10)QPointF(21,10)QPointF(21,21)QPointF(10,21))
QPolygonF(QPointF(10,10)QPointF(21,10)QPointF(21,21)QPointF(10,21))
QPolygonF(QPointF(10,10)QPointF(21,10)QPointF(21,21)QPointF(10,21))
...
  • 如何根据 View 按比例调整现有橡胶选择的大小?
  • 编辑:可能这是一个有用的关键字 - QGraphicsScene::setSelectionArea()

    The Qt 5 chip example which provides nice rubber band selection ,但示例基于 QGraphicsView ,不在 QChartView 上。

    最佳答案

    由于对此答案的回复,问题已解决:Get mouse coordinates in QChartView's axis system

    关键时刻:需要调用QChart::mapToValue()正确的坐标变换:

    QPointF ChartView::point_to_chart(const QPoint &pnt)
    {
    QPointF scene_point = mapToScene(pnt);
    QPointF chart_point = chart()->mapToValue(scene_point);

    return chart_point;
    }

    以及逆变换:

    QPoint ChartView::chart_to_view_point(QPointF char_coord)
    {
    QPointF scene_point = chart()->mapToPosition(char_coord);
    QPoint view_point = mapFromScene(scene_point);

    return view_point;
    }

    这就是我在resizeEvent上实现橡皮筋大小调整的方法。 .
    首先,我在鼠标释放事件上保存当前的橡皮筋:

    void ChartView::mouseReleaseEvent(QMouseEvent *event)
    {
    if (m_rubberBand.isVisible())
    {
    update_rubber_band(event);
    m_drawRubberBand = false;
    save_current_rubber_band(); <==
    }
    }

    地点:

    void ChartView::update_rubber_band(QMouseEvent * event)
    {
    QRect rect = chart()->plotArea().toRect();
    int width = event->pos().x() - m_rubberBandOrigin.x();
    int height = event->pos().y() - m_rubberBandOrigin.y();
    if (!rubberBand().testFlag(VerticalRubberBand))
    {
    m_rubberBandOrigin.setY(rect.top());
    height = rect.height();
    }
    if (!rubberBand().testFlag(HorizontalRubberBand))
    {
    m_rubberBandOrigin.setX(rect.left());
    width = rect.width();
    }
    m_rubberBand.setGeometry(QRect(m_rubberBandOrigin.x(), m_rubberBandOrigin.y(), width, height).normalized());
    }

    还有:

    void ChartView::save_current_rubber_band()
    {
    QRect rect = m_rubberBand.geometry();

    QPointF chart_top_left = point_to_chart(rect.topLeft());
    m_chartRectF.setTopLeft(chart_top_left);

    QPointF chart_bottom_right = point_to_chart(rect.bottomRight());
    m_chartRectF.setBottomRight(chart_bottom_right);
    }

    以及如何在调整大小事件中重新绘制橡胶:

    void ChartView::resizeEvent(QResizeEvent *event)
    {
    QChartView::resizeEvent(event);

    if (m_rubberBand.isVisible())
    {
    restore_rubber_band();
    }

    apply_nice_numbers();
    }

    地点:

    void ChartView::restore_rubber_band()
    {
    QPoint view_top_left = chart_to_view_point(m_chartRectF.topLeft());
    QPoint view_bottom_right = chart_to_view_point(m_chartRectF.bottomRight());

    m_rubberBandOrigin = view_top_left;
    m_rubberBand.setGeometry(QRect(view_top_left, view_bottom_right));
    }

    不要忘记 "nice numbers" :

    void ChartView::apply_nice_numbers()
    {
    QList<QAbstractAxis*> axes_list = chart()->axes();
    for each(QAbstractAxis* abstract_axis in axes_list)
    {
    QValueAxis* value_axis = qobject_cast<QValueAxis*>(abstract_axis);
    if (value_axis)
    {
    value_axis->applyNiceNumbers();
    }
    }
    }

    这个逻辑在起作用。调整大小之前: enter image description here

    调整大小后: enter image description here

    关于qt - 在 QChartView 上实现选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48164065/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com