HMI-63-【多媒体】空调部分 4

193 阅读7分钟

“我正在参加「掘金·启航计划」”

头图

HMI-63-【多媒体】空调部分 4

HMI-63-【多媒体】空调部分 4☀前言✍本文计划☢当前进度☯功能实现1 风向模块1.1 头文件1.2 源文件2 风量模块2.1 头文件2.2 源文件3 索引函数更新3.1 强转类型3.2 索引更新◕目前项目进展▶第三阶段 液晶仪表节能模式▶第二阶段 液晶仪表运动模式▶第一阶段 HUD和液晶仪表舒适模式©说明:

本文关键字: QtHMI多媒体QList空调UI

☀前言

其实呢,写到这里,如果是第一次点击进来这个系列的文章,那你一定是在想着傻子在干嘛,写的啥玩意,所以呢,我还是建议你看看整个系列Qt 汽车 HMI 仪表,毕竟写到这里,我有时候会迷糊,尤其是变量命名上,真的不知道以前的规则了,好多时候都是写到差不多了,回去一看,我曹,偏离了以前的风格,于是又花大量的时间去修改变量名,这个项目呢,持续的时间是在太久了,从之前整个UI练练手的想法,到现在想把它做成一个完成度较高的“产品”它已经已经跟着我走过三家公司了,不是说我工作换的,只是想说这个项目时间真的拖得好长,每家公司的编码风格也不一样,加上自己的懒散,就导致了现在的结果,我也在努力控制着,尽量保持风格一致有点。

为了大家更好的阅读,知道我在干啥,所以我也开始整理现在的程序了。我也不知道该怎么表示,毕竟大学里面学得软件工程全部都还给老师了,一点都不记得了。也不是什么大神,没啥框架,就是自己想着瞎写。只能按照我的想法瞎写瞎画,如果还能为大家提供有点帮助或者灵感,那就更好了。

我这里准备了两个文件,一个是当前的一个大致的组织架构图;一个是函数的调用图,尤其是这个函数调用图,我是真的不会表示,大家勉强看看吧。

框架图

我管这个图为框架图,那就叫框架图,会不定期更新,最新的可以看这个网址HMI项目框架

image-20220508100300093

函数调用流程

同上面一样,我就管这个图叫做函数流程调用图,里面用的还是流程图的基本样式,不过我在调用其他类的接口的时候,我把类图的图标拿来使用了,这样大家应该能明白吧。

☮ 比如里面有一个Loader类,我想表达的就是我创建一个Loader的实体对象(为啥是创建呢,就是里面我第一个函数是构造函数,所以是新创建类对象)。然后调用器show函数。,在后面还有一个finish函数,因为这个图连没有构造函数,所以这个表示的是调用上面创建对象的finish函数。

同样,会不定期更新,最新的在这里HMI项目函数调用流程

image-20220508111127956

✍本文计划

今天在上面的基础上,把风向和风量控制实现,不过还是部分实现,需要后期再完善。今天没有知识点,主要还是在上一篇中的知识点。剩下就是纯粹的工作量。

☢当前进度

相较昨天,今天实现了风向和风量的显示,并且可以和我们中央控制旋钮联动起来。如下图所示

☯功能实现

1 风向模块

风向模块目前只有三个表示风向的按钮,如下图所示

image-20220504234157212

这里就直接上源代码了

