前言:

随着4G/5G的发展,无线带宽不断的扩大,数据流量费用不断的降低,使得现在的实时网络视频和视频监控逐渐的普及。

传统的安防项目和车载监控系统都离不开音视频的录制,保存,回放,再加上现在的远程实时视频和远程视频文件调取下载,使得车载终端以及DVR这类设备得以继续的发展。

这里介绍一种使用QT来设计的,适用于安防或是DVR等嵌入式终端使用的控制界面。

说明:

  • QT版本:qt-everywhere-opensource-src-5.9.0
  • qt-creator版本:qt-creator-opensource-linux-x86_64-4.7.0.run
  • 运行设备:HI3520DV300,ARM Cortex A7 @Max. 800MHz,nand flash 128M
  • 编译环境:Ubuntu16.04
  • 交叉编译工具:arm-hisiv300-linux-
  • 测试平台:海思HI3520DV300,Ubuntu16.04

功能介绍:

主要涉及到音视频应用中的:
实时视频预览;录像设置;录像查询;设备状态查询;触发设置;系统设置
六大功能模块。

设计思路:

  1. 由于系统资源的有限性,并且为了软件的更加稳定可靠,将QT界面程序与海思音视频数据实际操作的模块区分开来,分开到两个独立的进程中去实现,海思程序主要处理硬件和海思平台相关的内容,QT程序主要处理界面显示和参数查询设置等内容。它们之间可以通过进程间通信(IPC)来交换信息。
  2. 视频预览和视频回放功能:
    由于在嵌入式设备中,系统资源有限,设备运行能力有限,所以将视频显示类的放到嵌入式设备中去实现。这海思平台,可以直接使用海思的硬件编解码来处理视频图像的显示。
  3. 参数设置和保存:
    视频编码和视频预览存储等等的这些参数,在海思程序中进行保存,QT界面需要显示的时候再去向海思程序查询这些参数的值,这样可以确保查询到的参数与实际使用的参数相同,如果要修改某些参数,也是通过QT界面进行设置,然后再将参数传回海思程序中保存。

详细设计:

  1. 海思程序,在设备上电之后,根据各种参数自动开始检测设备状态,状态正常后自动开始视频录制,存储设备存满之后,根据设置的条件,自动按条件进行覆盖操作。
  2. QT程序,主界面按功能模块分成实时视频预览,录像设置,录像查询,设备状态,触发设置,系统设置这6大模块,实际也就是6个按钮,用户通过鼠标或是触摸屏进行选择操作。
  3. QT程序主界面程序启动后,在后台建立一个线程,用来监听和接收海思模块发送过来的数据和命令(该项目使用的是在IPC队列基础上封装了一层协议的IPCP消息队列)。
  4. QT程序中,每个Qt功能模块就是一个独立的线程,也就是一个子菜单就是一个线程,只有在选中的时候才运行,子菜单关闭线程退出。
  5. QT程序里,各线程各对象之间的通信使用QT的信号和槽函数来实现。

QT界面设计:

主界面菜单参考了刘典武的界面设计,子菜单的界面则全是自己弄的,没有美工,只能说是凑合的将这些功能实现。






代码实现:

完整工程代码目录

