Galería de interfaces de usuario escritas en MQL - página 58

 
hini #:

Sí, es importante lanzar primero un programa completo.

Lo haré.
 
Una versión básica del motor y el constructor plenamente funcional es un objetivo válido y alcanzable. Requiere un plan claro y establecer prioridades. A su vez, significa el fin de añadir grandes tareas a los planes y el comienzo de resolver problemas urgentes.

Permítanme hacer una analogía con la construcción de un rascacielos. Imaginemos un proyecto en el que el capataz no sabe exactamente cuántos pisos hay que construir. Supongamos que no ha sido informado. Pero en el fondo es un creador, una persona creativa. No le importa. Cuanto más grande, mejor. Le gustan las casas altas y los rascacielos. Mientras él trabaja, la construcción avanza, se añaden pisos y el edificio crece hasta el cielo. Pero los pisos no se pueden entregar a los inquilinos, porque no se han quitado los andamios ni se ha limpiado el espacio habitable. Ni siquiera se han colocado las puertas. La casa está inacabada. Pero para el capataz son nimiedades. Él mira hacia arriba. Al cielo. Y los inquilinos esperan impacientes, necesitan pisos.

En general, es hora de que el capataz "cambie el firmware" y se reorganice mentalmente. Dejar de construir pisos y empezar a poner puertas en los huecos. Y, por último, empezar a limpiar la zona, enlucir las paredes, poner parqué e instalar lámparas de araña .....

Lo diré de este modo: los suelos, por ahora, no se construirán. En cambio, se terminarán los suelos ya construidos. Los trabajos se planificarán de tal manera que la casa se entregue a los inquilinos lo antes posible.

Al fin y al cabo, la casa se construyó para ellos....


 

Hola a todos,

A la luz de la reciente discusión, me gustaría proponer que documentemos los resultados y el progreso del proyecto de Peter Konow en el "Codebase" en lugar de en el foro. El foro es excelente para las discusiones y los comentarios inmediatos, pero carece de la estructura y la coherencia necesarias para presentar el panorama general y las políticas coherentes del proyecto.

Si utilizamos la "Codebase", nos aseguraremos de que toda la información relevante esté organizada, sea fácilmente accesible y ofrezca una visión clara del estado del proyecto. Esto no sólo ayudará a mantener la claridad, sino también a facilitar una mejor colaboración y comprensión entre todos los miembros del equipo y las partes interesadas.

Le agradecería mucho que tuviera en cuenta esta sugerencia.

 
Yutaka Okamoto proyecto de Peter Konow se documenten en Codebase en lugar de en el foro. El foro es estupendo para debatir y recibir comentarios inmediatos, pero carece de la estructura y la coherencia necesarias para presentar el panorama general y las políticas coherentes del proyecto.

Utilizando una "Codebase" podemos garantizar que toda la información relevante esté organizada, sea fácilmente accesible y ofrezca una imagen clara de la situación del proyecto. Esto no sólo ayudará a mantener la claridad, sino que también fomentará una mejor cooperación y comprensión entre todos los miembros del equipo y las partes interesadas.

Le agradecería mucho que considerara esta propuesta.

Es una sugerencia muy racional, gracias. Sin duda, la base de código es conveniente para publicar actualizaciones y comunicarse con los usuarios. Es una gran aportación al desarrollo del proyecto. Aunque apenas he utilizado la codebase en el pasado, ahora veo el sentido práctico de explorar las condiciones y adaptarme a los requisitos. Para hacerme una idea de las posibilidades y limitaciones de esta plataforma, buscaré proyectos de miembros conocidos de la comunidad. Tomando su ejemplo, podré llevar a cabo el proyecto en la codebase de forma informativa y competente.

 

Tengo una versión programada para hoy.

Sin embargo, he decidido seguir el útil consejo de un miembro del foro y publicar la nueva versión en la base de código. Para hacerlo bien, necesitaré unos días para estudiar ejemplos de publicaciones similares, para hacer un plan de funcionamiento paralelo del proyecto en el foro y allí. Y también para pasar por la moderación.

Algunas palabras sobre esta versión:

