国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源)

這篇具有很好參考價值的文章主要介紹了基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

前言:本文為手把手教學(xué)智能車載終端項(xiàng)目Linux+QT),該項(xiàng)目是綜合性非常強(qiáng)的 Linux 系列項(xiàng)目!項(xiàng)目核心板使用 NXPIMX6ULL 作為 CPU,整體實(shí)現(xiàn)了簡化版本的車載終端功能需求。項(xiàng)目可以學(xué)習(xí)的點(diǎn)非常多,包含:IMX6ULL 的硬件驅(qū)動,QT 的移植與 Linux 多進(jìn)程操作等。該項(xiàng)目的源代碼適用于正點(diǎn)原子的出廠鏡像,只學(xué)習(xí)應(yīng)用層開發(fā)的也可以嘗試學(xué)習(xí)該項(xiàng)目!希望該篇博客可以給諸位些許收獲,博客篇尾代碼開源!

硬件實(shí)物圖:

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

效果圖:

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

考慮到該項(xiàng)目整體流程過于復(fù)雜化,作者將重點(diǎn)側(cè)重軟件即 Linux+QT 的框架實(shí)現(xiàn)!該項(xiàng)目的好處是:源代碼可以直接在正點(diǎn)原子 IMX6ULL 開發(fā)板上使用!如果只學(xué)習(xí)應(yīng)用層開發(fā)的讀者朋友可以直接用正點(diǎn)原子的出廠鏡像即可!

一、智能車載終端概述

智能車載終端是一種用于對運(yùn)輸車輛進(jìn)行現(xiàn)代化管理的設(shè)備。它融合了 GPS 技術(shù)、里程定位技術(shù)以及汽車黑匣技術(shù),可以用于多種用途,包括 DVR 行車記錄儀、智能車載后視鏡、網(wǎng)約車運(yùn)營終端、兩客一危車隊(duì)管理終端等。智能車載終端開始普及,使得汽車行業(yè)進(jìn)入智能化加速階段。相較于傳統(tǒng)終端產(chǎn)品,智能車載終端能夠減少平臺許可費(fèi)用、減少研發(fā)費(fèi)用、縮短研發(fā)與生產(chǎn)時間、覆蓋終端知識產(chǎn)權(quán)、快速產(chǎn)品規(guī)劃。智能車載終端往往需要覆蓋大量商用車輛,企業(yè)對性價比存在一定需求,而智能模組產(chǎn)品能夠助力企業(yè)快速進(jìn)行產(chǎn)品迭代,實(shí)現(xiàn)更高效地研發(fā)。

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

隨著科技與電車技術(shù)發(fā)展,智能車載終端的功能和要求越來越復(fù)雜化和高級化。作者博客篇幅有限,所以這次僅給諸位讀者教學(xué)簡單的 3 個功能的實(shí)現(xiàn)和功能切換方法!?

1.1 車載終端:影音播放器

目前汽車終端上,車主使用最多的應(yīng)該還是音頻類設(shè)備。比如:收音機(jī)、電臺、音樂播放器、聽書等等。所以,車載終端上必須使用成功驅(qū)動音頻類芯片(I2S等)。該音頻設(shè)備無論是借助第 3 方音樂播放器還是自主設(shè)計(jì)一款音樂播放器,都是在車載終端上必不可少的!

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

1.2 車載終端:地圖功能

車載終端上的地圖功能同樣是不可或缺的,車主往往需要進(jìn)行地圖導(dǎo)航(手機(jī)導(dǎo)航可能用得更多,但是功能你必須要有)。地圖導(dǎo)航依賴的功能實(shí)現(xiàn)就比較復(fù)雜,需要驅(qū)動 GPS 等,同時,根據(jù) GPS 等信息結(jié)合地圖軟件進(jìn)行定位導(dǎo)航!

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

1.3 車載終端:倒車影像

如自動駕駛一般,科技的進(jìn)步往往是降低人類的駕駛難度。倒車入庫等操作屬于有難度的駕駛技術(shù),結(jié)合現(xiàn)代科技的倒車影像等技術(shù)??梢苑奖丬囍骺焖偻瓿刹僮?,享受愉快生活!

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

1.4 車載終端:雜項(xiàng)功能

車載終端是一個非常復(fù)雜且常用的裝置,隨著電車與自動駕駛技術(shù)的不斷升級迭代,需求也與日俱增!我們往往需要在終端上附加許許多多其他的功能,比如:智能家居聯(lián)動、車內(nèi)環(huán)境監(jiān)測、天氣預(yù)報與網(wǎng)上瀏覽等!

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

二、IMX6ULL車載項(xiàng)目的驅(qū)動

作者強(qiáng)調(diào):考慮到篇幅有限,作者本篇博客僅進(jìn)行部分功能實(shí)現(xiàn)教學(xué),并側(cè)重應(yīng)用層的實(shí)現(xiàn)!基礎(chǔ)薄弱的朋友,可以直接使用正點(diǎn)原子出廠的鏡像程序進(jìn)行項(xiàng)目復(fù)現(xiàn)!

2.1 音頻設(shè)備驅(qū)動

音頻 CODEC 支持 I2S 協(xié)議,那么主控制器也必須支持 I2S 協(xié)議,I.MX6ULL 也提供了一個叫做 SAI 的外設(shè),全稱為 SynchronousAudio Interface,翻譯過來就是同步音頻接口。

I.MX6ULLSAI 是一個全雙工、支持幀同步的串行接口,支持I2S、AC97、TDM和音頻DSP。

正點(diǎn)原子 ALPHA 開發(fā)板音頻原理圖如圖所示:

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

NXP 官方已經(jīng)寫好了 WM8960 驅(qū)動,因此我們直接配置內(nèi)核使能 WM8960 驅(qū)動即可,按照如下所示步驟使能 WM8960 驅(qū)動。

1、根據(jù)IMX6ULL的引腳原理圖修改設(shè)備樹;

2、使能內(nèi)核的 WM8960 驅(qū)動;

2.1、取消 ALSA 模擬 OSS API

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

2.2、使能 I.MX6ULL 的 WM8960 驅(qū)動

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

完整可見:《【正點(diǎn)原子】I.MX6U嵌入式Linux驅(qū)動開發(fā)指南V1.6》 第 1544 頁

2.2 LCD驅(qū)動

正點(diǎn)原子的 IMX6ULL 與 NXP 官方的 “藍(lán)版”相似度極高,就是仿照著進(jìn)行制作的(一般情況下,大都公司產(chǎn)品的項(xiàng)目板也是如此)

6ULL 的 eLCDIF 接口驅(qū)動程序 NXP 已經(jīng)編寫好了,因此 LCD 驅(qū)動部分我們不需要去修改。我們需要做的就是按照所使用的 LCD 來修改設(shè)備樹。重點(diǎn)要注意三個地方:

①、LCD 所使用的 IO 配置。
②、LCD 屏幕節(jié)點(diǎn)修改,修改相應(yīng)的屬性值,換成我們所使用的 LCD 屏幕參數(shù)。
③、LCD 背光節(jié)點(diǎn)信息修改,要根據(jù)實(shí)際所使用的背光 IO 來修改相應(yīng)的設(shè)備節(jié)點(diǎn)信息。

1、修改 LCD 所使用的 IO 配置;

檢查一下設(shè)備樹中 LCD 所使用的 IO 配置,這個其實(shí) NXP 都已經(jīng)給我們寫好了,不需要修改!

2、LCD 屏幕參數(shù)節(jié)點(diǎn)信息修改

imx6ull-alientek-emmc.dts 文件中找到 lcdif 節(jié)點(diǎn),節(jié)點(diǎn)內(nèi)容如下所示:

&lcdif {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_lcdif_dat
		     &pinctrl_lcdif_ctrl>;

	display = <&display0>;
	status = "okay"; 

	/* 7寸1024*600 */
	display0: display {
		bits-per-pixel = <24>;		/*  */
		bus-width = <24>;			/* LCD屏幕數(shù)據(jù)線有多少 */

		display-timings {
			native-mode = <&timing0>;
			timing0: timing0 {
			clock-frequency = <51200000>;		/* 時鐘頻率51.2MHZ */
			hactive = <1024>;					/* 水平像素點(diǎn) */
			vactive = <600>;					/* 垂直像素點(diǎn) */
			hfront-porch = <160>;
			hback-porch = <140>;
			hsync-len = <20>;
			vback-porch = <20>;
			vfront-porch = <12>;
			vsync-len = <3>;
			
			/* 像素點(diǎn)有效電平值 */
			hsync-active = <0>;
			vsync-active = <0>;
			de-active = <1>;
			pixelclk-active = <0>;
			};
		};
	};

	/* 4.3寸480*272 */
	/* display0: display {
		bits-per-pixel = <24>;
		bus-width = <24>;

		display-timings {
			native-mode = <&timing0>;
			timing0: timing0 {
			clock-frequency = <9000000>;
			hactive = <480>;
			vactive = <272>;
			hfront-porch = <5>;
			hback-porch = <40>;
			hsync-len = <1>;
			vback-porch = <8>;
			vfront-porch = <8>;
			vsync-len = <1>;

			hsync-active = <0>;
			vsync-active = <0>;
			de-active = <1>;
			pixelclk-active = <0>;
			};
		};
	};*/

	/* 4.3寸800*480 */
	/* display0: display {
		bits-per-pixel = <24>;
		bus-width = <24>;

		display-timings {
			native-mode = <&timing0>;
			timing0: timing0 {
			clock-frequency = <31000000>;
			hactive = <800>;
			vactive = <480>;
			hfront-porch = <40>;
			hback-porch = <88>;
			hsync-len = <48>;
			vback-porch = <32>;
			vfront-porch = <13>;
			vsync-len = <3>;

			hsync-active = <0>;
			vsync-active = <0>;
			de-active = <1>;
			pixelclk-active = <0>;
			};
		};
	};*/

};

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

根據(jù)自己使用 LCD 的實(shí)際參數(shù)修改紅色框中的各個參數(shù)信息!

3、LCD 屏幕背光節(jié)點(diǎn)信息

