HMI-63-【多媒体】空调部分 4
[toc]
本文关键字:
Qt
、HMI
、多媒体
、QList
、空调UI
☀前言
其实呢,写到这里,如果是第一次点击进来这个系列的文章,那你一定是在想着傻子在干嘛,写的啥玩意,所以呢,我还是建议你看看整个系列Qt 汽车 HMI 仪表,毕竟写到这里,我有时候会迷糊,尤其是变量命名上,真的不知道以前的规则了,好多时候都是写到差不多了,回去一看,我曹,偏离了以前的风格,于是又花大量的时间去修改变量名,这个项目呢,持续的时间是在太久了,从之前整个
UI
练练手的想法,到现在想把它做成一个完成度较高的“产品”
它已经已经跟着我走过三家公司了,不是说我工作换的,只是想说这个项目时间真的拖得好长,每家公司的编码风格也不一样,加上自己的懒散,就导致了现在的结果,我也在努力控制着,尽量保持风格一致有点。为了大家更好的阅读,知道我在干啥,所以我也开始整理现在的程序了。我也不知道该怎么表示,毕竟大学里面学得软件工程全部都还给老师了,一点都不记得了。也不是什么大神,没啥框架,就是自己想着瞎写。只能按照我的想法瞎写瞎画,如果还能为大家提供有点帮助或者灵感,那就更好了。
我这里准备了两个文件,一个是当前的一个大致的组织架构图;一个是函数的调用图,尤其是这个函数调用图,我是真的不会表示,大家勉强看看吧。
框架图
我管这个图为框架图,那就叫框架图,会不定期更新,最新的可以看这个网址HMI项目框架
函数调用流程
同上面一样,我就管这个图叫做函数流程调用图,里面用的还是流程图的基本样式,不过我在调用其他类的接口的时候,我把类图的图标拿来使用了,这样大家应该能明白吧。
☮ 比如里面有一个
Loader
类,我想表达的就是我创建一个Loader
的实体对象(为啥是创建呢,就是里面我第一个函数是构造函数,所以是新创建类对象)。然后调用器show
函数。,在后面还有一个finish
函数,因为这个图连没有构造函数,所以这个表示的是调用上面创建对象的finish
函数。同样,会不定期更新,最新的在这里HMI项目函数调用流程
✍本文计划
今天在上面的基础上,把风向和风量控制实现,不过还是部分实现,需要后期再完善。今天没有知识点,主要还是在上一篇中的知识点。剩下就是纯粹的工作量。
☢当前进度
相较昨天,今天实现了风向和风量的显示,并且可以和我们中央控制旋钮联动起来。如下图所示
☯功能实现
1 风向模块
风向模块目前只有三个表示风向的按钮,如下图所示
这里就直接上源代码了
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个表示风量等级的按钮组成,如下图所示:
还是,直接上源码:
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);
}
核心代码如下:
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);
}
核心代码:
◕目前项目进展
目前以完成了HUD和液晶仪表三种模式的开发。三个阶段合并展示如下:
[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/
▶第二阶段 液晶仪表运动模式
✈B站链接:https://www.bilibili.com/video/BV1aq4y1t7H7/
▶第一阶段 HUD和液晶仪表舒适模式
✈B站链接:https://www.bilibili.com/video/BV1qJ411X7Gs/
©说明:
☑ 本项目中所使借鉴原型来自:[吉利] 博瑞GE | 仪表HMI设计、吉利汽车HMI项目。
☑ 多媒体部分是来自吉利博瑞2017旗舰版界面所有权和解释权都归吉利汽车所有。
☑ 设计图的所有权和解释权都归吉利汽车所有。
☑ 本项目所有资源文件均由打不死的小海复刻制作。
☑ 本项目代码暂时不会开源,有需要的源码的可与我联系(博文结尾有我微信)。
☑ 本项目仅限学习交流、禁止商业使用。