在QChartView上启用水平缩放/滚动(2016年11月Qt-5.7.0)
我有一个长的在QChartView上启用水平缩放/滚动(2016年11月Qt-5.7.0),qt,Qt,我有一个长的QLineSeries,其中包含类似条形图的内容。我可以在QChartView中显示它,如果我设置HorizontalRubberBand,我可以放大它的一部分。默认的QChartView也会在鼠标右键单击时缩小。但是我不知道如何连接水平滚动条,这样当我放大时,我也可以沿着条带左右滚动 下面的代码创建了一个简单的QLineSeries,其中包含两个正弦周期。如果我能正确地进行缩放和滚动,我可以将这个想法扩展到我的实际项目中。有什么帮助吗 #include "mainwindow.h"
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;
}
#包括“mainwindow.h”
#包括“ui_main window.h”
主窗口::主窗口(QWidget*父窗口):
QMainWindow(父级),
用户界面(新用户界面::主窗口)
{
用户界面->设置用户界面(此);
QLineSeries*s=新的QLineSeries;
QChart*c=新QChart;
对于(双θ=0.0;θ<4.0*M_π;θ+=M_π/50.0)
s->append(θ,sin(θ));
c->addSeries(s);
c->createDefaultAxes();
用户界面->图表视图->设置图表(c);
ui->chartview->setRubberBand(QChartView::HorizontalRubberBand);
}
MainWindow::~MainWindow()
{
删除用户界面;
}
我开始使用各种可用的信号,并设法使我的示例程序按预期工作。我不确定这是否是被认可的方法,或者它是否能很好地扩展,但它对我来说是有效的
我不太清楚的一点是,QChartView
上的滚动条没有滚动正确的内容。它们滚动整个QChart
、轴和所有轴。要在图表中滚动缩放的数据,需要添加一个单独的滚动条,然后调用QChart
的scroll()
函数以响应valueChanged
信号。(我没有对此进行测试,但是调用QAxis
的setRange(min,max)
可能会起作用。)
下面是显示两个正弦波周期并允许橡皮筋缩放的代码。缩放后,可以沿波浪前后滚动
#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;
}
#包括“mainwindow.h”
#包括“ui_main window.h”
主窗口::主窗口(QWidget*父窗口)
:QMainWindow(父级)
,ui(新ui::Main窗口)
,滚动(错误)
{
用户界面->设置用户界面(此);
QLineSeries*s=新的QLineSeries;
QChart*c=新QChart;
对于(双θ=0.0;θ<4.0*M_π;θ+=M_π/50.0)
s->append(θ/mupi,sin(θ));
c->addSeries(s);
c->createDefaultAxes();
c->legend()->hide();
用户界面->图表视图->设置图表(c);
ui->chartView->setRubberBand(QChartView::HorizontalRubberBand);
//PlotAreaChanged看起来可能有用,但不是用于此目的
//rangeChanged(在轴上)是您需要的。
连接(c->axisX(),信号(rangeChanged(qreal,qreal)),这个,插槽(on_rangeChanged(qreal,qreal));
}
无效的
主窗口::在图表上滚动\u值已更改(int v)
{
如果(!滚动){
滚动=真;
//cerr涡旋(v-sv,0);
sv=v;
滚动=假;
}
}
无效的
主窗口::on_范围已更改(qreal最小值、qreal最大值)
{
if(scrolling)return;//滚动导致范围改变,但我们不必做任何事情。
QChart*c=ui->chartView->chart();
QAbstractAxis*x=c->axix();
qreal平均值=(最小值+最大值)/2.0;
bool range_fixed=false;
/*
*确保新范围正常;如果不正常,请修复。
*/
如果((最大-最小)<0.1){//避免过度缩放
最小值=平均值-0.05;
最大值=平均值+0.05;
范围固定=真;
}
如果(min<0.0){min=0.0;范围_fixed=true;}
如果(max>4.0){max=4.0;range_fixed=true;}
如果(范围固定){
x->setRange(最小,最大);//将使用固定范围重新发送信号
返回;
}
qreal vis_width=c->plotArea().width();
qreal all_width=vis_width*(4.0-0.0)/(max-min);
//瑟尔