6.QCustomPlot 用滚动条控制轴范围

用滚动条(scrollbar)控制轴(axis)的范围

虽然最直观的控制axis范围的方法是范围拖动和缩放机制,但可能还需要为此提供scrollbars滚动条。这可以通过signals 和slots 与scrollbar 连接来实现。需要一个中间slot 来在axis的QCPRange和scrollbar 的整数值之间进行转换。

本教程附带的示例项目称为scrollbar-axis-range-control,是完整软件包下载的一部分。

https://www.qcustomplot.com/index.php/tutorials/specialcases/scrollbar

 

与在滚动条和axis之间来回传播更改相关的信号是QScrollBar::valueChanged(int)和QCPAxis::rangeChanged(QCPRange)。因为我们希望保持正常的拖动和缩放范围,所以当轴的rangeChanged信号发出时,滚动条滑块的位置和大小必须更新。

QScrollBar是基于整数的。因此,我们需要一个因子将整型滚动条值转换为轴坐标。例如,如果我们想要在坐标范围-5到5上平滑滚动坐标轴,我们可以将因子设置为0.01(即将滚动条的值除以100),从而滚动条的范围为-500..500。

 

ui->horizontalScrollBar->setRange(-500, 500);
ui->verticalScrollBar->setRange(-500, 500);

 

如果可访问的坐标范围在任何一点发生变化,只需改变滚动条scrollbar的最大值/最小值即可。

执行坐标转换的中间槽称为horzScrollBarChanged、vertScrollBarChanged、xAxisChanged和yAxisChanged。它们连接到滚动条和x-/y轴的适当信号:

 

connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(horzScrollBarChanged(int)));
connect(ui->verticalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(vertScrollBarChanged(int)));
connect(ui->plot->xAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(xAxisChanged(QCPRange)));
connect(ui->plot->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(yAxisChanged(QCPRange)));

坐标转换slots

这两种类型的slots(轴范围到滚动条 和 滚动条到轴范围)都相当简单。它们分别获取滚动条或轴的更改值,应用转换并将结果设置为轴或滚动条。这些是在移动滚动条滑块时更新轴范围的slots:

 

void MainWindow::horzScrollBarChanged(int value)
{
  if (qAbs(ui->plot->xAxis->range().center()-value/100.0) > 0.01) // if user is dragging plot, we don't want to replot twice
  {
    ui->plot->xAxis->setRange(value/100.0, ui->plot->xAxis->range().size(), Qt::AlignCenter);
    ui->plot->replot();
  }
}
 
void MainWindow::vertScrollBarChanged(int value)
{
  if (qAbs(ui->plot->yAxis->range().center()+value/100.0) > 0.01) // if user is dragging plot, we don't want to replot twice
  {
    ui->plot->yAxis->setRange(-value/100.0, ui->plot->yAxis->range().size(), Qt::AlignCenter);
    ui->plot->replot();
  }
}

有两件事值得一提:

首先,我们在这里看到通过除以100.0将滚动条值转换为轴坐标。还要注意,当滑块在顶部时,垂直滚动条的值是低的,而当滑块在底部时,垂直滚动条的值是高的。对于绘图轴,情况则相反,这就是为什么要在包含垂直滚动条值的表达式中添加减号,例如在设置yAxis范围时。

条件qAbs(ui->plot->xAxis->range().center()-value/100.0) > 0.01是必要的,这样范围拖动就不会导致由变化信号和槽之间来回导致的双重重画。之所以会出现这种情况,是因为在拖动范围时,QCustomPlot会自动重新对自身进行绘图,并发出拖动轴的范围改变信号。在这个应用程序中,rangeChanged信号将调用插槽xAxisChanged或yAxisChanged,正如我们将看到的,通过调用滚动条的setValue方法更新滚动条滑块的位置。这个方法依次发出与上面的槽连接的滚动条的valueChanged信号。在这里,如果检查没有到位,就会发生第二次重新规划。该检查确保仅当当前轴范围与新的(转换后的)滚动条值不同时才执行重绘图。如果用户拖动轴范围,则不会出现这种情况,因此将跳过冗余的重新绘制和轴范围更新。

在坐标轴范围变化时更新滚动条的槽很简单

void MainWindow::xAxisChanged(QCPRange range)
{
  ui->horizontalScrollBar->setValue(qRound(range.center()*100.0)); // adjust position of scroll bar slider
  ui->horizontalScrollBar->setPageStep(qRound(range.size()*100.0)); // adjust size of scroll bar slider
}
 
void MainWindow::yAxisChanged(QCPRange range)
{
  ui->verticalScrollBar->setValue(qRound(-range.center()*100.0)); // adjust position of scroll bar slider
  ui->verticalScrollBar->setPageStep(qRound(range.size()*100.0)); // adjust size of scroll bar slider
}

他们只是将范围中心转换为滚动条值,并将范围大小转换为滚动条的页面步长(滚动条滑块大小)。

  • 0
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值