正點(diǎn)原子的 LCD 接口背光控制 IO 連接到了 I.MX6U 的 GPIO1_IO08 引腳上,GPIO1_IO08復(fù)用為 PWM1_OUT,通過 PWM 信號來控制 LCD 屏幕背光的亮度。正點(diǎn)原子 I.MX6U-ALPHA 開發(fā)板的 LCD 背光引腳和 NXP 官方 EVK 開發(fā)板的背光引腳一樣,因此背光的設(shè)備樹節(jié)點(diǎn)是不需要修改的。

設(shè)置 backlight 節(jié)點(diǎn),這個 NXP 已經(jīng)給我們設(shè)置好了,大家在 imx6ull-alientek-emmc.dts 文件中找到如下內(nèi)容:

backlight {
	compatible = "pwm-backlight";
	pwms = <&pwm1 0 5000000>;
	brightness-levels = <0 4 8 16 32 64 128 255>;
	default-brightness-level = <7>;
	status = "okay";
};

第 3 行,設(shè)置背光使用 pwm1,PWM 頻率為 200Hz
第 4 行,設(shè)置背 8 級背光(0~7),分別為 0、4、8、16、32、64、128、255,對應(yīng)占空比為0%、1.57%、3.13%、6.27%、12.55%、25.1%、50.19%、100%,如果嫌少的話可以自行添加一些其他的背光等級值。
第 5 行,設(shè)置默認(rèn)背光等級為 6,也就是 50.19%?的亮度。

完整可見:《【正點(diǎn)原子】I.MX6U嵌入式Linux驅(qū)動開發(fā)指南V1.6》 第 1386 頁

2.3 AP3216C驅(qū)動

本項(xiàng)目作者替換的智能家居 APP 的功能頁為 AP3216C 的車載內(nèi)室監(jiān)測功能!

篇幅有限,AP3216的使用和 QT 功能頁設(shè)計(jì)博客:http://t.csdn.cn/cN6p1

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

三、QT智能車載裝置

3.1 QMusic音樂播放器

音樂播放器是各家嵌入式機(jī)構(gòu) QT 練習(xí)的常規(guī)項(xiàng)目,QMediaPlayer 類是一個高級媒體播放類。它可以用來播放歌曲、電影和網(wǎng)絡(luò)廣播等內(nèi)容。一般用于播放 mp3 和 mp4 等等媒體文件。QMediaPlayer 類常常與 QMediaPlaylist 類一起使用。可以很輕松的設(shè)計(jì)一個自己喜歡的音樂播放器與視頻播放器。

QMediaPlayer 提供了很多信號,我們可以使用這些信號來完成音樂播放器的一系列操作,比如媒體狀態(tài)改變的信號 stateChanged(QMediaPlayer::State state),判斷這個 state 的狀態(tài)就可以知道什么時候媒體暫停、播放、停止了。

★在項(xiàng)目文件 14_musicplayer.pro 文件第一行添加的代碼:multimedia

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

在頭文件 “mainwindow.h” 具體代碼如下:

/******************************************************************
* @projectName   musicplayer
* @brief         mainwindow.h
* @author        混分巨獸龍某某
* @email         1178305328@qq.com
*******************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QPushButton>
#include <QSlider>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QListWidget>
#include <QLabel>
#include <QSpacerItem>
#include <QDebug>

/* 媒體信息結(jié)構(gòu)體 */
struct MediaObjectInfo {
    /* 用于保存歌曲文件名 */
    QString fileName;
    /* 用于保存歌曲文件路徑 */
    QString filePath;
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 媒體播放器,用于播放音樂 */
    QMediaPlayer *musicPlayer;

    /* 媒體列表 */
    QMediaPlaylist *mediaPlaylist;

    /* 音樂列表 */
    QListWidget *listWidget;

    /* 播放進(jìn)度條 */
    QSlider *durationSlider;

    /* 音樂播放器按鈕 */
    QPushButton *pushButton[7];
    QPushButton *exit_button;


    /* 垂直布局 */
    QVBoxLayout *vBoxLayout[3];

    /* 水平布局 */
    QHBoxLayout *hBoxLayout[4];

    /* 垂直容器 */
    QWidget *vWidget[3];

    /* 水平容器 */
    QWidget *hWidget[4];

    /* 標(biāo)簽文本 */
    QLabel *label[4];

    /* 用于遮罩 */
    QWidget *listMask;

    /* 音樂布局函數(shù) */
    void musicLayout();

    /* 主窗體大小重設(shè)大小函數(shù)重寫 */
    void resizeEvent(QResizeEvent *event);

    /* 媒體信息存儲 */
    QVector<MediaObjectInfo> mediaObjectInfo;

    /* 掃描歌曲 */
    void scanSongs();

    /* 媒體播放器類初始化 */
    void mediaPlayerInit();

private slots:
    /* 播放按鈕點(diǎn)擊 */
    void btn_play_clicked();

    /* 下一曲按鈕點(diǎn)擊*/
    void btn_next_clicked();

    /* 上一曲按鈕點(diǎn)擊 */
    void btn_previous_clicked();

    /* 媒體狀態(tài)改變 */
    void mediaPlayerStateChanged(QMediaPlayer::State);

    /* 列表單擊 */
    void listWidgetCliked(QListWidgetItem*);

    /* 媒體列表項(xiàng)改變 */
    void mediaPlaylistCurrentIndexChanged(int);

    /* 媒體總長度改變 */
    void musicPlayerDurationChanged(qint64);

    /* 媒體播放位置改變 */
    void mediaPlayerPositionChanged(qint64);

    /* 播放進(jìn)度條松開 */
    void durationSliderReleased();
};
#endif // MAINWINDOW_H

在源文件 “mainwindow.cpp” 具體代碼如下:

#include "mainwindow.h"
#include <QCoreApplication>
#include <QFileInfoList>
#include <QDir>
#include <QProcess>


QProcess * mypro;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 布局初始化 */
    musicLayout();

    /* 媒體播放器初始化 */
    mediaPlayerInit();

    /* 掃描歌曲 */
    scanSongs();

    /* 按鈕信號槽連接 */
    connect(pushButton[0], SIGNAL(clicked()),
            this, SLOT(btn_previous_clicked()));
    connect(pushButton[1], SIGNAL(clicked()),
            this, SLOT(btn_play_clicked()));
    connect(pushButton[2], SIGNAL(clicked()),
            this, SLOT(btn_next_clicked()));

    /* 媒體信號槽連接 */
    connect(musicPlayer,
            SIGNAL(stateChanged(QMediaPlayer::State)),
            this,
            SLOT(mediaPlayerStateChanged(QMediaPlayer::State)));
    connect(mediaPlaylist,
            SIGNAL(currentIndexChanged(int)),
            this,
            SLOT(mediaPlaylistCurrentIndexChanged(int)));
    connect(musicPlayer, SIGNAL(durationChanged(qint64)),
            this,
            SLOT(musicPlayerDurationChanged(qint64)));
    connect(musicPlayer,
            SIGNAL(positionChanged(qint64)),
            this,
            SLOT(mediaPlayerPositionChanged(qint64)));

    /* 列表信號槽連接 */
    connect(listWidget, SIGNAL(itemClicked(QListWidgetItem*)),
            this, SLOT(listWidgetCliked(QListWidgetItem*)));

    /* slider信號槽連接 */
    connect(durationSlider, SIGNAL(sliderReleased()),
            this, SLOT(durationSliderReleased()));

    /* 失去焦點(diǎn) */
    this->setFocus();

    exit_button = new QPushButton(this);
    exit_button->setMinimumSize(50, 50);
    exit_button->setMaximumSize(50, 50);
    exit_button->move(760,440);
    exit_button->setStyleSheet("QPushButton{background:yellow}");

    connect(exit_button,&QPushButton::clicked,[=](){
        mypro->close();
        exit(1);//退出程序
    });
}

