Último ++

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 5 de octubre de 2020; las comprobaciones requieren 8 ediciones .
Último ++

U++ La instantánea del IDE (editor de diseño seleccionado)
Tipo de Biblioteca de elementos de interfaz (widgets) , IDE
Desarrollador Mirek Fídler, Iñaki Zabala, Tomáš Rylek, Daniel Kos, Massimo Del Fedele, Zbigniew Rębacz + participantes del proyecto
Escrito en C++
Sistema operativo plataforma cruzada
ultima versión 2022.2 (rev. 16270) ( 27 de mayo de 2022 )
Licencia BSDL
Sitio web ultimatepp.org

Ultimate++ (también conocido como U++ y UPP ) es un conjunto de herramientas de desarrollo de software multiplataforma en el lenguaje de programación C++ . El objetivo de U++ es reducir la complejidad de las aplicaciones de escritorio típicas haciendo un uso intensivo de las funciones de C++. Funciona en Linux / X11 , BSD / X11 , Windows y desde la versión 2019.1 de MacOS X. El soporte de desarrollo para Android está en desarrollo [1] .

El proyecto se ha estado desarrollando desde 1999 , el núcleo del equipo de Ultimate++ está formado por programadores checos .

Características

Composición y propósito del marco

Es un marco diseñado no solo para proporcionar un desarrollo rápido de aplicaciones GUI , sino también, idealmente, para reemplazar todas las bibliotecas y herramientas de terceros para C ++, incluido incluso STL (que en U ++ es reproducido por la biblioteca NTL - Nueva biblioteca de plantillas). Ultimate++ es similar a Qt en este sentido, aunque va aún más lejos en esta dirección. Sin embargo, UPP, a diferencia de Qt, no extiende C++ con macroprocesadores de fuente no estándar, todas las herramientas de alto nivel de este marco, que parecen extensiones del lenguaje C++, se implementan a través de mecanismos estándar como la metaprogramación de plantillas y macros . Esto hace posible utilizar el mecanismo de plantilla al crear una interfaz, lo que hace posible lograr un código compacto y de fácil lectura. En términos de concisión, el código escrito con U++ se parece a los lenguajes de secuencias de comandos modernos de " supernivel " .

Ultimate++ incluye las siguientes bibliotecas:

Todos estos componentes están diseñados para usarse juntos y no están diseñados para funcionar individualmente. Ultimate ++ utiliza una organización de código específica en forma de los llamados "paquetes", por lo que es poco probable el desarrollo con Ultimate ++, pero sin usar TheIDE[ aclarar ] posible en la práctica.

Organización de las fuentes

El código fuente en U++ ocurre en categorías de paquetes (una idea familiar para los desarrolladores de Delphi o Lazarus ), en lugar de bibliotecas y archivos fuente dispares. Técnicamente, un paquete es solo un directorio separado que contiene los códigos fuente, que también contiene un archivo de descripción con una extensión upp. El IDE actualiza automáticamente los archivos .upp y son similares a los archivos make con descripciones de dependencias y marcas de compilación.

Cuando incluye un paquete en un proyecto, el IDE establecerá automáticamente las rutas y los indicadores necesarios para el compilador. El proyecto en sí también es un paquete que se puede conectar a otros proyectos de paquetes. Varios paquetes se combinan en un "nido" (nido), y los nidos se combinan en colecciones (ensamblajes).

El IDE coloca todos los programas creados en él en un árbol de paquetes global común. El usuario selecciona la raíz del árbol de paquetes cuando se inicia el IDE por primera vez, y todos sus programas solo se almacenarán en subdirectorios de este directorio.

Características de trabajar con widgets

La principal diferencia con otras bibliotecas de propósito similar es que todos los widgets generalmente se crean de forma estática, como las variables de miembro de clase ordinarias (aunque también se conserva la capacidad de crear widgets dinámicamente). Hay tipos especiales de campos de entrada para números reales y enteros. Por ejemplo, los widgets de la ventana de la calculadora se pueden describir de la siguiente manera:

clase MiVentana : public TopWindow { público : EditDouble val1 , val2 ; // Campos de entrada para operandos Label l1 , l2 ; // Etiquetas para campos de entrada Operación DropList ; // Lista desplegable de operaciones Label l3 ; // Etiqueta para la lista Botón computar ; // Calcular resultado de la etiqueta del botón ; // Etiqueta para el resultado

Luego, al colocar los widgets manualmente, debemos posicionarlos en la ventana del programa usando una función Add(widget)(ver la sección Hello World para un ejemplo de su uso ).

De hecho, los objetos de soporte de widgets existen en la memoria dinámica, pero están ocultos del alcance y se crean y destruyen automáticamente, operamos solo con sus "envoltorios" estáticos. Esto le permite deshacerse de la gestión manual de la memoria, ya no puede organizar una fuga de memoria al olvidarse de escribir delete . Es una buena práctica programar con Ultimate++ para nunca usar punteros para administrar recursos. Para gestionar conjuntos de datos de tamaño variable o de tipo polimórfico se utilizan contenedores NTL. No hay "punteros inteligentes" (como boost ::shared_ptr ) en NTL, no son necesarios y se consideran malas prácticas. Este enfoque de la gestión de la memoria en C++ ha demostrado ser bueno, prácticamente igualando la recolección de basura en términos de usabilidad y superándolo en términos de rendimiento y comportamiento determinista del programa.

Cada widget en U++ tiene algún significado "natural". Entonces, para el campo de entrada, el valor será el texto ingresado, para la lista, el elemento seleccionado, para el botón, el controlador de función para presionarlo. El operador ~widget (devuelve un valor del tipo de variante Value) se usa para obtener el valor de un widget, y el operador <<= value del widget se usa para configurarlo . Para establecer el valor de un widget, como un botón, en una función de controlador, debe "envolver" el nombre resp. función de miembro de clase en una macro THISBACK().

En la mayoría de las bibliotecas de GUI, como Qt , cada widget mantiene una lista de punteros a sus hijos, es decir, la jerarquía de widgets es una propiedad de las instancias de widgets y no depende del orden en que se definen en el cuerpo de la clase. En Ultimate++, sin embargo, la jerarquía se define únicamente a nivel de clase: cada widget contenedor que contiene otros widgets se define como una clase, de la que son miembros todos los widgets anidados.

Usando el editor de diseño

Existe una alternativa a la colocación manual de widgets en el constructor de ventanas: el editor de diseño visual (Editor de diseño). Los diseños creados en él son correctos para C++ e incluyen archivos que usan macros especiales y tienen la extensión .lay . Para trabajar con diseños, debemos incluir la biblioteca de encabezados lay.h en nuestro archivo C++, que incluye automáticamente el archivo de diseño especificado mediante la extensión #define LAYOUTFILE.

#define ARCHIVO DE DISEÑO <demo/demo1.lay> #include <CtrlCore.h>

Si el diseño se llama, por ejemplo , main , entonces para conectarlo a la clase de la ventana principal del programa, debe declararlo como

class MyWindow : public Withmain < TopWindow > {

donde Withmain es una clase de plantilla generada automáticamente por las macros lay.h basadas en el archivo lay. Utiliza una plantilla en lugar de una clase o estructura simple, por lo que puede usar cualquier tipo de widget como clase base, no solo un cuadro de diálogo ( TopWindow ).

Para organizar los widgets de la ventana de acuerdo con el diseño, al comienzo del constructor de archivos, debe agregar una llamada

CtrlLayout ( * esto );

Este enfoque de la edición de la interfaz visual hace posible compilar estáticamente los archivos de enlace, en lugar de interpretarlos en tiempo de ejecución, como hacen muchas herramientas GUI, lo que conduce a un mayor rendimiento de las aplicaciones creadas en Ultimate++.

Sin embargo, el editor de diseño no es un editor de interfaz visual completo como QtDesigner o Glade . Solo le permite establecer los nombres y las posiciones relativas de los widgets del mismo nivel de jerarquía. Todas las propiedades de los widgets (excepto las más simples, como la inscripción en un botón) y la lógica de su interacción están escritas en el código del programa.

Ejemplos

Solicitud mínima

#incluir <CtrlLib/CtrlLib.h> usando el espacio de nombres Upp ; GUI_APP_MAIN { }

Creando una ventana

#incluir <CtrlLib/CtrlLib.h> usando el espacio de nombres Upp ; clase MiVentana : public TopWindow { público : Mi Ventana () { título ( "¡Hola mundo!" ); MinimizarCuadro (); MaximizarCuadro (); considerable (); EstablecerRect ( 0 , 0 , 300 , 300 ); } }; GUI_APP_MAIN { Mi ventana (). ejecutar (); }

hola mundo

El siguiente ejemplo crea (sin usar el editor visual) una aplicación con un botón "HelloWorld".

#incluir <CtrlLib/CtrlLib.h> usando el espacio de nombres Upp ; clase MiAplicación : ventana superior pública { typedef MiAplicación NOMBRE DE CLASE ; público : MiAplicación () { título ( "hola mundo" ); botón _ SetLabel ( "¡Hola mundo!" ); botón <<= ESTO ATRÁS ( Click ); Agregar ( botón . HSizePos ( 100 , 100 ). VSizePos ( 100 , 100 )); } privado : Clic vacío () { if ( PromptYesNo ( "Se hizo clic en el botón. ¿Desea salir?" )) romper (); } botón botón ; }; GUI_APP_MAIN { miAplicación (). ejecutar (); }

Un ejemplo más complejo

En la sección de Comparaciones del sitio oficial, puede encontrar ejemplos de cómo crear un formulario bastante complejo en U++ y compararlo con la implementación de una funcionalidad similar en Qt , wxWidgets y Java / Swing .

Notas

  1. Trabajar con el constructor de Android . Consultado el 22 de diciembre de 2019. Archivado desde el original el 22 de diciembre de 2019.

Enlaces