biao@ubuntu:~/QT/qt_pro/HST_DVR_GUI$ 
biao@ubuntu:~/QT/qt_pro/HST_DVR_GUI$ tree
.
├── dvrGUI.pro
├── dvrGUI.pro.user
├── GUI_IPCPManager
│   ├── guiIPCManager.cpp
│   └── guiIPCManager.h
├── GUI_UI
│   ├── appinit.cpp
│   ├── appinit.h
│   ├── camaraview.cpp
│   ├── camaraview.h
│   ├── camaraview.ui
│   ├── dvrgui.cpp
│   ├── dvrgui.h
│   ├── dvrgui.ui
│   ├── head.h
│   ├── iconhelper.cpp
│   ├── iconhelper.h
│   ├── keyBoard.cpp
│   ├── keyBoard.h
│   ├── main.cpp
│   ├── main.qrc
│   ├── search.cpp
│   ├── search.h
│   ├── search.ui
│   ├── storage.cpp
│   ├── storage.h
│   ├── storage.ui
│   ├── SysInclude.h
│   ├── system.cpp
│   ├── system.h
│   ├── system.ui
│   ├── trigger.cpp
│   ├── trigger.h
│   ├── trigger.ui
│   ├── users.cpp
│   ├── users.h
│   ├── users.ui
│   ├── video.cpp
│   ├── video.h
│   └── video.ui
├── image
│   ├── DroidSansFallback.ttf
│   ├── fontawesome-webfont.ttf
│   └── main.bmp
├── IPCP_LIB
│   ├── AppDefine.h
│   ├── AppInclude.h
│   ├── HstlibIpcpCommon.h
│   ├── HstlibIpcpInterface.cpp
│   ├── HstlibIpcpInterface.h
│   ├── HstlibIPCPMsgStuct.h
│   ├── SysDebug.h
│   ├── SysDefine.h
│   └── SysInclude.h
└── main.qrc

4 directories, 51 files
biao@ubuntu:~/QT/qt_pro/HST_DVR_GUI$ 

注意事项:

(一)QT运行慢问题

我在海思HI3520DV300设备上运行,当拖动QT界面的时候,CPU使用率会非常的高,但是正常运行的时候基本上不占用CPU,初步定位是当界面刷新的瞬间占用CPU高,不确定是HI3520DV300的处理能力不行还是移植的QT哪里设置不对。

(二)QT图层隐藏问题

在Ubuntu中我们要隐藏QT界面方法有很多,但是有些在海思HI3520中不起作用。在海思中它是按图层来出来,需要隐藏QT图层,其实不需要去设置海思的fb参数,而是直接在QT程序中使用下面的方法三来实现:

/************************************************* 
Function:	 on_btnMsg_pressed  
Description: 右上导航按键
Return: 
Others: 点击关闭不是实际关闭,而是隐藏
	1.注意鼠标的隐藏
	2.鼠标离开了菜单之后失效
	3.setVisible 在海思开发板上不生效
Author: Caibiao Lee
Date:	2019-06-05
*************************************************/
void DVRgui::on_btnMsg_pressed()
{
	  /**方法1**/
//    this->setWindowOpacity(0);
//    this->setAttribute( Qt::WA_TranslucentBackground,true );
//    this->setWindowFlags( Qt::WindowMinimizeButtonHint );
//    exit(0);GuiIPCPSendHeartBeat

	  /**方法2**/
//    this->setVisible(true);
//    this->setHidden(true);

     /**方法3**/
	this->setHidden(true);
	this->setCursor(Qt::BlankCursor);	//隐藏鼠标
}

(三)鼠标问题

要想在海思平台中运行QT,并且支持鼠标控制界面,这个需要配置内核,使内核支持你所使用的鼠标类型。在我使用的HI3520SDK中,内核默认并没有配置鼠标使用的工程。
QT鼠标不支持热拔插,所以在需要在设备启动之前插入鼠标
鼠标正常配置,正常运行的时候,在/dev/input 下可以看到下面设备:

/dev # cd input/
/dev/input # ls
event0  mice    mouse0
/dev/input # 

event0  mice    mouse0 这三个设备,少一个都会出现异常。

(四)字体问题

在QT5中,我们不需要单独的将QT的字体库文件拷贝到ARM设备上,也不需要单独的设置环境变量。将字体库当做QT的资源文件添加到QT工程中去,在程序中加载库文件,这样QTcreater在编译程序的时候就会将QT的字符库文件一起打包到执行文件中去

。我这里使用的字体库是DroidSansFallback.ttf,它支持英文,中文,还有一些特殊图案和符号的显示。

/************************************************************
*Copyright (C), 2017-2027,lcb0281at163.com lcb0281atgmail.com
*FileName: main.cpp
*Date:     2019-06-05
*Author:   Caibiao Lee
*Version:  V1.0
*Description:
*Others:
*History:
***********************************************************/
#include "qapplication.h"
#include "appinit.h"
#include "dvrgui.h"
#include "video.h"
#include "search.h"
#include "storage.h"
#include "users.h"
#include "system.h"
#include "trigger.h"
#include "keyBoard.h"

