(QT-UI)十二、鼠标放置到时间轴,显示具体时间

   本系列预计实现

①刻度上方文字显示,

②时间轴拖动效果,

③时间轴刻度缩放,

④时间轴和其他控件联动显示,

⑤鼠标放置到时间轴,显示具体时间。

⑥通过定时器,实时更新时间轴

⑦时间轴上绘制时间片

 完整代码可见GitHub - 754816/QT_TimeLine: qt时间轴实现效果

1、基础思路

主要是用到了之前章节中添加上的mouseMoveEvent和时间轴中心的当前时间m_MoveDateTime,然后新增了鼠标进入时间轴的事件函数(enterEvent),离开事件函数leaveEvent,以及一个用来展示时间文字的Label。

当鼠标进入时间轴时,根据鼠标位置,计算出相当于时间轴中心点的偏移量,根据偏移量换算出相对于时间轴中心的当前时间的偏移时间,调用SetHidden(false)显示label,当离开时隐藏label

2、代码实现

首先在初始化时,添加上label类,调整大小,重点是要设置跟踪鼠标轨迹,否则会影响mouseMoveEvent的调用频率。

void MyTimeLine::InitializeUI()
{

    m_label = new QLabel(this);
    m_label->setText(m_MoveDateTime.time().toString("hh:mm:ss"));
    m_label->setHidden(true);
    m_label->resize(60, 20);
    //设置为true后,鼠标移动就会触发mouseMoveEvent,默认是false,不会自动跟踪
    this->setMouseTracking(true);
}

然后添加进入和离开事件。

//============hpp===============
protected:
    void enterEvent(QEvent *);
    void leaveEvent(QEvent *);

//=============cpp===============
void MyTimeLine::enterEvent(QEvent *)
{
    m_label->setHidden(false);
}
void MyTimeLine::leaveEvent(QEvent *)
{
    m_label->setHidden(true);
}

在mouseMoveEvent中添加上计算鼠标位移的代码,当鼠标移动后,计算一次。首先计算出鼠标相对于时间轴中心的偏移像素,用偏移像素除以每个块的长度,得到偏移比例,再用偏移比例乘以每个块对应的时间间隔,得到了偏移的秒数,然后用时间轴中心的时间加上偏移秒数,就得到了鼠标所指位置的偏移时间。

void MyTimeLine::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        int curMoveX = event->pos().x() - m_BeginX;
        m_MoveX = m_totalX + curMoveX;
        update();
    }

    //获取鼠标位置
    QPoint mousePos = event->pos();
    m_label->setHidden(false);
    //调整到鼠标左边一点点的位置,方便完整展示
    m_label->move(mousePos.x() + 3, this->size().height() - 15);
    if(!m_bMoving)
    {    //鼠标在拖动时间轴时,不更新label信息,只移动label
         QString timestr = CalMouseTime(mousePos);
         m_label->setText(timestr);
    }
}

void MyTimeLine::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_bMoving = true;
        m_BeginX = event->pos().x();
    }
}

void MyTimeLine::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_bMoving = false;
        m_totalX = m_totalX +  event->pos().x() - m_BeginX;
        m_MoveX = m_totalX;
    }
}

QString MyTimeLine::CalMouseTime(QPoint p)
{
    int width = this->size().width() / 2;
    //计算鼠标位置相对于中心点的偏移量
    double ratio =  ((double)p.x() - (double)width) / (double)m_blockWidth;
    //将偏移量转换为时间
    QDateTime time = DateTimeUtil::sub(m_MoveDateTime, -1 * ratio * m_IntervalType);
    return time.toString("hh:mm:ss");
}

3、在拖动时间轴的时候,只移动label,不修改label内容

在拖动时,鼠标显示的时间应该和时间轴同步,所以此时应该只移动label,不修改label内容

所以这里添加上一个全局变量m_bMoving,默认初始化为false,用来表示是否处于时间轴拖动状态,当鼠标在时间轴上按下时,m_bMoving设置为true,当结束拖动时,m_bMoving修改为false

void MyTimeLine::mousePressEvent(QMouseEvent *event)
{
     m_bMoving = true;
     ...
}
void MyTimeLine::mouseMoveEvent(QMouseEvent *event)
{
    //鼠标在拖动时间轴时,不更新label信息,只移动label
    if(!m_bMoving)
    {
       ...
    }
}
void MyTimeLine::mouseReleaseEvent(QMouseEvent *event)
{
    m_bMoving = false;
    ...
}

4、当鼠标滚轮缩放时,可以选择隐藏label

当鼠标滚轮缩放时,此时鼠标没有位移,所以也不会更新label,但是时间间隔已经变了,label上原来根据鼠标偏移位置算出来的偏移时间已不准确,需要重新计算,而通过放大和缩小按钮进行缩放的时候,鼠标必然是存在着移动,所以label始终是准确的。这里只给出解决思路,代码中未进行实现。

当鼠标缩放后,在鼠标滚轮事件中,添加上更新label的逻辑,由于鼠标滚轮事件wheelEvent(QWheelEvent *event)中,不方便直接获取鼠标位置,所以需要获取鼠标和时间轴的绝对坐标,也就是相对于屏幕左上角(0,0)点的坐标,然后就可以计算出鼠标相对于时间轴中心的偏移量,再根据比例计算出偏移的时间了。

当然,这里也可以选择直接隐藏label,用户在缩放完后,只要再触发下移动,就可以重新显示准确的时间。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值