1.1 头文件

 #ifndef MFD_AIRCONDITIONER_FANDIRECTION_H
 #define MFD_AIRCONDITIONER_FANDIRECTION_H
 ​
 #include <QWidget>
 ​
 namespace Ui {
 class MFD_AirConditioner_FanDirection;
 }
 ​
 class MFD_AirConditioner_FanDirection : public QWidget
 {
     Q_OBJECT
 ​
 public:
     explicit MFD_AirConditioner_FanDirection(QWidget *parent = nullptr);
     ~MFD_AirConditioner_FanDirection();
     /**
      * @brief enter
      * 进入,与按下功能一致
      */
     void enter();
     /**
      * @brief releaseEnter
      * 进入按钮松开,与按钮松开功能一致
      */
     void releaseEnter();
 ​
     void selected(int index,bool select);
 private slots:
     void on_pushButton_up_pressed();
 ​
     void on_pushButton_up_released();
 ​
     void on_pushButton_zhong_pressed();
 ​
     void on_pushButton_zhong_released();
 ​
     void on_pushButton_down_pressed();
 ​
     void on_pushButton_down_released();
 ​
 private:
     Ui::MFD_AirConditioner_FanDirection *ui;
 };
 ​
 #endif // MFD_AIRCONDITIONER_FANDIRECTION_H
 ​

1.2 源文件

 #include "mfd_airconditioner_fandirection.h"
 #include "ui_mfd_airconditioner_fandirection.h"
 #include "MultifunctionDisplay/MFD_AirConditioner/mfd_airconditioner.h"
 MFD_AirConditioner_FanDirection::MFD_AirConditioner_FanDirection(QWidget *parent) :
     QWidget(parent),
     ui(new Ui::MFD_AirConditioner_FanDirection)
 {
     ui->setupUi(this);
 }
 ​
 MFD_AirConditioner_FanDirection::~MFD_AirConditioner_FanDirection()
 {
     delete ui;
 }
 ​
 void MFD_AirConditioner_FanDirection::enter()
 {
 ​
 }
 ​
 void MFD_AirConditioner_FanDirection::releaseEnter()
 {
 ​
 }
 ​
 void MFD_AirConditioner_FanDirection::selected(int index, bool select)
 {
     switch (index) {
     case AirConditionerIndex::AC_fandirection_up:
         if(select)
         {
             ui->pushButton_up->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanDirection/up_selected.png);}");
         }
         else
         {
             ui->pushButton_up->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanDirection/up.png);}");
         }
         break;
     case AirConditionerIndex::AC_fandirection_mid:
         if(select)
         {
             ui->pushButton_zhong->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanDirection/zhong_selected.png);}");
         }
         else
         {
             ui->pushButton_zhong->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanDirection/zhong.png);}");
         }
         break;
     case AirConditionerIndex::AC_fandirection_down:
         if(select)
         {
             ui->pushButton_down->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanDirection/down_selected.png);}");
         }
         else
         {
             ui->pushButton_down->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanDirection/down.png);}");
         }
         break;
     default:
         break;
     }
 }
 ​
 void MFD_AirConditioner_FanDirection::on_pushButton_up_pressed()
 {
 ​
 }
 ​
 ​
 void MFD_AirConditioner_FanDirection::on_pushButton_up_released()
 {
 ​
 }
 ​
 ​
 void MFD_AirConditioner_FanDirection::on_pushButton_zhong_pressed()
 {
 ​
 }
 ​
 ​
 void MFD_AirConditioner_FanDirection::on_pushButton_zhong_released()
 {
 ​
 }
 ​
 ​
 void MFD_AirConditioner_FanDirection::on_pushButton_down_pressed()
 {
 ​
 }
 ​
 ​
 void MFD_AirConditioner_FanDirection::on_pushButton_down_released()
 {
 ​
 }
 ​
 ​
 ​

2 风量模块

风量模块也是,由8个表示风量等级的按钮组成,如下图所示:

image-20220504234430457

还是,直接上源码:

2.1 头文件

 #ifndef MFD_AIRCONDITIONER_FANLEVEL_H
 #define MFD_AIRCONDITIONER_FANLEVEL_H
 ​
 #include <QWidget>
 ​
 namespace Ui {
 class MFD_AirConditioner_FanLevel;
 }
 ​
 class MFD_AirConditioner_FanLevel : public QWidget
 {
     Q_OBJECT
 ​
 public:
     explicit MFD_AirConditioner_FanLevel(QWidget *parent = nullptr);
     ~MFD_AirConditioner_FanLevel();
     /**
      * @brief selected
      * @param select
      * 是否选中
      */
     void selected(bool select);
     /**
      * @brief setFanLevel
      * @param level
      * 设置风量等级
      */
     void setFanLevel(int level);
 signals:
     void signal_fanLevelChanged(int level);
 ​
 private slots:
     void on_pushButton_1_pressed();
     void on_pushButton_2_pressed();
     void on_pushButton_3_pressed();
     void on_pushButton_4_pressed();
     void on_pushButton_5_pressed();
     void on_pushButton_6_pressed();
     void on_pushButton_7_pressed();
     void on_pushButton_8_pressed();
 ​
 ​
 ​
 private:
     Ui::MFD_AirConditioner_FanLevel *ui;
 };
 ​
 #endif // MFD_AIRCONDITIONER_FANLEVEL_H
 ​

2.2 源文件

 #include "mfd_airconditioner_fanlevel.h"
 #include "ui_mfd_airconditioner_fanlevel.h"
 ​
 MFD_AirConditioner_FanLevel::MFD_AirConditioner_FanLevel(QWidget *parent) :
     QWidget(parent),
     ui(new Ui::MFD_AirConditioner_FanLevel)
 {
     ui->setupUi(this);
     selected(false);
 ​
     ui->pushButton_1->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/0.png);}");
     ui->pushButton_2->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/0.png);}");
     ui->pushButton_3->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/0.png);}");
     ui->pushButton_4->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/0.png);}");
     ui->pushButton_5->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/0.png);}");
     ui->pushButton_6->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/0.png);}");
     ui->pushButton_7->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/0.png);}");
     ui->pushButton_8->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/0.png);}");
 }
 ​
 MFD_AirConditioner_FanLevel::~MFD_AirConditioner_FanLevel()
 {
     delete ui;
 }
 ​
 void MFD_AirConditioner_FanLevel::selected(bool select)
 {
     if(select)
         ui->label_fanSelected->show();
     else
         ui->label_fanSelected->hide();
 }
 ​
 void MFD_AirConditioner_FanLevel::on_pushButton_1_pressed()
 {
     setFanLevel(1);
 }
 ​
 void MFD_AirConditioner_FanLevel::on_pushButton_2_pressed()
 {
     setFanLevel(2);
 }
 ​
 void MFD_AirConditioner_FanLevel::on_pushButton_3_pressed()
 {
     setFanLevel(3);
 }
 ​
 void MFD_AirConditioner_FanLevel::on_pushButton_4_pressed()
 {
     setFanLevel(4);
 }
 ​
 void MFD_AirConditioner_FanLevel::on_pushButton_5_pressed()
 {
     setFanLevel(5);
 }
 ​
 void MFD_AirConditioner_FanLevel::on_pushButton_6_pressed()
 {
     setFanLevel(6);
 }
 ​
 void MFD_AirConditioner_FanLevel::on_pushButton_7_pressed()
 {
     setFanLevel(7);
 }
 ​
 void MFD_AirConditioner_FanLevel::on_pushButton_8_pressed()
 {
     setFanLevel(8);
 }
 ​
 void MFD_AirConditioner_FanLevel::setFanLevel(int level)
 {
     emit signal_fanLevelChanged(level);
     ui->pushButton_1->setStyleSheet(QString("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/%1.png);}").arg(level >= 1 ? 1 : 0));
     ui->pushButton_2->setStyleSheet(QString("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/%1.png);}").arg(level >= 2 ? 2 : 0));
     ui->pushButton_3->setStyleSheet(QString("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/%1.png);}").arg(level >= 3 ? 3 : 0));
     ui->pushButton_4->setStyleSheet(QString("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/%1.png);}").arg(level >= 4 ? 4 : 0));
     ui->pushButton_5->setStyleSheet(QString("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/%1.png);}").arg(level >= 5 ? 5 : 0));
     ui->pushButton_6->setStyleSheet(QString("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/%1.png);}").arg(level >= 6 ? 6 : 0));
     ui->pushButton_7->setStyleSheet(QString("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/%1.png);}").arg(level >= 7 ? 7 : 0));
     ui->pushButton_8->setStyleSheet(QString("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerFanLevel/%1.png);}").arg(level >= 8 ? 8 : 0));
 }
 ​
 ​