#include <QFontDatabase>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QFont iconFont;
    int fontId = QFontDatabase::addApplicationFont(":/image/DroidSansFallback.ttf");
    QStringList fontName = QFontDatabase::applicationFontFamilies(fontId);

    if (fontName.count() > 0) {
        iconFont = QFont(fontName.at(0));
    } else {
       qDebug() << "load DroidSansFallback.ttf error";
    }

    a.setFont(iconFont);

	/**添加虚拟键盘**/
    keyBoard keyBoard;
    keyBoard.hide();


    /**move the windows**/
    AppInit::Instance()->start();

    /**the main UI**/
    DVRgui w;
    w.show();

    return a.exec();
}

(五)主界面图案

主界面上的六个图案并不是手动画上去的,其实它也是字体库中的一个符号,在DroidSansFallback.ttf库中已经实现,它通过数字码找到具体的图案,数字码可以去下面这两个网中查询:

http://fontawesome.dashgame.com
https://fontawesome.com/cheatsheet?from=io

主界面框的设置代码如下:

/************************************************* 
Function:	 initNav  
Description: 初始化选择菜单
Return: none
Others: none
Author: Caibiao Lee
Date:	2019-06-05
*************************************************/
void DVRgui::initNav()
{
    QList<QString> listColorBg;
    listColorBg << "#1570A5" << "#16A085" << "#C0392B" << "#047058" << "#9B59BB" << "#34495E";
    QList<QString> listColorText;
    listColorText << "#FEFEFE" << "#FEFEFE" << "#FEFEFE" << "#FEFEFE" << "#FEFEFE" << "#FEFEFE";

    /**Define QChar Variable**/
    QList<QChar> listChar;
    listChar << 0xf03d << 0xf1c8 << 0xf002 << 0xf030 << 0xf083 << 0xf085;
    QList<QString> listText;
    listText << "视频预览" << "录像设置" << "录像查询" << "设备状态"  << "触发设置" << "系统设置";

    /**Add QToolButton To QList**/
    btns << ui->btnViewMap << ui->btnViewPanel << ui->btnData << ui->btnMap << ui->btnDevice << ui->btnConfig;

    /**set Style Sheet of the QToolButton**/
    for (int i = 0; i < btns.count(); i++) {

        /**Returns the item at index position i in the list.**/
        QToolButton *btn = btns.at(i);
        btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
        btn->setIconSize(QSize(iconWidth, iconHeight));

        QPixmap pix = IconHelper::Instance()->getPixmap(listColorText.at(i), listChar.at(i), iconSize, iconWidth, iconHeight);
        btn->setIcon(QIcon(pix));
        btn->setText(listText.at(i));

        QStringList list;
        list.append(QString("QToolButton{font:%1px;background:%2;}").arg(iconSize / 2.5).arg(listColorBg.at(i)));
        list.append(QString("QToolButton{border:none;border-radius:8px;padding:30px;}"));
        list.append(QString("QToolButton:pressed{background:%1;}").arg("#737A97"));
        btn->setStyleSheet(list.join(""));

        connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClicked()));
    }
}

(六)鼠标作用域问题:

在海思平台运行QT程序与在PC及上还是有差异的,在海思平台,QT的鼠标只能在QT窗口范围内有效,如果窗口进行了拖动,或者是人为的移动了窗口位置,但是鼠标的位置没有做相应的移动,当鼠标处于QT窗口外时,鼠标的任何操作QT程序都会检测不到,

同样,鼠标也不能移动。在进行主界面隐藏之后,QT程序是不能够通过鼠标进行唤醒QT程序的,这时只能是通过外部发送一个信号,比如海思设备端的按键信号,触摸屏的信号,当QT接收到信号之后,再在其绑定的槽函数中将主界面拉回画面中。

工程获取


liwen01
公众号中回复
QT
获取工程代码,本章代码工程名为:
hisi_dvr_gui.rar

---------------------------End---------------------------
长按识别二维码
关注 liwen01 公众号

标签: none

添加新评论