Qt实践之用鼠标事件使QChart图表前移后移、时间坐标轴放大缩小

头文件声明

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();
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要设置QChart跟随时间移动坐标轴,可以按照以下步骤进行操作: 1. 创建一个QChart对象,并将其设置为视图的图表: ```cpp QChart *chart = new QChart(); chartView->setChart(chart); ``` 2. 创建一个QValueAxis对象,用于表示时间轴: ```cpp QValueAxis *timeAxis = new QValueAxis(); chart->addAxis(timeAxis, Qt::AlignBottom); // 将时间轴添加到图表中,并指定对齐方式为底部 ``` 3. 设置时间轴的范围和显示格式: ```cpp QDateTime startTime = QDateTime::currentDateTime(); // 获取当前时间作为起始时间 QDateTime endTime = startTime.addSecs(60); // 结束时间为起始时间+60秒 timeAxis->setRange(startTime, endTime); // 设置时间范围 timeAxis->setTickCount(6); // 设置显示的时间刻度数量 timeAxis->setFormat("hh:mm:ss"); // 设置时间的显示格式 ``` 4. 创建一个QLineSeries对象,并将其添加到图表中,并将时间轴与该系列关联: ```cpp QLineSeries *series = new QLineSeries(); chart->addSeries(series); series->attachAxis(timeAxis); // 将时间轴与系列关联 ``` 5. 在数据更新时,通过调整时间轴的范围来实现坐标轴的移动: ```cpp QDateTime newEndTime = QDateTime::currentDateTime(); // 获取新的结束时间 QDateTime newStartTime = newEndTime.addSecs(-60); // 新的起始时间为结束时间-60秒 timeAxis->setRange(newStartTime, newEndTime); // 调整时间轴的范围 ``` 通过以上步骤,可以实现QChart跟随时间移动坐标轴的效果。当数据不断更新时,只需要调整时间轴的范围,就可以实现坐标轴的移动,以显示最新的数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值