3 索引函数更新

这里有了更多的类型,但是原理还是一样

3.1 强转类型

通过类型转换,添加到我们的QList中。代码如下:

 void MFD_AirConditioner::initModules()
 {
     m_ModulesList.clear();
 ​
     ui->myPushButton_auto->setText("AUTO");
     m_ModulesList.append(ui->myPushButton_auto);
 ​
     ui->myPushButton_ac->setText("AC");
     m_ModulesList.append(ui->myPushButton_ac);
 ​
     ui->myPushButton_maxAC->setText("MAX A/C");
     m_ModulesList.append(ui->myPushButton_maxAC);
 ​
     ui->myPushButton_cycle->setPicText(":/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerPushButton/cycle.png",
                                        ":/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerPushButton/cycle_1.png");
     m_ModulesList.append(ui->myPushButton_cycle);
 ​
     ui->myPushButton_aqs->setText("AQS");
     m_ModulesList.append(ui->myPushButton_aqs);
 ​
     ui->myPushButton_dual->setText("DUAL");
     m_ModulesList.append(ui->myPushButton_dual);
 ​
 ​
     m_ModulesList.append(reinterpret_cast<MFD_AirConditioner_PushButon*>(ui->airConditionerNumberControl_L));
 ​
     m_ModulesList.append(reinterpret_cast<MFD_AirConditioner_PushButon*>(m_FanDirection));
     m_ModulesList.append(reinterpret_cast<MFD_AirConditioner_PushButon*>(m_FanDirection));
     m_ModulesList.append(reinterpret_cast<MFD_AirConditioner_PushButon*>(m_FanDirection));
 ​
     m_ModulesList.append(reinterpret_cast<MFD_AirConditioner_PushButon*>(ui->pushButton_off));
     m_ModulesList.append(reinterpret_cast<MFD_AirConditioner_PushButon*>(m_FanLevel));
 ​
     m_ModulesList.append(reinterpret_cast<MFD_AirConditioner_PushButon*>(ui->airConditionerNumberControl_R));
 ​
     ui->myPushButton_rear->setText("REAR");
     m_ModulesList.append(ui->myPushButton_rear);
 ​
     ui->myPushButton_rear->setICON(":/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/AirConditionerPushButton/lock.png");
 ​
     ui->myPushButton_ion->setText("ION");
     m_ModulesList.append(ui->myPushButton_ion);
 ​
 }

核心代码如下:

image-20220504234925056