1. Conceptualizado e implementado un sistema de interacción programática entre un programa de usuario y su interfaz gráfica.

Más detalles:

  • Tras realizar pruebas técnicas y analizar los resultados, se decidió utilizar funciones envolventes de elementos en lugar de propiedades globales abstractas. Resultó ser la variante más eficaz y sencilla de acoplamiento programático de algoritmos con el entorno gráfico.
  • Se realizaron adiciones a las funciones de guardado e impresión de proyectos de los archivos UIDATA.mqh y API.mqh para que cada elemento interactivo de la interfaz reciba automáticamente una función envolvente al guardar el proyecto.
  • Al mismo tiempo, las funciones de envoltura de elementos tienen un cuerpo muy pequeño y su tarea principal es llamar a la función central, pasándole tres parámetros principales: número de elemento, valor y valor de propiedad.
  • Lasimplicidad externa de las funciones no impide la versatilidad de su aplicación:

1. Cuando se llaman con los corchetes vacíos, las funciones devuelven el valor del parámetro elemento con uno de los tres tipos: int, double, string en función del tipo del elemento.

     int i    = w6_i_CHECKBOX_Some_checkbox(); //Элемент чекбокс. Буква i  после префикса означает что тип возвращаемого/устанавливаемого значения int.
     
     double d = w6_d_S_EDIT_Spin_the_value();  //Элемент поле ввода с кнопками. Буква d после префикса означает что тип возвращаемого/устанавливаемого значения double.

     string s = w7_s_EDIT_Comment_1();         //Элемент текстовое поле ввода. Буква s означает что тип возвращаемого/устанавливаемого значения string.

2. Cuando se llaman con un valor entre paréntesis, las funciones establecen el valor pasado al parámetro elemento y luego lo redibujan (el valor se establece en int, double o string, dependiendo del tipo de elemento).

     int i    = w6_i_CHECKBOX_Some_checkbox(0/1/2/3); //Элемент чекбокс. Передача нуля,единицы, двойки или тройки для смены между нейтральным, активированным, нетр.блокир. и актив. блокир. состояниями элемента. 
                                                      //Тот же метод работает для всех кнопок.
     
     double d = w6_d_S_EDIT_Spin_the_value(653.89);   //Элемент поле ввода с кнопками. Передача значения параметра в функцию для установки его в элемент.

     string s = w7_s_EDIT_Comment_1("Any text");      //Элемент текстовое поле ввода. Передача текста для установки в поле ввода.   


3. cuando se llama con el valor por defecto del primer parámetro y un número de propiedad (de las propiedades disponibles), las funciones devuelven el valor de esta propiedad del elemento (todos los números de propiedad son de tipo int, pasados en el parámetro propiedad).

      int i = w6_i_BUTTON_Start(get_i,_A_COLOR); //Элемент Кнопка. Возврат значения цвета из свойства _A_COLOR. Может быть указано другое значение или другое свойство из списка доступных свойств.
                                                                  //Однако, данных тип функции принимает значения только типа int, но может приводить их к другим родственным типам (uint, short, bool...).
                                                                  //Значение первого параметра get_i говорит функции что не нужно принимать значение первого параметра в расчет, а лишь вернуть значение свойства _A_COLOR.


4 . Cuando se llaman convalor y valor depropiedad entre paréntesis, las funciones establecen los valores pasados a las propiedades disponibles del elemento. El número de propiedad se pasa en el parámetro property , el valor de la propiedadse pasa en el parámetrovalue .

     int i = w6_i_BUTTON_Start(C'255,0,0',_A_COLOR); //Элемент Кнопка. Передача и установка польз. значения цвета в свойство _A_COLOR. Может быть указано другое значение или другое свойство из списка доступных свойств.
                                                                      //Однако, тип функции этого элемента принимает значения только типа int, но может приводить их к другим родственным типам (uint, short, bool...).


La estructura de los nombres de las funciones-wrapper: w6_i_BUTTON_Start();

1. w es la letra inicial de todas las funciones wrapper. Es una abreviatura de ventana.

