私はさまざまな信号を再生することができました。私はサンプルプログラムを希望どおりに動作させることができました。私はこれが承認された方法であるかどうか、あるいはそれがうまく調整されているかどうかはわかりませんが、それは私にとってはうまくいきます。
特に私にはっきりしないことの1つは、QChartView
のスクロールバーが正しいものをスクロールしないということです。彼らはQChart
、軸とすべてをスクロールします。チャート内のズームしたデータをスクロールするには、別のスクロールバーを追加してから、valueChanged
信号に応答してQChart
のscroll()
関数を呼び出す必要があります。 (私はこれをテストしませんでしたが、代わりにのsetRange(<i>min</i>, <i>max</i>)
と呼ぶことがあります)
ここでは、2つの正弦波サイクルを表示し、ラバーバンドズームを可能にするコードです。ズームすると、波に沿って前後にスクロールすることができます。
#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
のための謝罪[4π
から]。正しいことを行うには、スクロールしているデータの完全な範囲を見ている。)