3.2 索引更新

 void MFD_AirConditioner::updateSelect()
 {
 ​
     /**
      * 这里使用迭代器有点问题,因为m_ModulesList有多个类型了
      */
     //    QListIterator<MFD_AirConditioner_PushButon*> list(m_ModulesList);
     //    while (list.hasNext()) {
     //        list.next()->selected(false);
     //    }
 ​
     for(auto i = 0;i< m_ModulesList.count();i++)
     {
 ​
         if(i == AirConditionerIndex::AC_number_L || i == AirConditionerIndex::AC_number_R)
         {
             reinterpret_cast<MFD_AirConditionerNumberControl*>(m_ModulesList[i])->selected(false);
         }
         else if(i == AirConditionerIndex::AC_fandirection_up || i == AirConditionerIndex::AC_fandirection_mid || i == AirConditionerIndex::AC_fandirection_down)
         {
 ​
             switch (i) {
             case AirConditionerIndex::AC_fandirection_up:
                 reinterpret_cast<MFD_AirConditioner_FanDirection*>(m_ModulesList[i])->selected(AirConditionerIndex::AC_fandirection_up,false);
                 break;
             case AirConditionerIndex::AC_fandirection_mid:
                 reinterpret_cast<MFD_AirConditioner_FanDirection*>(m_ModulesList[i])->selected(AirConditionerIndex::AC_fandirection_mid,false);
                 break;
             case AirConditionerIndex::AC_fandirection_down:
                 reinterpret_cast<MFD_AirConditioner_FanDirection*>(m_ModulesList[i])->selected(AirConditionerIndex::AC_fandirection_down,false);
                 break;
             default:
                 break;
             }
 ​
 ​
 ​
         }
         else if(i == AirConditionerIndex::AC_off)
         {
             reinterpret_cast<QPushButton*>(m_ModulesList[i])->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/off.png);}");
         }
         else if(i == AirConditionerIndex::AC_fanlevel)
         {
             reinterpret_cast<MFD_AirConditioner_FanLevel*>(m_ModulesList[i])->selected(false);
         }
         else
             m_ModulesList[i]->selected(false);
     }
 ​
 ​
     if(m_SelectIndex == AirConditionerIndex::AC_number_L || m_SelectIndex == AirConditionerIndex::AC_number_R)
     {
         reinterpret_cast<MFD_AirConditionerNumberControl*>(m_ModulesList[m_SelectIndex])->selected(true);
     }
     else if(m_SelectIndex == AirConditionerIndex::AC_fandirection_up || m_SelectIndex == AirConditionerIndex::AC_fandirection_mid || m_SelectIndex == AirConditionerIndex::AC_fandirection_down)
     {
         switch (m_SelectIndex) {
         case AirConditionerIndex::AC_fandirection_up:
             reinterpret_cast<MFD_AirConditioner_FanDirection*>(m_ModulesList[m_SelectIndex])->selected(AirConditionerIndex::AC_fandirection_up,true);
             break;
         case AirConditionerIndex::AC_fandirection_mid:
             reinterpret_cast<MFD_AirConditioner_FanDirection*>(m_ModulesList[m_SelectIndex])->selected(AirConditionerIndex::AC_fandirection_mid,true);
             break;
         case AirConditionerIndex::AC_fandirection_down:
             reinterpret_cast<MFD_AirConditioner_FanDirection*>(m_ModulesList[m_SelectIndex])->selected(AirConditionerIndex::AC_fandirection_down,true);
             break;
         default:
             break;
         }
     }
     else if(m_SelectIndex == AirConditionerIndex::AC_off)
     {
         reinterpret_cast<QPushButton*>(m_ModulesList[m_SelectIndex])->setStyleSheet("QPushButton{border-image: url(:/AirConditioner/Resources/MultifunctionDisplay/AirConditioner/off_1.png);}");
     }
     else if(m_SelectIndex == AirConditionerIndex::AC_fanlevel)
     {
         reinterpret_cast<MFD_AirConditioner_FanLevel*>(m_ModulesList[m_SelectIndex])->selected(true);
     }
     else
         m_ModulesList[m_SelectIndex]->selected(true);
 }

核心代码:

image-20220504235046793


◕目前项目进展

目前以完成了HUD和液晶仪表三种模式的开发。三个阶段合并展示如下:

[video(video-yznBr6e3-1648369267384)(type-bilibili)(url-player.bilibili.com/player.html…img-blog.csdnimg.cn/img_convert…基于Qt的汽车仪表模拟 3.0)]

▶第三阶段 液晶仪表节能模式

✈B站链接:www.bilibili.com/video/BV1WS…

▶第二阶段 液晶仪表运动模式

✈B站链接:www.bilibili.com/video/BV1aq…

▶第一阶段 HUD和液晶仪表舒适模式

✈B站链接:www.bilibili.com/video/BV1qJ…

©说明:

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

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

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

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

☑ 本项目代码暂时不会开源,有需要的源码的可与我联系(博文结尾有我微信)。

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