2. 6 (u otro número) - el número de secuencia de la ventana que contiene el elemento.

3. i (ya sea d o s) - significa el tipo del valor devuelto/establecido del parámetro del elemento.

  • Puede ser int: para botones, casillas de verificación, deslizadores, campos de entrada con/sin botones, barras de progreso, barras de gráfico, botones de radio.
  • Puede ser double: para controles deslizantes, campos de entrada con/sin botones.
  • Puede ser cadena: para campos de entrada de texto, para elementos VALUE, para celdas de tabla, para listas emergentes.


4. BUTTON - nombre del tipo de elemento al que pertenece la función envolvente. Puede ser cualquier otro elemento.

5. INICIO - nombre de un elemento específico .


  • Todas las funciones wrapper tienen una estructura de nombres idéntica.
  • Repito: todas las funciones se imprimen automáticamente.

//----------------------------------------------------------------------------------------------------

Aplicación inteligente del sistema intellisense:

Se decidió utilizar un sistema especial de prefijos que ayuda a buscar y encontrar rápidamente las funciones-wrappers necesarias de ventanas y elementos. He aquí un ejemplo:

Todas las funciones-wrapper de ventanas y elementos tienen la letra w al principio. Sin embargo, si pone un guión bajo después de w: _ se abre una ventana intellisense con una lista de nombres de todas las funciones de ventana de la interfaz de usuario. A continuación, tienes que encontrar la ventana con el nombre que buscas en la lista, mirar su número (está impreso en el nombre de la función) y borrar el guión y poner este número después de w. Enseguida aparecerá la lista de intellisense con los nombres de las funciones de los elementos incluidos en la ventana. Así es como se hace:

Esta es una forma sencilla de navegar rápidamente por la lista de funciones de envoltura de elementos. Ni siquiera es necesario imprimirlas.

//----------------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------

