Desarrollo de vista previa de video de la interfaz principal de PUPANVR-UI

Desarrollo de vista previa de video de la interfaz principal de PUPANVR-UI

elección de interfaz de usuario

Originalmente consideré usar MINIGUI, pero al ver el estilo de control antiguo, pensé que sería demasiado molesto hacer las texturas más modernas, ¡y su método de código abierto no es muy fácil de usar!

Luego miré varias bibliotecas de UI y miré los ejemplos de la biblioteca LVGL. Aunque nunca la entendí bien, ¡me enamoré de ella al instante!

Bueno, ¡usemos LVGL!

trasplante

No es necesario hablar sobre el cambio de valor. El framebuffer es bastante simple. En la plataforma HiSilicon, puede ver la introducción a su uso en Hi3536C en el artículo anterior.

Proceso único o multiproceso

Me pregunto si necesito hacer de la interfaz de usuario un proceso independiente. Estoy un poco confundido. Si lo escribo como un proceso independiente, habrá más interacciones con el proceso de gestión de grabación en segundo plano en la interfaz de usuario. Pienso en Necesidad de modos de servidor y cliente, llamadas, notificaciones y decodificación de formato de protocolo requieren una gran cantidad de código. Siento que herramientas como gdbus no son fáciles de usar y la carga de trabajo no es pequeña. Si se utiliza el método de proceso único, en productos anteriores, a menudo hay llamadas coincidentes a cada módulo de código. Cuando hay más personas manteniéndolo, ¡las cosas a menudo se estropean más tarde! Pero en el modo multiproceso, ¡también es un dolor de cabeza si hay personalización del cliente en la parte delantera y trasera!
Teniendo en cuenta las interacciones posteriores y la cantidad de código, ¡usemos primero el método de proceso único! Limite todo el código de la interfaz de usuario a un directorio Ver. La comunicación y la interacción entre la interfaz de usuario y la interfaz externa se convierten a través de una capa, de modo que los métodos multiproceso posteriores se puedan modificar rápidamente.

Ver instrucciones básicas

¡Pongo todo el código de la interfaz de usuario en el directorio del proyecto de la vista y solo proporciono una inicialización view_main.h y algunas interfaces de llamada al mundo exterior!

		/*
		 * UI的初始化操作
		 * */
		int 	view_init();

		/*
		 * UI的退出操作
		 * */
		void 	view_exit();

		/*
		 * 进入UI处理过程
		 * */
		int		view_process();

Específicamente, puede ver la llamada en main.cpp, que es relativamente simple: después de la inicialización, el hilo principal se bloquea en view_process. ¡Uso estándar de UI!

Una interfaz view_lvgl.h está definida en la vista. Aquí definiremos algunas definiciones relacionadas con lvgl y las referenciaremos en el archivo de encabezado. ¡Y algunas operaciones relacionadas de lvgl!

		/*
		 * lvgl相关的初始调用
		 * */
		int 	view_lvgl_init();
		/*
		 * 退出lvgl
		 * */
		void 	view_lvgl_exit();

		/*
		 * 进入lvgl的UI处理
		 * */
		void	view_lvgl_process();

TView_App.h define una entrada para la inicialización de la aplicación UI. Lvgl también se inicializa oficialmente desde aquí. Más tarde, la inicialización inicial relacionada con la UI se puede colocar aquí, como una visualización de dibujo al inicio. Cree una UI en TView_App:: proceso
principal interfaz y llame a view_lvgl_process para ingresar oficialmente al flujo de procesamiento de la interfaz de usuario.

		int TView_App::process()
		{
			TViewMainWindow* appMainWnd = TViewMainWindow::getInstance();

			if(!appMainWnd->init())
			{
				LOG(ERROR) << "TViewMainWindow init failure!" << endl;
				return -1;
			}

			view_lvgl_process();

			return 0;
		}

TViewObject es una abstracción del objeto de la ventana de la interfaz de usuario.

Mirando la documentación de lvgl, no existe un concepto de ventana formal en lvgl, ¡parece que el diseño de ventana en varias bibliotecas de UI anteriores se ha debilitado intencionalmente! En las interacciones de interfaz de usuario modernas, como en nuestros teléfonos móviles, el mouse rara vez se usa para interactuar con varias pantallas y el estilo de la ventana es inapropiado. Personalmente, también abstraigo esto como una clase base y lo uso como una ventana de una clase base.

		class TViewObject
		{
		public:
			TViewObject();
			TViewObject(ViewHandle parentHandle);
			virtual ~TViewObject();
			/**
			 * 获取窗口对像句柄
			 * */
			virtual ViewHandle 	getViewHandle();
			/**
			 * 设置显示位置
			 * */
			virtual bool		setpos(int x, int y);
			/**
			 * 设置显示大小
			 * */
			virtual bool		setViewSize(int width, int height);

			virtual int			getViewWidth();

			virtual int 		getViewHeight();

			virtual bool 		viewShow();
			virtual bool		viewHide();

			/*事件处理*/
			virtual void		event_process(lv_event_t * event);
		private:
			static void			_event_process(lv_event_t * event);
		protected:
			/*LVGL的一个对像句柄*/
			ViewHandle m_viewHandle;
			/*LVGL的一个对像的基本样式*/
			lv_style_t m_style;
		};

