ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Qt实战14.告警信息滚动轮播控件

2022-01-27 12:35:34  阅读:308  来源: 互联网

标签:pAnimation 控件 轮播 动画 pItemGroup 告警信息 item AlarmHistoryScene


1 需求描述

做一个独立的控件,该控件能够滚动轮播报警信息,告警信息分为一般、严重、危险三个等级,分别用不同颜色做标记。

2 设计思路

做滚动轮播效果,优先想到Qt的动画框架,同时考虑到图形视图框架的易用性,实现上应该会简单不少,所以该控件会使用图形视图框架并结合动画框架实现。

  • 每一条告警信息用QGraphicsTextItem表示
  • 由于整体要使用动画轮播,所有的QGraphicsTextItem会添加到一个QGraphicsItemGroup中,方便做整体动画
  • 动画使用QVariantAnimation即可,毕竟轮播只是改变了QGraphicsItemGroup的y坐标
  • 为了能够适应窗口大小的变化,需要动态调整场景的大小和动画参数

3 代码实现

控件为QGraphicsView的子类,设定了自定义的场景类,在场景类中提供接口,添加/清空告警信息:

3.1 AlarmHistoryScene.h

class AlarmHistoryScene : public QGraphicsScene
{
    Q_OBJECT

public:
    explicit AlarmHistoryScene(QObject *parent = 0);

    void addAlarmText(WarningLevel level, const QString &alarm);
    void clear();

private:
    void updateAnimation();

private:
    QStringList m_alarmList;
    QGraphicsItemGroup *m_pItemGroup = nullptr;
    QVariantAnimation *m_pAnimation = nullptr;
};

addAlarmText添加告警信息接口,clear清空告警信息,updateAnimation会在初次启动或窗口大小变化时自动调用。

3.2 AlarmHistoryScene.cpp

AlarmHistoryScene::AlarmHistoryScene(QObject *parent) : QGraphicsScene(parent)
{
    m_pItemGroup = new QGraphicsItemGroup();

    addItem(m_pItemGroup);
    m_pItemGroup->setPos(0, 0);

    connect(this, &AlarmHistoryScene::sceneRectChanged, this, &AlarmHistoryScene::updateAnimation);
}

void AlarmHistoryScene::addAlarmText(WarningLevel level ,const QString &alarm)
{
    QString detail = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")
            .append(QStringLiteral(":"))
            .append(alarm);

    QGraphicsTextItem *item = new QGraphicsTextItem(detail);

    QFont font;
    font.setFamily("System");
    font.setPixelSize(12);

    item->setFont(font);
    switch (level) {
    case WarningLevel::Normal:
        item->setDefaultTextColor(QColor(227, 207, 87));
        break;
    case WarningLevel::Serious:
        item->setDefaultTextColor(QColor(243, 130, 19));
        break;
    case WarningLevel::Danger:
        item->setDefaultTextColor(QColor("red"));
        break;
    default:
        break;
    }

    int count = m_pItemGroup->childItems().count();

    item->setPos(0, m_pItemGroup->y() + count * (font.pixelSize() + 2));
    m_pItemGroup->addToGroup(item);

    updateAnimation();
}

根据日志等级实例化QGraphicsTextItem并添加到m_pItemGroup中,再更新下动画,这里没啥可说的。

void AlarmHistoryScene::clear()
{
    if (m_pAnimation)
    {
        m_pAnimation->stop();
        m_pAnimation->deleteLater();
        m_pAnimation = nullptr;
    }

    m_pItemGroup->setPos(0, 0);
    auto list = m_pItemGroup->childItems();
    int count = list.count();
    for (int i = 0; i < count; ++i) {
        auto item = list.at(i);
        m_pItemGroup->removeFromGroup(item);
        removeItem(item);
        delete item;
    }
}

这里主要是关闭动画,并清空所有告警信息。

void AlarmHistoryScene::updateAnimation()
{
    if (m_pAnimation)
    {
        m_pAnimation->stop();
        m_pAnimation->deleteLater();
        m_pAnimation = nullptr;
    }

    m_pAnimation = new QVariantAnimation(this);
    connect(m_pAnimation, &QVariantAnimation::valueChanged, this, [=](const QVariant &value) {
        m_pItemGroup->setPos(0, value.toDouble());
    });
    m_pAnimation->setLoopCount(-1);

    qreal sceneHeight = this->sceneRect().height();
    m_pItemGroup->setPos(0, sceneHeight);

    m_pAnimation->setDuration((sceneHeight + m_pItemGroup->boundingRect().height()) * 12);
    m_pAnimation->setStartValue(sceneHeight);
    m_pAnimation->setEndValue(-m_pItemGroup->boundingRect().height());
    m_pAnimation->start();
}

更新动画,作用于m_pItemGroup,轮播只需要改变y坐标值,所以使用QVariantAnimation即可实现,同时动画时间需要根据视图大小动态调整。
好啦,主要代码就这么多了,还是挺简单的。

4 总结

Qt图形视图框架异常强大,结合动画框架能够实现很多酷炫效果,这里也只用到了一点点皮毛,多看看Qt的Demo程序会有很多意外收获,一般人我不告诉他,哈哈。溜了溜了。。。新年快乐!

5 下载

示例代码

标签:pAnimation,控件,轮播,动画,pItemGroup,告警信息,item,AlarmHistoryScene
来源: https://www.cnblogs.com/luoxiang/p/15849231.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有