También se han hecho cambios y adiciones al archivo API. Ahora más información sobre el elemento y la ventana está disponible para el usuario:

 switch(Element)
   {
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      BUTTON
//NAME:         Start
//PARAMETER:    int
//INIT STATE:   OFF
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   int w6_i_BUTTON_Start(int value = none, int Property = 0)      | PFX: w6
//=====================================================================================================================
  
case Settings_example_1___Start:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when button pressed or released?
               //------------------------------------------------------------------------------------------------------
               switch((int)action)
               {
                case pressed:  Alert("BUTTON Start pressed!");   break;
  
                case released:  Alert("BUTTON Start released!");   break;
               }
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
  
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      CHECKBOX
//NAME:         Set an option
//PARAMETER:    int
//INIT STATE:   OFF
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   int w6_i_CHECKBOX_Set_an_option(int value = none, int Property = 0)      | PFX: w6
//=====================================================================================================================
  
case Settings_example_1___Set_an_option:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when checkbox checked or unchecked?
               //------------------------------------------------------------------------------------------------------
               switch((int)action)
               {
                case checked:  Alert("CHECKBOX Set_an_option pressed!");   break;
  
                case unchecked:  Alert("CHECKBOX Set_an_option released!");   break;
               }
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
  
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      CHECKBOX
//NAME:         Set another option
//PARAMETER:    int
//INIT STATE:   OFF
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   int w6_i_CHECKBOX_Set_another_option(int value = none, int Property = 0)      | PFX: w6
//=====================================================================================================================
  
case Settings_example_1___Set_another_option:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when checkbox checked or unchecked?
               //------------------------------------------------------------------------------------------------------
               switch((int)action)
               {
                case checked:  Alert("CHECKBOX Set_another_option pressed!");   break;
  
                case unchecked:  Alert("CHECKBOX Set_another_option released!");   break;
               }
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
  
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      D_LIST
//NAME:         D_LIST 1
//PARAMETER:    string
//INIT OPTION:  L_ITEM  1
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   string w6_s_D_LIST_D_LIST_1(string value = get_s, int Property = 0)      | PFX: w6
//=====================================================================================================================
 
Espero probar estas funciones pronto.
 
hini #:
Espero probar estas características pronto.
Subiré la nueva versión a codobase mañana por la tarde.
 
Liberación nocturna.
 

Presento una versión del motor interactuando programáticamente con la GUI.

He hecho mucho. Hay algo que contar y mostrar.

Después de las pruebas públicas lo subiré a la base de código.

Ha resultado algo interesante...

Más detalles mañana.

Archivos adjuntos:
4uh38_06.08.24.zip  1712 kb
 

Adelantándome un poco, puedo decir que he encontrado una solución muy cómoda para los usuarios. Dentro de su código pueden navegar fácilmente a través de ventanas, elementos y propiedades. La solución les permite no recordar los nombres de los elementos o propiedades, sino encontrarlos fácilmente y trabajar con ellos. Al mismo tiempo, cada elemento tiene una lista de propiedades get/set disponibles sólo para él y los elementos "relacionados". Con el prefijo incrustado en el nombre de la función del elemento, el usuario la llama y nunca cometerá el error de intentar devolver o establecer una propiedad que el elemento no tiene.

Las funciones envoltorio han resultado ser tan versátiles y fáciles de usar que yo mismo me sorprendo. Devuelven el valor de un parámetro cuando los corchetes están vacíos, establecen cuando el valor es uno, devuelven el valor de una propiedad de una lista cuando el primer parámetro está vacío y el índice de la propiedad está en el segundo. Establecen un valor a una propiedad cuando hay un valor en el primer parámetro y un índice de propiedad en el segundo. También devuelven una notificación de resultado como 1 en caso de éxito, y -1 en caso de error (valor o propiedad no válidos). Las funciones redibujan los propios elementos. No necesitas ocuparte de esto.

Lo que puedes hacer con las funciones wrapper:

1. 1. Obtener el valor del parámetro del elemento.

2. Establecer el valor de un parámetro de elemento.

3. Obtener valores de propiedades de elementos de la lista individual de propiedades pertenecientes a su tipo de elementos (llamados por el prefijo escrito en el nombre de la función).

4. Establecer valores de propiedades de elementos de la misma lista.

5. Establecer el estado del elemento: neutro, activado, (encendido/apagado), bloqueado neutro, bloqueado activado.

6. Devuelve el estado actual del elemento.


En el primer caso la función devuelve el valor del parámetro.

En el segundo caso devuelve el resultado: éxito o error. El error se envía al log.

En el tercer caso, devuelve el valor de la propiedad.

En el cuarto - resultado: éxito o error de la configuración de la propiedad.

En el quinto, devuelve 1 o -1.

En el sexto - devuelve el índice de estado del elemento (detalles más abajo).


Todo se hace mediante una función envolvente que se imprime automáticamente. Para encontrarla, escribe w_, se abrirá la lista de intellisense, contiene los nombres de las ventanas. En una de ellas está el elemento que buscas. Tienes que recordar más o menos en qué ventana está. Entonces, borra el diablo y escribe el número de la ventana y selecciona la que necesitas de la lista de elementos. Sin memorización.

Tampoco necesitas recordar las propiedades de los elementos. Mira el nombre del elemento, ve el prefijo para abrir una lista de propiedades individuales. Escríbala, ábrala, seleccione la propiedad. No necesitas recordar nada en absoluto. Tampoco hay que teclear nada. Intellisense lo hace todo.

Windows también tiene sus propias envolturas. Pueden abrirlas y cerrarlas. El resto de las características no se han implementado todavía.


Hice una gran actualización al archivo API. Ahora tiene una ENORME cantidad de información más útil sobre el elemento. A saber: prefijos, propiedades individuales, prototipos de la función envolvente del elemento y su ventana, la localización exacta del elemento (tabla, lienzo y pestaña a la que pertenece el elemento, si existe), el tipo de su parámetro (int, double, string...), se imprimen las propiedades de su parámetro (valor.min, valor.max, paso, número de dígitos después del punto decimal). Valor inicial u opción seleccionada (según el elemento). Todo está diseñado bastante legible y comprensible.

He probado parcialmente la nueva funcionalidad y estoy satisfecho con ella. Todo funciona según lo previsto.

Mañana lo mostraré en la práctica.