ViewHandle m_viewHandle

Redefiní un ViewHandle en View, simplemente redefiniendo el typedef lv_obj_t* ViewHandle. ¡No hay manera, estoy acostumbrado al concepto de identificador de objeto! Dado que es un objeto LVGL, debe haber una definición de lv_obj_t.

lv_style_t m_estilo

Un lv_style_t m_style está definido en el objeto TViewObject. Principalmente cuando uso lvgl para crear cada objeto de ventana, descubrí que necesito establecer un estilo diferente. Se siente muy problemático. Cada ventana que sale de TViewObject lo necesita, por lo que debería colocarse directamente en la clase base.

evento_proceso vacío virtual (lv_event_t * evento);

En términos de procesamiento de eventos, encontramos que muchas ventanas necesitan procesar eventos. Al procesar eventos, deben definir una devolución de llamada de procesamiento de eventos. El C ++ utilizado aquí debe transferirse al objeto de ventana correspondiente para su procesamiento cada vez, por lo que es ¡Implemente directamente un método estático _event_process en la clase base y luego llame al método virtual event_process! En esta ventana de clase, si desea manejar eventos, ¡solo necesita anular este método! Sin embargo, parece que la respuesta de procesamiento predeterminada de LVGL no funciona. ¡Solo usé LVGL para ver cómo resolver este problema!

Construir y manejar TViewObject::TViewObject(ViewHandle parentHandle)

En el constructor, el objeto lv se crea directamente, se inicializa el estilo y se configura el procesamiento de eventos.

	TViewObject::TViewObject(ViewHandle parentHandle)
	{
		m_viewHandle = lv_obj_create(parentHandle);
		lv_obj_add_event_cb(m_viewHandle, _event_process, LV_EVENT_ALL, this);
		lv_style_init(&m_style);
		lv_obj_add_style(m_viewHandle, &m_style, 0);
	}

Cree una vista previa de video en la interfaz de usuario de NVR

Varios objetos se abstraen en la interfaz de usuario, TViewMultiVideoManage: uno es un administrador de ventanas de vista múltiple, que administra la división y el modo de visualización de videos; TViewPlayer: un reproductor de video en el nivel de la interfaz de usuario;

TViewMultiVideoAdministrar

Responsable de la creación de TViewPlayer y la visualización de modos. ¡Varios modos de visualización de reglas comunes están definidos en el sistema!

	typedef enum{
		View_Splite_Mode_UNKNOW = 0,
		View_Splite_mode_1 = 1,
		View_Splite_mode_4 = 4,
		View_Splite_mode_9 = 9,
		View_Splite_mode_16 = 16
	}ViewVideoPlayerSplitMode;

TViewMultiVideoManage actualmente hace lo siguiente:

  • En TViewMultiVideoManage, el TViewPlayer que crea cada canal se inicializa y se coloca en una estructura de mapa, indexado con el número del canal de video como Clave!;
  • Al configurar el modo de visualización de video, TViewMultiVideoManage será responsable de mostrar el TViewPlayer de esos canales y no mostrarlos allí;
  • Establecer el estilo del canal seleccionado;
  • Responsable de la visualización del recorrido en vídeo;

TVViewPlayer

¡TViewPlayer es responsable del estilo de visualización, el procesamiento comercial interactivo de la interfaz de usuario del canal, etc.! Si el usuario hace clic, significa que este canal está seleccionado, se cambia el estilo seleccionado y se llaman las interacciones relacionadas.

Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

Experiencia de uso de LVGL

A través de los pocos códigos anteriores, básicamente se logra una pantalla de vista previa de video de la interfaz de usuario de NVR. ¡Parece que LVGL es muy fácil de usar!

Simple, pocas capas y moderno, ¡esta es la sensación que me da LVGL! Solo lo usé durante dos días, leí un día de documentos y pasé un día probando varios controles y efectos para crear la interfaz de usuario principal del NVR. arriba, con muchos detalles. ¡Si no lo entiendes, es posible que lo estés usando mal! ¡Mejoremos según la experiencia en el futuro!

dirección de código

Dirección del código PUPANVR

Supongo que te gusta

Origin blog.csdn.net/jhting/article/details/122572476
Recomendado
Clasificación