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

简介: 其实呢,写到这里,如果是第一次点击进来这个系列的文章,那你一定是在想着傻子在干嘛,写的啥玩意,所以呢,我还是建议你看看整个系列[Qt 汽车 HMI 仪表](https://dreamlife.blog.csdn.net/category_9146909_2.html),毕竟写到这里,我有时候会迷糊,尤其是变量命名上,真的不知道以前的规则了,好多时候都是写到差不多了,回去一看,我曹,偏离了以前的风格,于是又花大量的时间去修改变量名,这个项目呢,持续的时间是在太久了,从之前整个`UI`练练手的想法,到现在想把它做成一个完成度较高的`“产品”`它已经已经跟着我走过三家公司了,不是说我工作换的,只是想

头图

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

[toc]

本文关键字: 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-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旗舰版界面所有权和解释权都归吉利汽车所有。

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

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

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

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


博客签名2021

相关文章
|
29天前
|
网络架构
海康大华云台摄像机使用ONVIF无法控制云台问题
海康大华云台摄像机使用ONVIF无法控制云台问题
38 1
HMI-60-【多媒体】空调部分 1
今天我们搞空调的按钮,今天这里我们不会堆砌大量的素材,而是用一个自定义的Button来实现这些,可以看到我们这次的空调按钮有以下元素
|
6月前
|
索引
HMI-61-【多媒体】空调部分 2
昨天我们已经实现了自定义的按钮了,今天我们把已经定义好的按钮和我们的控制台联动起来,使我们的多媒体部分不仅可以触屏控制,可一个使用控制台的旋钮来控制。演示如下
|
6月前
|
索引
HMI-62-【多媒体】空调部分 3
今天接着昨天的思路来搞,实现空调数字模块,因为素材里面的空调是双区空调,所以我还是自定义了一个模块,这个实现不难,可以参考上一篇自定义个按钮。
HMI-59-【多媒体】收音机 2
今天接着搞收音机,今天我们将把控制台的模拟中控旋钮信号引进到收音机里面来,来控制我们收音机调频。
HMI-57-【多媒体】收音机 1
前面几篇已经音乐播放器简单搞了一下,可以放音乐了。今天艺术家发来了收音机的界面,今天先搞搞。
HMI-52-【多媒体】音乐播放器 1
今天我们搞音乐播放器,哎嗨,这个东西要是往细碎了搞,事情还真不少,今天就先努力实现面上的内容。
HMI-53-【多媒体】音乐播放器 2
今天我们接着搞我们的音乐播放器,今天我把们昨天剩下的那些布局搞一搞,后面再实现细节,今天我们把下面的菜单和逻辑实现了,以及上次漏掉的右上角的子菜单按钮。
HMI-56-【多媒体】音乐播放器 5
上一篇中实现了音乐播放的后台线程,夜里睡觉也没有睡踏实,总是感觉不合适,所以今天还是决定重新搞一下。
HMI-55-【多媒体】音乐播放器 4
今天我们接着搞音乐播放器,今天主要实现音乐播放器的播放音频功能