void MainWindow::musicLayout()
{
    /* 設(shè)置位置與大小,這里固定為800, 480 */
    this->setGeometry(0, 0, 800, 480);
    QPalette pal;

    /* 按鈕 */
    for (int i = 0; i < 7; i++)
        pushButton[i] = new QPushButton();

    /* 標(biāo)簽 */
    for (int i = 0; i < 4; i++)
        label[i] = new QLabel();

    for (int i = 0; i < 3; i++) {
        /* 垂直容器 */
        vWidget[i] = new QWidget();
        vWidget[i]->setAutoFillBackground(true);
        /* 垂直布局 */
        vBoxLayout[i] = new QVBoxLayout();
    }

    for (int i = 0; i < 4; i++) {
        /* 水平容器 */
        hWidget[i] = new QWidget();
        hWidget[i]->setAutoFillBackground(true);
        /* 水平布局 */
        hBoxLayout[i] = new QHBoxLayout();
    }

    /* 播放進(jìn)度條 */
    durationSlider = new QSlider(Qt::Horizontal);
    durationSlider->setMinimumSize(300, 15);
    durationSlider->setMaximumHeight(15);
    durationSlider->setObjectName("durationSlider");

    /* 音樂列表 */
    listWidget = new QListWidget();
    listWidget->setObjectName("listWidget");
    listWidget->resize(310, 265);
    listWidget->setVerticalScrollBarPolicy(
                Qt::ScrollBarAlwaysOff);
    listWidget->setHorizontalScrollBarPolicy(
                Qt::ScrollBarAlwaysOff);

    /* 列表遮罩 */
    listMask = new QWidget(listWidget);
    listMask->setMinimumSize(310, 50);
    listMask->setMinimumHeight(50);
    listMask->setObjectName("listMask");
    listMask->setGeometry(0,
                          listWidget->height() - 50,
                          310,
                          50);


    /* 設(shè)置對象名稱 */
    pushButton[0]->setObjectName("btn_previous");
    pushButton[1]->setObjectName("btn_play");
    pushButton[2]->setObjectName("btn_next");
    pushButton[3]->setObjectName("btn_favorite");
    pushButton[4]->setObjectName("btn_mode");
    pushButton[5]->setObjectName("btn_menu");
    pushButton[6]->setObjectName("btn_volume");

    /* 設(shè)置按鈕屬性 */
    pushButton[1]->setCheckable(true);
    pushButton[3]->setCheckable(true);

    /* H0布局 */
    vWidget[0]->setMinimumSize(310, 480);
    vWidget[0]->setMaximumWidth(310);
    vWidget[1]->setMinimumSize(320, 480);
    QSpacerItem *hSpacer0 = new
            QSpacerItem(70, 480,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);

    QSpacerItem *hSpacer1 = new
            QSpacerItem(65, 480,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);

    QSpacerItem *hSpacer2 = new
            QSpacerItem(60, 480,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);

    hBoxLayout[0]->addSpacerItem(hSpacer0);
    hBoxLayout[0]->addWidget(vWidget[0]);
    hBoxLayout[0]->addSpacerItem(hSpacer1);
    hBoxLayout[0]->addWidget(vWidget[1]);
    hBoxLayout[0]->addSpacerItem(hSpacer2);
    hBoxLayout[0]->setContentsMargins(0, 0, 0, 0);

    hWidget[0]->setLayout(hBoxLayout[0]);
    setCentralWidget(hWidget[0]);

    /* V0布局 */
    listWidget->setMinimumSize(310, 265);
    hWidget[1]->setMinimumSize(310, 80);
    hWidget[1]->setMaximumHeight(80);
    label[0]->setMinimumSize(310, 95);
    label[0]->setMaximumHeight(95);
    QSpacerItem *vSpacer0 = new
            QSpacerItem(310, 10,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);
    QSpacerItem *vSpacer1 = new
            QSpacerItem(310, 30,
                        QSizePolicy::Minimum,
                        QSizePolicy::Minimum);
    vBoxLayout[0]->addWidget(label[0]);
    vBoxLayout[0]->addWidget(listWidget);
    vBoxLayout[0]->addSpacerItem(vSpacer0);
    vBoxLayout[0]->addWidget(hWidget[1]);
    vBoxLayout[0]->addSpacerItem(vSpacer1);
    vBoxLayout[0]->setContentsMargins(0, 0, 0, 0);

    vWidget[0]->setLayout(vBoxLayout[0]);

    /* H1布局 */
    for (int i = 0; i < 3; i++) {
        pushButton[i]->setMinimumSize(80, 80);
    }
    QSpacerItem *hSpacer3 = new
            QSpacerItem(40, 80,
                        QSizePolicy::Expanding,
                        QSizePolicy::Expanding);
    QSpacerItem *hSpacer4 = new
            QSpacerItem(40, 80,
                        QSizePolicy::Expanding,
                        QSizePolicy::Expanding);
    hBoxLayout[1]->addWidget(pushButton[0]);
    hBoxLayout[1]->addSpacerItem(hSpacer3);
    hBoxLayout[1]->addWidget(pushButton[1]);
    hBoxLayout[1]->addSpacerItem(hSpacer4);
    hBoxLayout[1]->addWidget(pushButton[2]);
    hBoxLayout[1]->setContentsMargins(0, 0, 0, 0);

    hWidget[1]->setLayout(hBoxLayout[1]);

    /* V1布局 */
    QSpacerItem *vSpacer2 = new
            QSpacerItem(320, 40,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);
    QSpacerItem *vSpacer3 = new
            QSpacerItem(320, 20,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);
    QSpacerItem *vSpacer4 = new
            QSpacerItem(320, 30,
                        QSizePolicy::Minimum,
                        QSizePolicy::Minimum);
    label[1]->setMinimumSize(320, 320);
    QImage Image;
    Image.load(":/images/cd.png");
    QPixmap pixmap = QPixmap::fromImage(Image);
    int with = 320;
    int height = 320;
    QPixmap fitpixmap =
            pixmap.scaled(with, height,
                          Qt::IgnoreAspectRatio,
                          Qt::SmoothTransformation);
    label[1]->setPixmap(fitpixmap);
    label[1]->setAlignment(Qt::AlignCenter);
    vWidget[2]->setMinimumSize(300, 80);
    vWidget[2]->setMaximumHeight(80);
    vBoxLayout[1]->addSpacerItem(vSpacer2);
    vBoxLayout[1]->addWidget(label[1]);
    vBoxLayout[1]->addSpacerItem(vSpacer3);
    vBoxLayout[1]->addWidget(durationSlider);
    vBoxLayout[1]->addWidget(vWidget[2]);
    vBoxLayout[1]->addSpacerItem(vSpacer4);
    vBoxLayout[1]->setContentsMargins(0, 0, 0, 0);

    vWidget[1]->setLayout(vBoxLayout[1]);

    /* V2布局 */
    QSpacerItem *vSpacer5 = new
            QSpacerItem(300, 10,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);
    hWidget[2]->setMinimumSize(320, 20);
    hWidget[3]->setMinimumSize(320, 60);
    vBoxLayout[2]->addWidget(hWidget[2]);
    vBoxLayout[2]->addSpacerItem(vSpacer5);
    vBoxLayout[2]->addWidget(hWidget[3]);
    vBoxLayout[2]->setContentsMargins(0, 0, 0, 0);

    vWidget[2]->setLayout(vBoxLayout[2]);

    /* H2布局 */
    QFont font;

    font.setPixelSize(10);

    /* 設(shè)置標(biāo)簽文本 */
    label[0]->setText("Q Music,Enjoy it!");
    label[2]->setText("00:00");
    label[3]->setText("00:00");
    label[2]->setSizePolicy(QSizePolicy::Expanding,
                            QSizePolicy::Expanding);
    label[3]->setSizePolicy(QSizePolicy::Expanding,
                            QSizePolicy::Expanding);
    label[3]->setAlignment(Qt::AlignRight);
    label[2]->setAlignment(Qt::AlignLeft);
    label[2]->setFont(font);
    label[3]->setFont(font);

    pal.setColor(QPalette::WindowText, Qt::white);
    label[0]->setPalette(pal);
    label[2]->setPalette(pal);
    label[3]->setPalette(pal);

    hBoxLayout[2]->addWidget(label[2]);
    hBoxLayout[2]->addWidget(label[3]);

    hBoxLayout[2]->setContentsMargins(0, 0, 0, 0);
    hWidget[2]->setLayout(hBoxLayout[2]);

    /* H3布局 */
    QSpacerItem *hSpacer5 = new
            QSpacerItem(0, 60,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);
    QSpacerItem *hSpacer6 = new
            QSpacerItem(80, 60,
                        QSizePolicy::Maximum,
                        QSizePolicy::Maximum);
    QSpacerItem *hSpacer7 = new
            QSpacerItem(80, 60,
                        QSizePolicy::Maximum,
                        QSizePolicy::Maximum);
    QSpacerItem *hSpacer8 = new
            QSpacerItem(80, 60,
                        QSizePolicy::Maximum,
                        QSizePolicy::Maximum);
    QSpacerItem *hSpacer9 = new
            QSpacerItem(0, 60,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);

    for (int i = 3; i < 7; i++) {
        pushButton[i]->setMinimumSize(25, 25);
        pushButton[i]->setMaximumSize(25, 25);
    }

    hBoxLayout[3]->addSpacerItem(hSpacer5);
    hBoxLayout[3]->addWidget(pushButton[3]);
    hBoxLayout[3]->addSpacerItem(hSpacer6);
    hBoxLayout[3]->addWidget(pushButton[4]);
    hBoxLayout[3]->addSpacerItem(hSpacer7);
    hBoxLayout[3]->addWidget(pushButton[5]);
    hBoxLayout[3]->addSpacerItem(hSpacer8);
    hBoxLayout[3]->addWidget(pushButton[6]);
    hBoxLayout[3]->addSpacerItem(hSpacer9);
    hBoxLayout[3]->setContentsMargins(0, 0, 0, 0);
    hBoxLayout[3]->setAlignment(Qt::AlignHCenter);

    hWidget[3]->setLayout(hBoxLayout[3]);

    //hWidget[0]->setStyleSheet("background-color:red");
    //hWidget[1]->setStyleSheet("background-color:#ff5599");
    //hWidget[2]->setStyleSheet("background-color:#ff55ff");
    //hWidget[3]->setStyleSheet("background-color:black");
    //vWidget[0]->setStyleSheet("background-color:#555555");
    //vWidget[1]->setStyleSheet("background-color:green");
    //vWidget[2]->setStyleSheet("background-color:gray");

}

MainWindow::~MainWindow()
{
}

void MainWindow::btn_play_clicked()
{
    int state = musicPlayer->state();

    switch (state) {
    case QMediaPlayer::StoppedState:
        /* 媒體播放 */
        musicPlayer->play();
        break;

    case QMediaPlayer::PlayingState:
        /* 媒體暫停 */
        musicPlayer->pause();
        break;

    case QMediaPlayer::PausedState:
        musicPlayer->play();
        break;
    }
}

void MainWindow::btn_next_clicked()
{
    musicPlayer->stop();
    int count = mediaPlaylist->mediaCount();
    if (0 == count)
        return;

    /* 列表下一個 */
    mediaPlaylist->next();
    musicPlayer->play();
}

void MainWindow::btn_previous_clicked()
{
    musicPlayer->stop();
    int count = mediaPlaylist->mediaCount();
    if (0 == count)
        return;

    /* 列表上一個 */
    mediaPlaylist->previous();
    musicPlayer->play();
}

void MainWindow::mediaPlayerStateChanged(
        QMediaPlayer::State
        state)
{
    switch (state) {
    case QMediaPlayer::StoppedState:
        pushButton[1]->setChecked(false);
        break;

    case QMediaPlayer::PlayingState:
        pushButton[1]->setChecked(true);
        break;

    case QMediaPlayer::PausedState:
        pushButton[1]->setChecked(false);
        break;
    }
}

void MainWindow::listWidgetCliked(QListWidgetItem *item)
{
    musicPlayer->stop();
    mediaPlaylist->setCurrentIndex(listWidget->row(item));
    musicPlayer->play();
}

void MainWindow::mediaPlaylistCurrentIndexChanged(
        int index)
{
    if (-1 == index)
        return;

    /* 設(shè)置列表正在播放的項(xiàng) */
    listWidget->setCurrentRow(index);
}

