在QChartView上启用水平缩放/滚动(2016年11月Qt-5.7.0)

时间:2016-11-27 18:59:18

标签: qt

我有一个很长的QLineSeries,其中包含条形图。我可以在QChartView中显示它,如果我设置HorizontalRubberBand,我可以放大它的一部分。默认QChartView也会在鼠标右键单击时缩小。但我不知道如何连接水平滚动条,这样当我放大时,我也可以沿着条带向左和向右滚动。

下面的代码创建一个包含两个正弦周期的简单QLineSeries。如果我可以正确地进行缩放和滚动,我可以将想法扩展到我的实际项目。有什么帮助吗?

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QLineSeries *s = new QLineSeries;
    QChart      *c = new QChart;

    for (double theta = 0.0; theta < 4.0 * M_PI; theta += M_PI / 50.0)
        s->append( theta, sin( theta ) );

    c->addSeries( s );
    c->createDefaultAxes( );

    ui->chartview->setChart( c );
    ui->chartview->setRubberBand( QChartView::HorizontalRubberBand );
}

MainWindow::~MainWindow()
{
    delete ui;
}

1 个答案:

答案 0 :(得分:2)

我开始玩各种可用的信号,我设法让我的示例程序按照需要运行。我不确定这是否是经过批准的方法,或者它是否能很好地扩展,但它对我有用。

有一件事我并不特别清楚,QChartView上的滚动条不会滚动正确的东西。它们滚动整个QChart,轴和所有。要滚动图表中的缩放数据,您需要添加单独的滚动条,然后调用QChart的{​​{1}}函数以响应scroll()信号。 (我没有对此进行测试,但可能会调用valueChanged&#39; QAxis来代替。{/ p>

这是显示两个正弦波周期并允许橡皮筋缩放的代码。缩放时,您可以沿着波浪来回滚动。

setRange( <i>min</i>, <i>max</i> )

(对于硬编码#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , scrolling( false ) { ui->setupUi(this); QLineSeries *s = new QLineSeries; QChart *c = new QChart; for (double theta = 0.0; theta < 4.0 * M_PI; theta += M_PI / 50.0) s->append( theta / M_PI, sin( theta ) ); c->addSeries( s ); c->createDefaultAxes( ); c->legend( )->hide( ); ui->chartView->setChart( c ); ui->chartView->setRubberBand( QChartView::HorizontalRubberBand ); // PlotAreaChanged seems like it might be useful, but not for this purpose // rangeChanged (on the axis) is the one you need. connect( c->axisX( ), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(on_rangeChanged(qreal,qreal)) ); } void MainWindow::on_chartScroll_valueChanged( int v ) { if (!scrolling) { scrolling = true; // cerr << "scroll " << v << endl; ui->chartView->chart( )->scroll( v - sv, 0 ); sv = v; scrolling = false; } } void MainWindow::on_rangeChanged( qreal min, qreal max ) { if (scrolling) return; // Scrolling causes range changes, but we don't have to do anything. QChart *c = ui->chartView->chart( ); QAbstractAxis *x = c->axisX( ); qreal avg = (min + max) / 2.0; bool range_fixed = false; /* * Make sure the new range is sane; fix if not. */ if ((max - min) < 0.1) { // Avoid overzooming min = avg - 0.05; max = avg + 0.05; range_fixed = true; } if (min < 0.0) { min = 0.0; range_fixed = true; } if (max > 4.0) { max = 4.0; range_fixed = true; } if (range_fixed) { x->setRange( min, max ); // will re-signal with the fixed range return; } qreal vis_width = c->plotArea( ).width( ); qreal all_width = vis_width * (4.0 - 0.0) / (max - min); // cerr << "range " << min << " ... " << max << " in " << vis_width << " pixels" << endl; // cerr << "full width requires " << all_width << " pixels" << endl;; if (max - min < 4.0) { // cerr << "set scroll parameters" << endl; scrolling = true; ui->chartScroll->setMaximum( all_width - vis_width ); sv = min / (4.0 - 0.0) * all_width; ui->chartScroll->setValue( sv ); scrolling = false; } else { // cerr << "disable scroll bar" << endl; scrolling = true; ui->chartScroll->setMaximum( 0 ); ui->chartScroll->setValue( sv ); scrolling = false; } } MainWindow::~MainWindow() { delete ui; } [来自4.0]的道歉。正确的事情是查看您要滚动浏览的所有数据。)