HMI-50-【多媒体】菜单导航界面实现

简介: 今天是清明小长假的第二天,我们来实现以下菜单。因为咱们这个是纯粹使用二维来凑三维,所以效果肯定是有点拉胯的,各位看官留情。

头图

HMI-50-【多媒体】菜单导航界面实现

​ 今天是清明小长假的第二天,我们来实现以下菜单。因为咱们这个是纯粹使用二维来凑三维,所以效果肯定是有点拉胯的,各位看官留情。

当前进度

​ 按照以往的节奏。先上效果,如下图所示。

​ 本次核心看点,一个是下面这个水波的样子,一个就是旋菜单的。


[toc]

关键字: HMIMultifunctionQtlighteco

水波实现

​ 水波核心原理就是在Label上绘制图片,利用定时器实现刷图,实现水波效果,代码如下:

绘制函数

void MFD_MenuDisplay::drawMove()
{
    QPainter painter;
    painter.begin(ui->label_menuMove);
    switch (indexForMoveDiaplsy % 3) {
    case 0:
        painter.drawPixmap(0,0,width(),height(), QPixmap(":/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/1_1.png"));
        painter.drawPixmap(0,0,width(),height(), QPixmap(":/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/2_2.png"));
        painter.drawPixmap(0,0,width(),height(), QPixmap(":/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/3_3.png"));
        break;
    case 1:
        painter.drawPixmap(0,0,width(),height(), QPixmap(":/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/3_1.png"));
        painter.drawPixmap(0,0,width(),height(), QPixmap(":/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/1_2.png"));
        painter.drawPixmap(0,0,width(),height(), QPixmap(":/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/2_3.png"));
        break;
    case 2:
        painter.drawPixmap(0,0,width(),height(), QPixmap(":/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/2_1.png"));
        painter.drawPixmap(0,0,width(),height(), QPixmap(":/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/3_2.png"));
        painter.drawPixmap(0,0,width(),height(), QPixmap(":/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/1_3.png"));
        break;
    default:
        break;
    }
    painter.end();
}

控制定时器

    m_TimerForMoveDiaplsy = new QTimer();
    connect(m_TimerForMoveDiaplsy,&QTimer::timeout,this,[=](){
        indexForMoveDiaplsy++;
        update();
        if(indexForMoveDiaplsy == 3)
        {
            indexForMoveDiaplsy = 0;
            m_TimerForMoveDiaplsy->stop();
        }
    });
    m_TimerForMoveDiaplsy->start(125);

圆形导航旋钮

​ 这里用到的就是设置控件控件位置接口setGeometry()

首先使用一个QList来保存10个按钮的QRect。代码如下:

定义并初始化代码

QList<QRect> m_PushbuttonRectList;


void MFD_MenuDisplay::initPushbuttonList()
{
    m_PushbuttonRectList.append(QRect(190,500,240,188));
    m_PushbuttonRectList.append(QRect(460,590,240,188));
    m_PushbuttonRectList.append(QRect(840,630,240,188));
    m_PushbuttonRectList.append(QRect(1220,560,240,188));
    m_PushbuttonRectList.append(QRect(1490,500,240,188));

    m_PushbuttonRectList.append(QRect(1340,320,154,121));
    m_PushbuttonRectList.append(QRect(1110,290,154,121));
    m_PushbuttonRectList.append(QRect(883,270,154,121));
    m_PushbuttonRectList.append(QRect(640,290,154,121));
    m_PushbuttonRectList.append(QRect(390,320,154,121));

}

切换List数据

​ 这里的办法并不聪明,浪费大量资源,后期再说吧,先搞定从无到有,代码如下:

void MFD_MenuDisplay::inputControlDialValue(int value)
{
    if(value)
    {

        QRect temp = m_PushbuttonRectList[9];

        for(auto i = 9;i>0;i--)
        {
            m_PushbuttonRectList[i] = m_PushbuttonRectList[i-1];
        }
        m_PushbuttonRectList[0] = temp;

        muenIndex++;
        if(muenIndex == 11)
            muenIndex = 1;
    }
    else
    {


        QRect temp = m_PushbuttonRectList[0];

        for(auto i = 0;i<9;i++)
        {
            m_PushbuttonRectList[i] = m_PushbuttonRectList[i+1];
        }
        m_PushbuttonRectList[9] = temp;
        muenIndex--;
        if(muenIndex == 0)
            muenIndex = 10;
    }
    updatePushbuttonGeometry();
}