void MainWindow::musicPlayerDurationChanged(
        qint64 duration)
{
    durationSlider->setRange(0, duration / 1000);
    int second  = duration / 1000;
    int minute = second / 60;
    second %= 60;

    QString mediaDuration;
    mediaDuration.clear();

    if (minute >= 10)
        mediaDuration = QString::number(minute, 10);
    else
        mediaDuration = "0" + QString::number(minute, 10);

    if (second >= 10)
        mediaDuration = mediaDuration
                + ":" + QString::number(second, 10);
    else
        mediaDuration = mediaDuration
                + ":0" + QString::number(second, 10);

    /* 顯示媒體總長度時間 */
    label[3]->setText(mediaDuration);
}

void MainWindow::mediaPlayerPositionChanged(
        qint64 position)
{
    if (!durationSlider->isSliderDown())
        durationSlider->setValue(position/1000);

    int second  = position / 1000;
    int minute = second / 60;
    second %= 60;

    QString mediaPosition;
    mediaPosition.clear();

    if (minute >= 10)
        mediaPosition = QString::number(minute, 10);
    else
        mediaPosition = "0" + QString::number(minute, 10);

    if (second >= 10)
        mediaPosition = mediaPosition
                + ":" + QString::number(second, 10);
    else
        mediaPosition = mediaPosition
                + ":0" + QString::number(second, 10);

    /* 顯示現(xiàn)在播放的時間 */
    label[2]->setText(mediaPosition);
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);
    listMask->setGeometry(0,
                          listWidget->height() - 50,
                          310,
                          50);
}

void MainWindow::durationSliderReleased()
{
    /* 設(shè)置媒體播放的位置 */
    musicPlayer->setPosition(durationSlider->value() * 1000);
}

void MainWindow::scanSongs()
{
    QDir dir(QCoreApplication::applicationDirPath()
             + "/myMusic");
    QDir dirbsolutePath(dir.absolutePath());
    /* 如果目錄存在 */
    if (dirbsolutePath.exists()) {
        /* 定義過濾器 */
        QStringList filter;
        /* 包含所有.mp3后綴的文件 */
        filter << "*.mp3";
        /* 獲取該目錄下的所有文件 */
        QFileInfoList files =
                dirbsolutePath.entryInfoList(filter, QDir::Files);
        /* 遍歷 */
        for (int i = 0; i < files.count(); i++) {
            MediaObjectInfo info;
            /* 使用utf-8編碼 */
            QString fileName = QString::fromUtf8(files.at(i)
                                                 .fileName()
                                                 .replace(".mp3", "")
                                                 .toUtf8()
                                                 .data());
            info.fileName = fileName + "\n"
                    + fileName.split("-").at(1);
            info.filePath = QString::fromUtf8(files.at(i)
                                              .filePath()
                                              .toUtf8()
                                              .data());
            /* 媒體列表添加歌曲 */
            if (mediaPlaylist->addMedia(
                        QUrl::fromLocalFile(info.filePath))) {
                /* 添加到容器數(shù)組里儲存 */
                mediaObjectInfo.append(info);
                /* 添加歌曲名字至列表 */
                listWidget->addItem(info.fileName);
            } else {
                qDebug()<<
                           mediaPlaylist->errorString()
                           .toUtf8().data()
                        << endl;
                qDebug()<< "  Error number:"
                         << mediaPlaylist->error()
                         << endl;
            }
        }
    }
}

void MainWindow::mediaPlayerInit()
{
    musicPlayer = new QMediaPlayer(this);
    mediaPlaylist = new QMediaPlaylist(this);
    /* 確保列表是空的 */
    mediaPlaylist->clear();
    /* 設(shè)置音樂播放器的列表為mediaPlaylist */
    musicPlayer->setPlaylist(mediaPlaylist);
    /* 設(shè)置播放模式,Loop是列循環(huán) */
    mediaPlaylist->setPlaybackMode(QMediaPlaylist::Loop);
}

上述代碼就是常規(guī)的 QT 頁面布局以及操作函數(shù)和信號,代碼參考了正點(diǎn)原子的教程。特別需要注意的地方是需要在 QMusic 的功能頁中加入退出按鈕,即切換至其父進(jìn)程!具體如下圖:

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

運(yùn)行結(jié)果:

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

3.2 QVideo視頻播放器

視頻播放器依舊是各家嵌入式機(jī)構(gòu)QT練習(xí)的常規(guī)項(xiàng)目,與音樂播放器一樣使用 QMediaPlayer 類,不同的是需要使用 setVideoOutput(QVideoWidget*) 設(shè)置一個視頻輸出窗口,好讓視頻在此窗口顯示,其他步驟基本都一樣。

★在項(xiàng)目文件 15_videoplayer.pro 文件第一行添加的代碼:multimedia multimediawidgets

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

在頭文件 “mainwindow.h” 具體代碼如下

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QPushButton>
#include <QSlider>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QListWidget>
#include <QLabel>
#include <QSpacerItem>
#include <QVideoWidget>
#include <QDebug>

/* 媒體信息結(jié)構(gòu)體 */
struct MediaObjectInfo {
    /* 用于保存視頻文件名 */
    QString fileName;
    /* 用于保存視頻文件路徑 */
    QString filePath;
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /* 媒體播放器,用于播放視頻 */
    QMediaPlayer *videoPlayer;

    /* 媒體列表 */
    QMediaPlaylist *mediaPlaylist;

    /* 視頻顯示窗口 */
    QVideoWidget *videoWidget;

    /* 視頻列表 */
    QListWidget *listWidget;

    /* 播放進(jìn)度條 */
    QSlider *durationSlider;

    /* 音量條 */
    QSlider *volumeSlider;

    /* 視頻播放器按鈕 */
    QPushButton *pushButton[5];

    QPushButton *exit_button;

    /* 水平布局 */
    QHBoxLayout *hBoxLayout[3];

    /* 水平容器 */
    QWidget *hWidget[3];

    /* 標(biāo)簽文本 */
    QLabel *label[2];

    /* 垂直容器 */
    QWidget *vWidget[2];

    /* 垂直界面 */
    QVBoxLayout *vBoxLayout[2];

    /* 視頻布局函數(shù) */
    void videoLayout();

    /* 主窗體大小重設(shè)大小函數(shù)重寫 */
    void resizeEvent(QResizeEvent *event);

    /* 媒體信息存儲 */
    QVector<MediaObjectInfo> mediaObjectInfo;

    /* 掃描本地視頻文件 */
    void scanVideoFiles();

    /* 媒體初始化 */
    void mediaPlayerInit();
private slots:
    /* 播放按鈕點(diǎn)擊 */
    void btn_play_clicked();

    /* 下一個視頻按鈕點(diǎn)擊 */
    void btn_next_clicked();

    /* 音量加 */
    void btn_volmeup_clicked();

    /* 音量減 */
    void btn_volmedown_clicked();

    /* 全屏 */
    void btn_fullscreen_clicked();

    /* 媒體狀態(tài)改變 */
    void mediaPlayerStateChanged(QMediaPlayer::State);

    /* 列表單擊 */
    void listWidgetCliked(QListWidgetItem*);

    /* 媒體列表項(xiàng)改變 */
    void mediaPlaylistCurrentIndexChanged(int);

    /* 媒體總長度改變 */
    void musicPlayerDurationChanged(qint64);

    /* 媒體播放位置改變 */
    void mediaPlayerPositionChanged(qint64);

    /* 播放進(jìn)度條松開 */
    void durationSliderReleased();

    /* 音量條松開 */
    void volumeSliderReleased();
};
#endif // MAINWINDOW_H

在源文件?“mainwindow.cpp”?具體代碼如下:

#include "mainwindow.h"
#include <QCoreApplication>
#include <QFileInfoList>
#include <QDir>
#include <QProcess>


QProcess * mypro;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 視頻播放器布局初始化 */
    videoLayout();

    /* 媒體初始化 */
    mediaPlayerInit();

    /* 掃描本地視頻 */
    scanVideoFiles();

    /* 設(shè)置按鈕的屬性 */
    pushButton[0]->setCheckable(true);
    pushButton[4]->setCheckable(true);

    /* 按鈕連接信號槽 */
    connect(pushButton[0], SIGNAL(clicked()),
            this, SLOT(btn_play_clicked()));
    connect(pushButton[1], SIGNAL(clicked()),
            this, SLOT(btn_next_clicked()));
    connect(pushButton[2], SIGNAL(clicked()),
            this, SLOT(btn_volmedown_clicked()));
    connect(pushButton[3], SIGNAL(clicked()),
            this, SLOT(btn_volmeup_clicked()));
    connect(pushButton[4], SIGNAL(clicked()),
            this, SLOT(btn_fullscreen_clicked()));

    /* 列表連接信號槽 */
    connect(listWidget, SIGNAL(itemClicked(QListWidgetItem*)),
            this, SLOT(listWidgetCliked(QListWidgetItem*)));

    /* 媒體連接信號槽 */
    connect(videoPlayer,
            SIGNAL(stateChanged(QMediaPlayer::State)),
            this,
            SLOT(mediaPlayerStateChanged(QMediaPlayer::State)));
    connect(mediaPlaylist,
            SIGNAL(currentIndexChanged(int)),
            this,
            SLOT(mediaPlaylistCurrentIndexChanged(int)));
    connect(videoPlayer, SIGNAL(durationChanged(qint64)),
            this,
            SLOT(musicPlayerDurationChanged(qint64)));
    connect(videoPlayer,
            SIGNAL(positionChanged(qint64)),
            this,
            SLOT(mediaPlayerPositionChanged(qint64)));

    /* slider信號槽連接 */
    connect(durationSlider, SIGNAL(sliderReleased()),
            this, SLOT(durationSliderReleased()));
    connect(volumeSlider, SIGNAL(sliderReleased()),
            this, SLOT(volumeSliderReleased()));

    /* 退出按鈕 */
    exit_button = new QPushButton(this);
    exit_button->setMinimumSize(60, 50);
    exit_button->setMaximumSize(60, 50);
    exit_button->move(740,10);
    exit_button->setStyleSheet("QPushButton{background: black}");

    connect(exit_button,&QPushButton::clicked,[=](){
        mypro->close();
        exit(1);//退出程序
    });

}

MainWindow::~MainWindow()
{
}

