头文件声明
protected:
void wheelEvent(QWheelEvent *event) override;
private slots:
void onTimeout();
private:
void dragPressureChart(int delta);
void zoomPressureChart(QWheelEvent *wheelEvent);
void showStreamStatusChart();
int m_totalDelta; //记录前移或后移的时间刻度
QTimer *m_timer;
成员变量初始化
m_totalDelta = 0;
m_timer = new QTimer();
QObject::connect(m_timer, &QTimer::timeout, this, &StatusPanel::onTimeout);
m_timer->start(1000);
实现滚轮事件
void StatusPanel::wheelEvent(QWheelEvent *event)
{
if (m_statusChartView->geometry().contains(m_statusChartView->mapFrom(this, event->position().toPoint())))
{
if (event->modifiers() & Qt::ControlModifier)
{
zoomPressureChart(event); // CTRL加滚动,放大或缩小坐标轴的范围
}
else
{
dragPressureChart(event->angleDelta().y()); // 单独滚动,前移或后移图表曲线,当滚轮上滚时参数为120,反之为-120
}
}
event->accept(); //来接受事件,表示事件已经被处理。如果不调用该函数,事件会继续传递给其他可能处理该事件的控件
}
实现前移后移图表曲线
void StatusPanel::dragPressureChart(int delta)
{
if (delta > 0 && m_totalDelta < 1800) // 30 minutes, scroll up // 允许前移或后移的范围为30分钟
{
m_axisX->setMin(m_axisX->min().addSecs(-60));
m_axisX->setMax(m_axisX->max().addSecs(-60));
m_totalDelta += 60;
}
else if (delta < 0 && m_totalDelta > -1800) // scroll down
{
m_axisX->setMin(m_axisX->min().addSecs(60));
m_axisX->setMax(m_axisX->max().addSecs(60));
m_totalDelta -= 60;
}
}
实现放大缩小时间坐标轴
void StatusPanel::zoomPressureChart(QWheelEvent *wheelEvent)
{
static int axisRange[3] = {3, 5, 10}; // 时间轴改变的幅度共三档,3*2, 5*2, 10*2
static int wheelCount = 0; // 记录滚轮有效滚动次数
static int callCount = 0; //记录函数调用次数,每调用三次,有效滚动次数加一,坐标轴改变一次
callCount++;
if (callCount >= 3)
{
wheelCount++;
Count = 0;
if (wheelCount < 0)
{
wheelCount = -wheelCount;
}
if (wheelCount > 2)
{
wheelCount = 0;
}
QDateTime min = QDateTime::currentDateTime().addSecs(-60 * axisRange[wheelCount]);
QDateTime max = QDateTime::currentDateTime().addSecs(60 * axisRange[wheelCount]);
m_axisX->setRange(min, max);
m_totalDelta = 0; // 清零,表示当前无前移或后移曲线
}
}
实现定时器事件,实时更新以时间为坐标轴表示的图表
void MyClass::onTimeout()
{
showStreamStatusChart();
}
定时器事件实际要做的是从界面获取数据源,并根据数据源实时更新图表曲线,每次使曲线前进一分钟
void MyClass::showStreamStatusChart()
{
QLineSeries *dataSeries = dynamic_cast<QLineSeries *>(m_statusChart->series().at(streamIndex));
m_axisX = qobject_cast<QDateTimeAxis *>(m_statusChart->axisX(dataSeries));
QDateTime currentTimePoint = QDateTime::currentDateTime();
if (currentTimePoint.secsTo(m_axisX->min()) < -3 * 60)
{
if (currentTimePoint.operator>=(m_axisX->min()) && currentTimePoint.operator<=(m_axisX->max()))
{
QDateTime newMax = m_axisX->max().addSecs(60);
if (newMax <= currentTimePoint.addSecs(90))
{
m_axisX->setMin(m_axisX->min().addSecs(60));
m_axisX->setMax(newMax);
}
}
else if (currentTimePoint.secsTo(m_axisX->min()) < -31 * 60) // 使图表只保留前后30分钟的数据
{
m_axisX->setMin(m_axisX->min().addSecs(60));
m_axisX->setMax(m_axisX->max().addSecs(60));
}
}
double currentPressure = m_ui->labelPump1Pressure->text().toDouble(); // 从界面获取图表曲线的数据源
dataSeries->append(QDateTime::currentMSecsSinceEpoch(), currentPressure);
dataSeries->show();
}