​ 上面代码中,存在一个变量muenIndex,这个是后面用来控制切换的,暂时可以不用理会。

更新位置、大小及样式代码

void MFD_MenuDisplay::updatePushbuttonGeometry()
{
    ui->pushButton_airConditioner->setGeometry(m_PushbuttonRectList[0]);

    ui->pushButton_drivingRecorder->setGeometry(m_PushbuttonRectList[1]);

    ui->pushButton_radio->setGeometry(m_PushbuttonRectList[2]);

    ui->pushButton_multimedia->setGeometry(m_PushbuttonRectList[3]);

    ui->pushButton_navigation->setGeometry(m_PushbuttonRectList[4]);

    ui->pushButton_360Panorama->setGeometry(m_PushbuttonRectList[5]);

    ui->pushButton_phone->setGeometry(m_PushbuttonRectList[6]);

    ui->pushButton_mobileConnect->setGeometry(m_PushbuttonRectList[7]);

    ui->pushButton_internetofVehicles->setGeometry(m_PushbuttonRectList[8]);

    ui->pushButton_setUp->setGeometry(m_PushbuttonRectList[9]);

    if(m_TimerForMoveDiaplsy)
        m_TimerForMoveDiaplsy->start(125);

    ui->pushButton_airConditioner->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/airConditioner.png);");

    ui->pushButton_drivingRecorder->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/drivingRecorder.png);");

    ui->pushButton_radio->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/radio.png);");

    ui->pushButton_multimedia->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/multimedia.png);");

    ui->pushButton_navigation->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/navigation.png);");

    ui->pushButton_360Panorama->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/360Panorama.png);");

    ui->pushButton_phone->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/phone.png);");

    ui->pushButton_mobileConnect->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/mobileConnect.png);");

    ui->pushButton_internetofVehicles->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/internetofVehicles.png);");

    ui->pushButton_setUp->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/setUp.png);");

    switch (muenIndex) {
    case 1:
        ui->pushButton_airConditioner->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/airConditioner_1.png);");
        break;
    case 2:
        ui->pushButton_drivingRecorder->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/drivingRecorder_1.png);");
        break;
    case 3:
        ui->pushButton_radio->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/radio_1.png);");
        break;
    case 4:
        ui->pushButton_multimedia->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/multimedia_1.png);");
        break;
    case 5:
        ui->pushButton_navigation->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/navigation_1.png);");
        break;
    case 6:

        ui->pushButton_360Panorama->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/360Panorama_1.png);");
        break;
    case 7:
        ui->pushButton_phone->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/phone_1.png);");
        break;
    case 8:

        ui->pushButton_mobileConnect->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/mobileConnect_1.png);");
        break;
    case 9:
        ui->pushButton_internetofVehicles->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/internetofVehicles_1.png);");
        break;
    case 10:
        ui->pushButton_setUp->setStyleSheet("border-image: url(:/MenuDisplay/Resources/MultifunctionDisplay/MenuDisplay/setUp_1.png);");
        break;
    default:
        break;
    }


}

第三阶段成果展示

​ 目前已完成液晶仪表三种模式的初步显示,小模块后期根据精力更新了,主要还得找美术来搞资源,自己能力不够。暂未跟新计划。展示如下:

[video(video-yznBr6e3-1648369267384)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=679609061)(image-https://ucc.alicdn.com/images/user-upload-01/img_convert/4d157e1cb316b007a2cb9790cb2dbfde.png)(title-基于Qt的汽车仪表模拟 3.0)]

B站链接:https://www.bilibili.com/video/BV1WS4y137y1/

第二阶段成果展示

​ 目前以完成HUD界面及接口开发,液晶仪表舒适模式和运动模式的开发。展示如下:

[video(video-2AqJ88TY-1645273728489)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=594179292)(image-https://ucc.alicdn.com/images/user-upload-01/img_convert/e75563c3ce68bc980547dde8f6e265ba.png)(title-基于Qt的汽车仪表模拟 2.0)]

B站链接:https://www.bilibili.com/video/BV1aq4y1t7H7/

第一阶段成果展示

​ 目前以完成HUD界面及接口开发,液晶仪表舒适模式开发。展示如下:

[video(video-ArCvRvBQ-1642664938100)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=77197267)(image-https://ucc.alicdn.com/images/user-upload-01/img_convert/ccddd04e0cef191fd33d7f58d41adb24.png)(title-基于Qt的汽车仪表模拟 1.0))]

B站链接:https://www.bilibili.com/video/BV1qJ411X7Gs/


说明:

本项目中所使借鉴原型来自:[吉利] 博瑞GE | 仪表HMI设计吉利汽车HMI项目

多媒体部分是来自吉利博瑞2017旗舰版界面所有权和解释权都归吉利汽车所有。

设计图的所有权和解释权都归吉利汽车所有。

本项目所有资源文件均由打不死的小海复刻制作。

本项目代码暂时不会开源,有需要的源码的可与我联系,左上角二维码加微信。

本项目仅限学习交流、禁止商业使用。


博客签名2021

相关文章
|
7月前
|
人工智能
生成式人工智能认证(GAI认证)官网 - 全国统一认证中文服务平台上线
生成式人工智能(AI)正深刻改变职场规则,但系统化学习相关技术成为难题。近日,由全球知名教育公司培生推出的生成式人工智能认证(GAI认证)中文官网正式上线,为专业人士和学习者提供了权威解决方案。该认证涵盖核心技能、提示工程、伦理合规等内容,助力持证者紧跟技术前沿,在职场中脱颖而出。全国统一认证平台提供便捷报名与在线考试服务,考后快速出成绩并颁发证书。行动起来,开启AI职业新篇章!
stm32f407探索者开发板(十)——时钟系统精讲
stm32f407探索者开发板(十)——时钟系统精讲
803 0
|
JavaScript 前端开发 架构师
Angular进阶:理解RxJS在Angular应用中的高效运用
RxJS(Reactive Extensions for JavaScript)是JavaScript的一个响应式编程库,特别适用于处理异步数据流。
224 0
|
存储 数据采集 安全
CDAM数据资产管理的策略制定与落地
在数字化时代,数据成为企业的核心资产,直接影响决策效率与市场竞争力。本文探讨数据资产管理策略的制定与实施,涵盖目标设定、组织架构搭建、政策流程制定、工具技术应用、数据战略规划、人才培养、风险管理及持续优化等方面,旨在为企业提供全方位的实践指导。
1016 0
|
JavaScript 前端开发 API
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
这篇文章讨论了Vue项目中错误的处理方式,包括后端接口错误和代码逻辑错误的处理策略。文章详细介绍了如何使用axios的拦截器处理后端接口错误,以及Vue提供的全局错误处理函数`errorHandler`和生命周期钩子`errorCaptured`来处理代码中的逻辑错误。此外,还分析了Vue错误处理的源码,解释了`handleError`、`globalHandleError`、`invokeWithErrorHandling`和`logError`函数的作用和处理流程。
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
|
Shell Linux 网络安全
性能工具之 JMeter 使用 shell 脚本快速执行
【2月更文挑战第30天】性能工具之 JMeter 使用 shell 脚本快速执行
884 1
性能工具之 JMeter 使用 shell 脚本快速执行
|
SQL 监控 网络协议
DM8数据守护集群安装部署详细教程
DM8数据守护集群安装部署详细教程
544 0
|
存储 监控 NoSQL
Redis中的LRU淘汰策略深入解析
Redis的内存管理关键在于处理数据增长与有限内存的矛盾,LRU策略被广泛用于此。LRU基于“不常访问的数据未来访问可能性小”的假设,淘汰最近最少使用的数据。Redis通过双向链表实现,但并非严格LRU,而是采样算法以平衡性能和精度。用户可通过调整`maxmemory-samples`等参数优化。尽管LRU简单高效,但无法区分数据重要性和访问频率,可能误淘汰重要数据。合理设置参数、结合其他策略、监控调优是优化LRU使用的关键。
489 1
|
自然语言处理 算法 算法框架/工具
精通 Transformers(一)(4)
精通 Transformers(一)
352 4