void MainWindow::videoLayout()
{
    /* 設(shè)置位置與大小,這里固定為800, 480 */
    this->setGeometry(0, 0, 800, 480);
    //    this->setMinimumSize(800, 480);
    //    this->setMaximumSize(800, 480);
    QPalette pal;
    pal.setColor(QPalette::WindowText, Qt::white);

    for (int i = 0; i < 3; i++) {
        /* 水平容器 */
        hWidget[i] = new QWidget();
        hWidget[i]->setAutoFillBackground(true);
        /* 水平布局 */
        hBoxLayout[i] = new QHBoxLayout();
    }

    for (int i = 0; i < 2; i++) {
        /* 垂直容器 */
        vWidget[i] = new QWidget();
        vWidget[i]->setAutoFillBackground(true);
        /* 垂直布局 */
        vBoxLayout[i] = new QVBoxLayout();
    }

    for (int i = 0; i < 2; i++) {
        label[i] = new QLabel();
    }

    for (int i = 0; i < 5; i++) {
        pushButton[i] = new QPushButton();
        pushButton[i]->setMaximumSize(44, 44);
        pushButton[i]->setMinimumSize(44, 44);
    }

    /* 設(shè)置 */
    vWidget[0]->setObjectName("vWidget0");
    vWidget[1]->setObjectName("vWidget1");
    hWidget[1]->setObjectName("hWidget1");
    hWidget[2]->setObjectName("hWidget2");
    pushButton[0]->setObjectName("btn_play");
    pushButton[1]->setObjectName("btn_next");
    pushButton[2]->setObjectName("btn_volumedown");
    pushButton[3]->setObjectName("btn_volumeup");
    pushButton[4]->setObjectName("btn_screen");

    QFont font;

    font.setPixelSize(18);
    label[0]->setFont(font);
    label[1]->setFont(font);

    pal.setColor(QPalette::WindowText, Qt::white);
    label[0]->setPalette(pal);
    label[1]->setPalette(pal);

    label[0]->setText("00:00");
    label[1]->setText("/00:00");

    durationSlider = new QSlider(Qt::Horizontal);
    durationSlider->setMaximumHeight(15);
    durationSlider->setObjectName("durationSlider");

    volumeSlider = new QSlider(Qt::Horizontal);
    volumeSlider->setRange(0, 100);
    volumeSlider->setMaximumWidth(80);
    volumeSlider->setObjectName("volumeSlider");
    volumeSlider->setValue(50);

    listWidget = new QListWidget();
    listWidget->setObjectName("listWidget");
    listWidget->setVerticalScrollBarPolicy(
                Qt::ScrollBarAlwaysOff);
    listWidget->setHorizontalScrollBarPolicy(
                Qt::ScrollBarAlwaysOff);
    //listWidget->setFocusPolicy(Qt::NoFocus);
    videoWidget = new QVideoWidget();
    videoWidget->setStyleSheet("border-image: none;"
                               "background: transparent;"
                               "border:none");

    /* H0布局 */
    vWidget[0]->setMinimumSize(300, 480);
    vWidget[0]->setMaximumWidth(300);
    videoWidget->setMinimumSize(500, 480);

    hBoxLayout[0]->addWidget(videoWidget);
    hBoxLayout[0]->addWidget(vWidget[0]);

    hWidget[0]->setLayout(hBoxLayout[0]);
    hBoxLayout[0]->setContentsMargins(0, 0, 0, 0);

    setCentralWidget(hWidget[0]);

    /* V0布局 */
    QSpacerItem *vSpacer0 = new
            QSpacerItem(0, 80,
                        QSizePolicy::Minimum,
                        QSizePolicy::Maximum);
    vBoxLayout[0]->addWidget(listWidget);
    vBoxLayout[0]->addSpacerItem(vSpacer0);
    vBoxLayout[0]->setContentsMargins(0, 0, 0, 0);

    vWidget[0]->setLayout(vBoxLayout[0]);

    /* V1布局 */
    /* 底板部件布局 */
    hWidget[1]->setMaximumHeight(15);
    hWidget[2]->setMinimumHeight(65);
    vBoxLayout[1]->addWidget(hWidget[1]);
    vBoxLayout[1]->addWidget(hWidget[2]);
    vBoxLayout[1]->setAlignment(Qt::AlignCenter);

    vWidget[1]->setLayout(vBoxLayout[1]);
    vWidget[1]->setParent(this);
    vWidget[1]->setGeometry(0, this->height() - 80, this->width(), 80);
    vBoxLayout[1]->setContentsMargins(0, 0, 0, 0);
    /* 位于最上層 */
    vWidget[1]->raise();

    /* H1布局 */
    hBoxLayout[1]->addWidget(durationSlider);
    hBoxLayout[1]->setContentsMargins(0, 0, 0, 0);
    hWidget[1]->setLayout(hBoxLayout[1]);

    /* H2布局 */
    QSpacerItem *hSpacer0 = new
            QSpacerItem(300, 80,
                        QSizePolicy::Expanding,
                        QSizePolicy::Maximum);

    hBoxLayout[2]->addSpacing(20);
    hBoxLayout[2]->addWidget(pushButton[0]);
    hBoxLayout[2]->addSpacing(10);
    hBoxLayout[2]->addWidget(pushButton[1]);
    hBoxLayout[2]->addSpacing(10);
    hBoxLayout[2]->addWidget(pushButton[2]);
    hBoxLayout[2]->addWidget(volumeSlider);
    hBoxLayout[2]->addWidget(pushButton[3]);
    hBoxLayout[2]->addWidget(label[0]);
    hBoxLayout[2]->addWidget(label[1]);
    hBoxLayout[2]->addSpacerItem(hSpacer0);
    hBoxLayout[2]->addWidget(pushButton[4]);
    hBoxLayout[2]->addSpacing(20);
    hBoxLayout[2]->setContentsMargins(0, 0, 0, 0);
    hBoxLayout[2]->setAlignment(Qt::AlignLeft | Qt::AlignTop);

    hWidget[2]->setLayout(hBoxLayout[2]);
}

void MainWindow::mediaPlayerInit()
{
    videoPlayer = new QMediaPlayer(this);
    mediaPlaylist = new QMediaPlaylist(this);
    /* 確保列表是空的 */
    mediaPlaylist->clear();
    /* 設(shè)置視頻播放器的列表為mediaPlaylist */
    videoPlayer->setPlaylist(mediaPlaylist);
    /* 設(shè)置視頻輸出窗口 */
    videoPlayer->setVideoOutput(videoWidget);
    /* 設(shè)置播放模式,Loop是列循環(huán) */
    mediaPlaylist->setPlaybackMode(QMediaPlaylist::Loop);
    /* 設(shè)置默認(rèn)軟件音量為50% */
    videoPlayer->setVolume(50);
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);
    vWidget[1]->setGeometry(0, this->height() - 80, this->width(), 80);
}

void MainWindow::btn_play_clicked()
{
    int state = videoPlayer->state();
    switch (state) {
    case QMediaPlayer::StoppedState:
        /* 媒體播放 */
        videoPlayer->play();
        break;

    case QMediaPlayer::PlayingState:
        /* 媒體暫停 */
        videoPlayer->pause();
        break;

    case QMediaPlayer::PausedState:
        /* 設(shè)置視頻輸出窗口 */
        videoPlayer->play();
        break;
    }
}

void MainWindow::btn_next_clicked()
{
    videoPlayer->stop();
    int count = mediaPlaylist->mediaCount();
    if (0 == count)
        return;

    /* 列表下一個 */
    mediaPlaylist->next();
    videoPlayer->play();
}

void MainWindow::btn_volmeup_clicked()
{
    /* 點(diǎn)擊每次音量+5 */
    volumeSlider->setValue(volumeSlider->value() + 5);
    videoPlayer->setVolume(volumeSlider->value());
}

void MainWindow::btn_fullscreen_clicked()
{
    /* 全屏/非全屏操作 */
    vWidget[0]->setVisible(!pushButton[4]->isChecked());
}

void MainWindow::btn_volmedown_clicked()
{
    /* 點(diǎn)擊每次音量-5 */
    volumeSlider->setValue(volumeSlider->value() - 5);
    videoPlayer->setVolume(volumeSlider->value());
}

void MainWindow::mediaPlayerStateChanged(
        QMediaPlayer::State
        state)
{
    switch (state) {
    case QMediaPlayer::StoppedState:
        pushButton[0]->setChecked(false);
        break;

    case QMediaPlayer::PlayingState:
        pushButton[0]->setChecked(true);
        break;

    case QMediaPlayer::PausedState:
        pushButton[0]->setChecked(false);
        break;
    }
}

void MainWindow::listWidgetCliked(QListWidgetItem *item)
{
    videoPlayer->stop();
    mediaPlaylist->setCurrentIndex(listWidget->row(item));
    videoPlayer->play();
}

void MainWindow::mediaPlaylistCurrentIndexChanged(
        int index)
{
    if (-1 == index)
        return;

    /* 設(shè)置列表正在播放的項(xiàng) */
    listWidget->setCurrentRow(index);
}

void MainWindow::musicPlayerDurationChanged(
        qint64 duration)
{
    durationSlider->setRange(0, duration / 1000);
    int second  = duration / 1000;
    int minute = second / 60;
    second %= 60;

    QString mediaDuration;
    mediaDuration.clear();

    if (minute >= 10)
        mediaDuration = QString::number(minute, 10);
    else
        mediaDuration = "0" + QString::number(minute, 10);

    if (second >= 10)
        mediaDuration = mediaDuration
                + ":" + QString::number(second, 10);
    else
        mediaDuration = mediaDuration
                + ":0" + QString::number(second, 10);

    /* 顯示媒體總長度時間 */
    label[1]->setText("/" + mediaDuration);
}

void MainWindow::mediaPlayerPositionChanged(
        qint64 position)
{
    if (!durationSlider->isSliderDown())
        durationSlider->setValue(position / 1000);

    int second  = position / 1000;
    int minute = second / 60;
    second %= 60;

    QString mediaPosition;
    mediaPosition.clear();

    if (minute >= 10)
        mediaPosition = QString::number(minute, 10);
    else
        mediaPosition = "0" + QString::number(minute, 10);

    if (second >= 10)
        mediaPosition = mediaPosition
                + ":" + QString::number(second, 10);
    else
        mediaPosition = mediaPosition
                + ":0" + QString::number(second, 10);

    /* 顯示現(xiàn)在播放的時間 */
    label[0]->setText(mediaPosition);
}

void MainWindow::durationSliderReleased()
{
    /* 設(shè)置媒體播放的位置 */
    videoPlayer->setPosition(durationSlider->value() * 1000);
}

void MainWindow::volumeSliderReleased()
{
    /* 設(shè)置音量 */
    videoPlayer->setVolume(volumeSlider->value());
}

void MainWindow::scanVideoFiles()
{
    QDir dir(QCoreApplication::applicationDirPath()
             + "/myVideo");
    QDir dirbsolutePath(dir.absolutePath());
    /* 如果目錄存在 */
    if (dirbsolutePath.exists()) {
        /* 定義過濾器 */
        QStringList filter;
        /* 包含所有xx后綴的文件 */
        filter << "*.mp4" << "*.mkv" << "*.wmv" << "*.avi";
        /* 獲取該目錄下的所有文件 */
        QFileInfoList files =
                dirbsolutePath.entryInfoList(filter, QDir::Files);
        /* 遍歷 */
        for (int i = 0; i < files.count(); i++) {
            MediaObjectInfo info;
            /* 使用utf-8編碼 */
            info.fileName = QString::fromUtf8(files.at(i)
                                              .fileName()
                                              .toUtf8()
                                              .data());
            info.filePath = QString::fromUtf8(files.at(i)
                                              .filePath()
                                              .toUtf8()
                                              .data());
            /* 媒體列表添加視頻 */
            if (mediaPlaylist->addMedia(
                        QUrl::fromLocalFile(info.filePath))) {
                /* 添加到容器數(shù)組里儲存 */
                mediaObjectInfo.append(info);
                /* 添加視頻名字至列表 */
                listWidget->addItem(info.fileName);
            } else {
                qDebug()<<
                           mediaPlaylist->errorString()
                           .toUtf8().data()
                        << endl;
                qDebug()<< "  Error number:"
                        << mediaPlaylist->error()
                        << endl;
            }
        }
    }
}

與上一小節(jié)音樂播放器的一樣,在構(gòu)造函數(shù)里布局初始化,然后執(zhí)行掃描本地視頻文件。之后就是一些信號槽的連接,基本上就是這么一個流程了。特別注意:IMX6ULL因?yàn)椴荒苓M(jìn)行漢字解碼,所以漢字名的 mp4 等格式文件名會變成???,但是不影響程序運(yùn)行!

運(yùn)行結(jié)果:

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

3.3 AP3216C監(jiān)測

本項(xiàng)目作者替換的智能家居 APP 的功能頁為 AP3216C 的車載內(nèi)室監(jiān)測功能!

篇幅有限,AP3216的使用和 QT 功能頁設(shè)計(jì)博客:http://t.csdn.cn/cN6p1

運(yùn)行結(jié)果:

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

3.4 終端APP切換實(shí)現(xiàn)

★該部分為本篇博客核心部分,希望讀者朋友可以通過這里掌握 Linux+QT 下的多進(jìn)程操作!

3.4.1 Picture制作

作者一直認(rèn)為 QT 的靈魂是設(shè)計(jì)美學(xué),優(yōu)化流程絲滑方面,功能的實(shí)現(xiàn)是非?;A(chǔ)的部分!各別作者可能嘗試自己制作一些產(chǎn)品可能沒有美工,作者這邊提供一種方法!

通過網(wǎng)絡(luò)選擇我們需要的圖標(biāo)和圖片信息,使用去在線去背景網(wǎng)站進(jìn)行去背景操作!

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

將去背景后的圖片導(dǎo)入到 Ubuntu 中,圖標(biāo)大小盡量保持一致(允許存在些許偏差?。?/p>

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

3.4.2 APP功能頁制作

考慮到這些 APP 圖標(biāo)的功能實(shí)現(xiàn)和框架是相似的,作者這里僅以 QMusic 為例進(jìn)行教學(xué)!

通過添加?Qt Resource File 資源放置我們之前準(zhǔn)備好的 APP 圖標(biāo)!

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

1、智能車載終端的時間顯示(掃描檢測):

    /* 獲取屏幕的分辨率,Qt官方建議使用這
    * 種方法獲取屏幕分辨率,防上多屏設(shè)備導(dǎo)致對應(yīng)不上
    * 注意,這是獲取整個桌面系統(tǒng)的分辨率
    */
    QList <QScreen *> list_screen = QGuiApplication::screens();

    /* 如果是ARM平臺,直接設(shè)置大小為屏幕的大小 */
#if __arm__
     /* 重設(shè)大小 */
     this->resize(list_screen.at(0)->geometry().width(),
                 list_screen.at(0)->geometry().height());
#else
     /* 否則則設(shè)置主窗體大小為800x480 */
     this->resize(800,400);
#endif

    /* 構(gòu)建布局標(biāo)題和背景色 */
    this->setWindowTitle("智能車載系統(tǒng)");
    this->setStyleSheet("background-color: rgb(240, 255, 255);");   //QT顏色標(biāo):http://t.csdn.cn/SF7Rc

    //給進(jìn)程分配空間
    my_pro = new QProcess(this);

    //時間顯示label
    QLabel *time_label = new QLabel(this);
    time_label->setGeometry(10,20,240,100);//設(shè)置坐標(biāo)
    //time_label->setStyleSheet("font-size:55px;color:black");//設(shè)置大小顏色
    time_label->setFont(QFont("Helvetica", 72));
    //time_label->ssetFont(QFont("Helvetica", 30)); // 設(shè)置字體為Arial,大小為16

    //日期顯示label
    QLabel *date_label = new QLabel(this);
    date_label->setGeometry(200,100,240,100);//設(shè)置坐標(biāo)
    date_label->setStyleSheet("font-size:25px;color:green");//設(shè)置大小顏色

    //智能車載裝置
    QFont font("Arial", 30, QFont::Normal);
    QLabel *title_label = new QLabel(this);
    title_label->setGeometry(40,180,260,50);//設(shè)置坐標(biāo)
    title_label->setFont(font);
    title_label->setText("智能車載終端");

    m_pLCD = new QLCDNumber(this);
    // 設(shè)置能顯示的位數(shù)
    m_pLCD->setDigitCount(8);

    m_pLCD->setGeometry(20,30,230,100);
    // 設(shè)置顯示的模式為十進(jìn)制
    m_pLCD->setMode(QLCDNumber::Dec);
    // 設(shè)置樣式
    m_pLCD->setStyleSheet("border: 1px solid green;font-size:70%;color: green");
    m_pLCD->resize(300,100);

    //定時器刷新顯示
    QTimer *timer = new QTimer(this);
    timer->start(200);

    connect(timer,&QTimer::timeout,[=](){
        /* 獲取當(dāng)前日期 */
        QDate date = QDate::currentDate();//獲取當(dāng)前日期
        QString date_msg = QString("%1-%2-%3").arg(date.year()).arg(date.month()).arg(date.day());
        date_label->setText(date_msg);

        // 獲取系統(tǒng)當(dāng)前時間
        QDateTime dateTime = QDateTime::currentDateTime();
        // 顯示的內(nèi)容
        m_pLCD->display(dateTime.toString("HH:mm:ss"));


        /* 判斷進(jìn)程狀態(tài) */
        if(my_pro->state() == QProcess::NotRunning)
        {
            this->show();//重新顯示窗口
        }
        else
        {
            this->hide();
        }

    });

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

上述代碼通過 Q_Label 和?QLCDNumber 分別創(chuàng)造了普通字體的日期和 “LED數(shù)碼管” 字體,創(chuàng)造一個 timer,每 200ms 觸發(fā)一次信號,信號中函數(shù)進(jìn)行更新時間!同時關(guān)鍵的是進(jìn)行檢測 my_pro 進(jìn)程是否停止運(yùn)行,如果停止運(yùn)行就顯示當(dāng)前 this 進(jìn)程(主菜單進(jìn)程),否則就隱藏 this 進(jìn)程!

2、QMusic 功能按鈕操作:

menubutton.h:

#ifndef MENUBUTTON_H
#define MENUBUTTON_H
#include<QPushButton>
#include<QPropertyAnimation>
#include<QString>
#include<QEvent>
#include<QMouseEvent>

#include <QObject>
#include <QWidget>

/*
 * 作者:混分巨獸龍某某
 * csdn:混分巨獸龍某某
 * 郵箱:1178305328@qq.com
 * 嵌入式技術(shù)交流群:958820627
 */

/* 創(chuàng)建了MenuButton的類,并且該類繼承QPushButton */
class MenuButton : public QPushButton
{
    Q_OBJECT

public:
    MenuButton(QString normal_path,QString press_path="",int pixwidth=10,int pixheight=10);
    void zoom1();
    void zoom2();

private:
    QString normal_path;
    QString press_path;
    QPropertyAnimation* animation;

protected:
    //void mousePressEvent(QMouseEvent * e);
    //void mouseReleaseEvent(QMouseEvent * e);

signals:

public slots:
};

#endif // MENUBUTTON_H

通過上述?menubutton.h文件,我們創(chuàng)建了一個 MenuButton 的類,該類繼承了 QPushButton 可以作為一個按鈕(核心技巧)。我們通過讀取?Qt Resource File 文件中的 APP 圖標(biāo)作為按鈕!隨后,對 APP 按鈕進(jìn)行布局和設(shè)置大??!

    /* 菜單按鈕切屏定時器 */
    time1= new QTimer(this);

    //音樂按鈕
    MenuButton * music_button=new MenuButton(":/picture/music.png","",245,245);
    music_button->setParent(this);
    music_button->move(400,10);
    //音樂按鈕按下處理
    connect(music_button,&MenuButton::clicked,[=](){
        /* 設(shè)計(jì)動作圖標(biāo) */
        music_button->zoom1();//彈跳
        music_button->zoom2();
        /* 延遲500ms后啟動播放器進(jìn)程 */
        time1->start(500);
        connect(time1,&QTimer::timeout,[=](){
            time1->stop();
            my_pro->close();
            my_pro->start("./QMusicPlayer");});
     });

當(dāng)用?MenuButton 類創(chuàng)建了一個?music_button 對象,即 APP 按鈕被按下之后觸發(fā)設(shè)定好的函數(shù),music_button->zoom1() 和?music_button->zoom2() 其實(shí)就是 APP 按鈕的跳動動畫(使得車載終端更美化)。開啟 time1,500ms 之后觸發(fā)信號,關(guān)閉 time1 ,關(guān)閉當(dāng)前my_pro 進(jìn)程,并將該進(jìn)程開啟成 QMusicPlayer 進(jìn)程!其余的以此類推!

我們需要注意的是,start 函數(shù)后面的進(jìn)程名一定要存在當(dāng)前目錄中,且可以在當(dāng)前設(shè)備環(huán)境下運(yùn)行才可以

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

3.4. 3 完整代碼

menubutton.h:

#ifndef MENUBUTTON_H
#define MENUBUTTON_H
#include<QPushButton>
#include<QPropertyAnimation>
#include<QString>
#include<QEvent>
#include<QMouseEvent>

#include <QObject>
#include <QWidget>

/*
 * 作者:混分巨獸龍某某
 * csdn:混分巨獸龍某某
 * 郵箱:1178305328@qq.com
 * 嵌入式技術(shù)交流群:958820627
 */

/* 創(chuàng)建了MenuButton的類,并且該類繼承QPushButton */
class MenuButton : public QPushButton
{
    Q_OBJECT

public:
    MenuButton(QString normal_path,QString press_path="",int pixwidth=10,int pixheight=10);
    void zoom1();
    void zoom2();

private:
    QString normal_path;
    QString press_path;
    QPropertyAnimation* animation;

protected:

signals:

public slots:
};

#endif // MENUBUTTON_H

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLCDNumber>
#include <QProcess>
#include <QTimer>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

/*
 * 作者:混分巨獸龍某某
 * csdn:混分巨獸龍某某
 * 郵箱:1178305328@qq.com
 * 嵌入式技術(shù)交流群:958820627
 */

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    QLCDNumber *m_pLCD;
    QProcess *my_pro;
    QTimer *time1;

    /* 布局初始化 */
    void layoutInit();

private slots:
    //void onTimeOut();
};
#endif // MAINWINDOW_H

menubutton.cpp:

#include "menubutton.h"
#include <QDebug>

MenuButton::MenuButton(QString normal_path,QString press_path,int pixwidth,int pixheight)
{
    this->normal_path=normal_path;
    this->press_path=press_path;

    QPixmap pix;
    bool ret = pix.load(this->normal_path);
    if(!ret)
    {
        qDebug()<<"圖片加載失敗";
        return ;

    }
    //設(shè)置圖片固定大小
    this->setFixedSize(pixwidth,pixheight);
    //設(shè)置不規(guī)則圖片樣式
    this->setStyleSheet( "QPushButton{border:0px;}" );
    //設(shè)置圖標(biāo)
    this->setIcon(pix);
    //設(shè)置圖標(biāo)大小
    this->setIconSize(QSize(pixwidth,pixheight));

    this->setFocusPolicy(Qt::NoFocus);     //去除虛線邊框

    animation = new QPropertyAnimation(this,"geometry");

}

void MenuButton::zoom1()
{
    //設(shè)置動畫時間間隔
    animation->setDuration(200);
    //設(shè)置起始位置
    animation->setStartValue(QRect(this->x(),this->y()+10,this->width(),this->height()));
    //設(shè)置結(jié)束位置
    animation->setEndValue(QRect(this->x(),this->y(),this->width(),this->height()));
    //設(shè)置彈跳曲線
    animation->setEasingCurve(QEasingCurve::OutBounce);
    //執(zhí)行動畫
    animation->start();
}

void MenuButton::zoom2()
{
    //設(shè)置動畫時間間隔
    animation->setDuration(200);
    //設(shè)置起始位置
    animation->setStartValue(QRect(this->x(),this->y(),this->width(),this->height()));
    //設(shè)置結(jié)束位置
    animation->setEndValue(QRect(this->x(),this->y()-10,this->width(),this->height()));
    //設(shè)置彈跳曲線
    animation->setEasingCurve(QEasingCurve::InElastic);
    //執(zhí)行動畫
    animation->start();
}

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QLabel>
#include<QTimer>
#include<QTime>
#include<QProcess>
#include "menubutton.h"
#include <QScreen>
#include<QFont>

/*
 * 作者:混分巨獸龍某某
 * csdn:混分巨獸龍某某
 * 郵箱:1178305328@qq.com
 * 嵌入式技術(shù)交流群:958820627
 */

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 布局初始化 */
    layoutInit();
}

/* 析構(gòu)函數(shù) */
MainWindow::~MainWindow()
{

}

/* 屏幕布局初始化 */
void MainWindow::layoutInit()
{
    /* 獲取屏幕的分辨率,Qt官方建議使用這
    * 種方法獲取屏幕分辨率,防上多屏設(shè)備導(dǎo)致對應(yīng)不上
    * 注意,這是獲取整個桌面系統(tǒng)的分辨率
    */
    QList <QScreen *> list_screen = QGuiApplication::screens();

    /* 如果是ARM平臺,直接設(shè)置大小為屏幕的大小 */
#if __arm__
     /* 重設(shè)大小 */
     this->resize(list_screen.at(0)->geometry().width(),
                 list_screen.at(0)->geometry().height());
#else
     /* 否則則設(shè)置主窗體大小為800x480 */
     this->resize(800,400);
#endif

    /* 構(gòu)建布局標(biāo)題和背景色 */
    this->setWindowTitle("智能車載系統(tǒng)");
    this->setStyleSheet("background-color: rgb(240, 255, 255);");   //QT顏色標(biāo):http://t.csdn.cn/SF7Rc

    //給進(jìn)程分配空間
    my_pro = new QProcess(this);

    //時間顯示label
    QLabel *time_label = new QLabel(this);
    time_label->setGeometry(10,20,240,100);//設(shè)置坐標(biāo)
    //time_label->setStyleSheet("font-size:55px;color:black");//設(shè)置大小顏色
    time_label->setFont(QFont("Helvetica", 72));
    //time_label->ssetFont(QFont("Helvetica", 30)); // 設(shè)置字體為Arial,大小為16

    //日期顯示label
    QLabel *date_label = new QLabel(this);
    date_label->setGeometry(200,100,240,100);//設(shè)置坐標(biāo)
    date_label->setStyleSheet("font-size:25px;color:green");//設(shè)置大小顏色

    //智能車載裝置
    QFont font("Arial", 30, QFont::Normal);
    QLabel *title_label = new QLabel(this);
    title_label->setGeometry(40,180,260,50);//設(shè)置坐標(biāo)
    title_label->setFont(font);
    title_label->setText("智能車載終端");

    m_pLCD = new QLCDNumber(this);
    // 設(shè)置能顯示的位數(shù)
    m_pLCD->setDigitCount(8);

    m_pLCD->setGeometry(20,30,230,100);
    // 設(shè)置顯示的模式為十進(jìn)制
    m_pLCD->setMode(QLCDNumber::Dec);
    // 設(shè)置樣式
    m_pLCD->setStyleSheet("border: 1px solid green;font-size:70%;color: green");
    m_pLCD->resize(300,100);

    //定時器刷新顯示
    QTimer *timer = new QTimer(this);
    timer->start(200);

    connect(timer,&QTimer::timeout,[=](){
        /* 獲取當(dāng)前日期 */
        QDate date = QDate::currentDate();//獲取當(dāng)前日期
        QString date_msg = QString("%1-%2-%3").arg(date.year()).arg(date.month()).arg(date.day());
        date_label->setText(date_msg);

        // 獲取系統(tǒng)當(dāng)前時間
        QDateTime dateTime = QDateTime::currentDateTime();
        // 顯示的內(nèi)容
        m_pLCD->display(dateTime.toString("HH:mm:ss"));


        /* 判斷進(jìn)程狀態(tài) */
        if(my_pro->state() == QProcess::NotRunning)
        {
            this->show();//重新顯示窗口
        }
        else
        {
            this->hide();
        }

    });

    /* 菜單按鈕切屏定時器 */
    time1= new QTimer(this);

    //音樂按鈕
    MenuButton * music_button=new MenuButton(":/picture/music.png","",245,245);
    music_button->setParent(this);
    music_button->move(400,10);
    //音樂按鈕按下處理
    connect(music_button,&MenuButton::clicked,[=](){
        /* 設(shè)計(jì)動作圖標(biāo) */
        music_button->zoom1();//彈跳
        music_button->zoom2();
        /* 延遲500ms后啟動播放器進(jìn)程 */
        time1->start(500);
        connect(time1,&QTimer::timeout,[=](){
            time1->stop();
            my_pro->close();
            my_pro->start("./QMusicPlayer");});
        });


    //視頻按鈕
    MenuButton * video_button=new MenuButton(":/picture/bofangqi.png","",215,215);
    //time1= new QTimer(this);
    video_button->setParent(this);
    video_button->move(710,20);
    //視頻按鈕按下處理
    connect(video_button,&MenuButton::clicked,[=](){
        video_button->zoom1();//彈跳
        video_button->zoom2();
        time1->start(500);//定時500ms
        connect(time1,&QTimer::timeout,[=](){
            time1->stop(); //關(guān)閉定時器
            my_pro->close();
            my_pro->start("./QVideo");   });
        });

    //家居按鈕
    MenuButton * sensor_button=new MenuButton(":/picture/sensor.png","",245,245);
    //time1= new QTimer(this);
    sensor_button->setParent(this);
    sensor_button->move(45,300);
    //硬件數(shù)據(jù)按下處理
    connect(sensor_button,&MenuButton::clicked,[=](){
        sensor_button->zoom1();//彈跳
        sensor_button->zoom2();
        time1->start(500);
        connect(time1,&QTimer::timeout,[=](){
            time1->stop();
            my_pro->close();
            my_pro->start("./senor");});
        });

    //地圖按鈕
    MenuButton * map_button=new MenuButton(":/picture/map.png","",240,245);
    map_button->setParent(this);
    map_button->move(400,300);

    //天氣按鈕
    MenuButton * weather_button=new MenuButton(":/picture/weather.png","",245,245);
    weather_button->setParent(this);
    weather_button->move(700,300);

    //進(jìn)程結(jié)束處理
    connect(my_pro,&QProcess::stateChanged,[=](){

    });
}

運(yùn)行結(jié)果:

基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源),IMX6ULL開發(fā),Linux,QT,車載終端

四、項(xiàng)目效果

4.1 實(shí)戰(zhàn)視頻

IMX6ULL智能車載終端

4.2 作者有話

該項(xiàng)目為作者之前某成品級項(xiàng)目的簡化版本,考慮到教學(xué)博客篇幅有限。作者將當(dāng)初項(xiàng)目的 “雛形”分享給大家,該項(xiàng)目可以實(shí)現(xiàn)簡單的智能車載終端的多級功能切換!代碼的整體框架兼容性很高,讀者朋友可以根據(jù)在作者的代碼基礎(chǔ)上進(jìn)行增加或者修改自己的功能!

后續(xù)作者空閑之后會將當(dāng)初智能車載終端的大部分功能和代碼都教學(xué)與分享給大家!包括:頁面切換,地圖功能實(shí)現(xiàn),倒車影像設(shè)計(jì)與流程絲滑的圖標(biāo)切換等。感謝的讀取朋友可以期待一波,希望該博客讓大家有所收獲!

五、代碼開源

代碼地址:?基于IMX6ULL的智能車載終端項(xiàng)目代碼資源-CSDN文庫

如果積分不夠的朋友,點(diǎn)波關(guān)注,評論區(qū)留下郵箱,作者無償提供源碼和后續(xù)問題解答。求求啦關(guān)注一波吧?!?。?/strong>文章來源地址http://www.zghlxwxcb.cn/news/detail-605006.html

到了這里,關(guān)于基于IMX6ULL的智能車載終端項(xiàng)目(代碼開源)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【基于IMX6ULL開發(fā)板開機(jī)攝像頭的自啟動】

    這里簡述項(xiàng)目相關(guān)背景: 最近在準(zhǔn)備暑期實(shí)習(xí)和秋招,準(zhǔn)備一個Camera項(xiàng)目,涉及調(diào)試內(nèi)核、優(yōu)化開機(jī)——從啟動到獲取第一幀圖像的時間,硬件平臺為 正點(diǎn)原子IMX6ULL開發(fā)板 ,攝像頭為 OV5640 ,內(nèi)核基于正點(diǎn)原子出廠linux源碼,根文件系統(tǒng)暫時選擇正點(diǎn)原子出廠文件系統(tǒng) 首先

    2024年02月08日
    瀏覽(18)
  • 嵌入式Linux實(shí)戰(zhàn)開發(fā)之項(xiàng)目總體概述(基于IMX6ULL)

    嵌入式Linux實(shí)戰(zhàn)開發(fā)之項(xiàng)目總體概述(基于IMX6ULL)

    現(xiàn)在越來越多的智能設(shè)備融入到我們的生活,然而,豐富的設(shè)備之下也是有一套基本的運(yùn)行框架,只是根據(jù)不同的需求增減相應(yīng)的功能從而滿足自身的需要。而電子產(chǎn)品量產(chǎn)工具項(xiàng)目,就是實(shí)現(xiàn)基礎(chǔ)的功能,可以作為一個基礎(chǔ)的模版,學(xué)成之后便可進(jìn)行擴(kuò)展,根據(jù)自身需求,

    2024年02月13日
    瀏覽(84)
  • iMX6ULL驅(qū)動開發(fā) | 讓imx6ull開發(fā)板支持usb接口FC游戲手柄

    iMX6ULL驅(qū)動開發(fā) | 讓imx6ull開發(fā)板支持usb接口FC游戲手柄

    手邊有一閑置的linux開發(fā)板iMX6ULL一直在吃灰,不用來搞點(diǎn)事情,總覺得對不住它。業(yè)余打發(fā)時間就玩起來吧,總比刷某音強(qiáng)。從某多多上買來一個usb接口的游戲手柄,讓開發(fā)板支持以下它,后續(xù)就可以接著在上面玩童年經(jīng)典游戲啦。 ?我使用的是正點(diǎn)原子的I.MX6U-ALPHA 開發(fā)板,

    2024年02月14日
    瀏覽(39)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】08.IMX6ULL通過GPIO子系統(tǒng)函數(shù)點(diǎn)亮LED

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】08.IMX6ULL通過GPIO子系統(tǒng)函數(shù)點(diǎn)亮LED

    通過GPIO子系統(tǒng)函數(shù)點(diǎn)亮LED 1、GPIO子系統(tǒng)函數(shù) 1.1 確定 led 的GPIO標(biāo)號,查看內(nèi)核中的gpiochip 查看 gpiochip ,以正點(diǎn)原子的IMX6ULL阿爾法開發(fā)板為例 查看原理圖,發(fā)現(xiàn)led接的引腳是 GPIO1_IO3,對應(yīng) /sys/kernel/debug/gpio 中的 gpiochip0 組,gpiochip0 組從0開始算起, 所以 GPIO1_IO3 對應(yīng)的標(biāo)號就

    2024年02月10日
    瀏覽(25)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】22.IMX6ULL開發(fā)板讀取ADC(以MQ-135為例)

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】22.IMX6ULL開發(fā)板讀取ADC(以MQ-135為例)

    IMX6ULL一共有兩個ADC,每個ADC都有八個通道,但他們共用一個ADC控制器 在imx6ull.dtsi文件中已經(jīng)幫我們定義好了adc1的節(jié)點(diǎn)部分信息 注意 num-channels = 2; ,這個表示指定使用ADC1的兩個通道,即通道1和通道2 如果你要使用多個ADC通道,修改這個值即可 配置ADC引腳的 pinctrl ,在自己的

    2024年02月12日
    瀏覽(60)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】05.IMX6ULL驅(qū)動開發(fā)_編寫第一個hello驅(qū)動【熬夜肝】

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】05.IMX6ULL驅(qū)動開發(fā)_編寫第一個hello驅(qū)動【熬夜肝】

    經(jīng)過以下四個步驟,終于可以開始驅(qū)動開發(fā)了 01.安裝交叉編譯環(huán)境【附下載地址】 02.IMX6ULL燒寫Linux系統(tǒng) 03.設(shè)置IMX6ULL開發(fā)板與虛擬機(jī)在同一網(wǎng)段 04.IMX6ULL開發(fā)板與虛擬機(jī)互傳文件 一、獲取內(nèi)核、編譯內(nèi)核 二、創(chuàng)建vscode工作區(qū),添加內(nèi)核目錄和個人目錄 三、了解驅(qū)動程序編寫

    2024年02月06日
    瀏覽(18)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】15.IMX6ULL驅(qū)動開發(fā)問題記錄(sleep被kill_fasync打斷)

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】15.IMX6ULL驅(qū)動開發(fā)問題記錄(sleep被kill_fasync打斷)

    發(fā)現(xiàn)問題的契機(jī): 學(xué)習(xí)異步通知的時候,自己實(shí)現(xiàn)一個功能:按鍵控制蜂鳴器,同時LED燈在閃爍 結(jié)果:LED好像也同時被按鍵控制了 最后調(diào)試結(jié)果發(fā)現(xiàn): 應(yīng)用層的 sleep 被驅(qū)動層的 kill_fasync 打斷,所以sleep沒有執(zhí)行完就重新進(jìn)入下一次循環(huán)了 修改代碼后解決該問題 解決邏輯就

    2024年02月13日
    瀏覽(18)
  • 基于IMX6ULL的AP3216C的QT動態(tài)數(shù)據(jù)曲線圖顯示

    基于IMX6ULL的AP3216C的QT動態(tài)數(shù)據(jù)曲線圖顯示

    前言: 本文為手把手教學(xué) Linux+QT 的典型基礎(chǔ)項(xiàng)目 AP3216C 的數(shù)據(jù)折線圖顯示,項(xiàng)目使用正點(diǎn)原子的 IMX6ULL ?阿爾法( Cortex-A7 系列)開發(fā)板。項(xiàng)目需要實(shí)現(xiàn) AP3216C 在 Linux 系統(tǒng)下的驅(qū)動,使用 QT 設(shè)計(jì) AP3216C 的數(shù)據(jù)顯示頁面作為項(xiàng)目的應(yīng)用層。該項(xiàng)目屬于非常簡單的入門級項(xiàng)目,核心

    2024年02月16日
    瀏覽(35)
  • IMX6ull SPI 協(xié)議

    IMX6ull SPI 協(xié)議

    1.1 SPI SPI 全稱是 Serial Perripheral Interface,也就是 串行外圍設(shè)備接口 。 SPI 是 Motorola 公司推出的一種同步串行接口 技術(shù),是一種高速、 全雙工的同步通信總線 , SPI 時鐘頻率相比 I2C 要高很多,最高可以工作 在 上百 MH z。 SPI 以主從方式工作,通常是有一個主設(shè)備和一個或多

    2024年02月12日
    瀏覽(26)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】03.設(shè)置IMX6ULL開發(fā)板與虛擬機(jī)在同一網(wǎng)段(設(shè)置開發(fā)板靜態(tài)IP)

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】03.設(shè)置IMX6ULL開發(fā)板與虛擬機(jī)在同一網(wǎng)段(設(shè)置開發(fā)板靜態(tài)IP)

    為什么要設(shè)置IMX6ULL與虛擬機(jī)通信? 因?yàn)橐言谔摂M機(jī)下編譯的文件傳到IMX6ULL開發(fā)板上運(yùn)行 設(shè)置好同一網(wǎng)段,可以互ping后,可以參考這篇博客,實(shí)現(xiàn)開發(fā)板與虛擬機(jī)的文件互傳 IMX6ULL開發(fā)板與虛擬機(jī)互傳文件 一、設(shè)置windows有線網(wǎng)卡 二、配置虛擬機(jī)雙網(wǎng)卡(原本有一個NAT網(wǎng)卡

    2024年02月07日
    瀏覽(50)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包