Обсуждение статьи "Графические интерфейсы VI: Элементы "Чекбокс", "Поле ввода" и их смешанные типы (Глава 1)"

 

Опубликована статья Графические интерфейсы VI: Элементы "Чекбокс", "Поле ввода" и их смешанные типы (Глава 1):

С этой статьи начинается шестая часть серии о разработке библиотеки для создания графических интерфейсов в терминалах MetaTrader. В первой главе речь пойдёт о таких элементах управления, как «чекбокс», «поле ввода», а также о смешанных типах этих элементов.

Элемент «Чекбокс»

Элемент управления «чекбокс» предназначен для управления параметрами, у которых может быть только два состояния. Чтобы понять, в каком состоянии сейчас находится параметр, к которому привязан элемент, используется кнопка с двумя изображениями. Изображение с символом «галочка» обозначает состояние «включено» (on). Изображение без этого символа «галочка» обозначит состояние «выключено» (off). Рядом с кнопкой располагается краткое описание параметра. 

Собирать этот элемент будем из трёх графических объектов. Перечислим их.

  1. Фон
  2. Картинка (кнопка)
  3. Текстовая метка

Рис. 1. Составные части элемента управления «Чекбокс».

Рис. 1. Составные части элемента управления «Чекбокс».

Автор: Anatoli Kazharski

 

А ведь "подмигивание" при достижении крайних значений не будет работать в индикаторах - Sleep() же ...

Анатоль, записывай ещё одно пожелание к доработке: задержку организовывать через таймер, тем более, что почти всё для этого у тебя уже есть.

 
Artyom Trishkin:

А ведь "подмигивание" при достижении крайних значений не будет работать в индикаторах - Sleep() же ...

Анатоль, записывай ещё одно пожелание к доработке: задержку организовывать через таймер, тем более, что почти всё для этого у тебя уже есть.

Записал. Списочек растёт. Спасибо. )
 
Впечатляет... :)
 

Анатолий, созданная Вами библиотека в высокой степени готовности и вот решил попробовать создать на ней не большой проект для себя. Пишу в эту тем, так чтобы было понятно к какому элементу относится вопрос. Для поля ввода (SpinEdit) необходим ввод значений с точностью до двух десятых. Выставил соответствующие свойства (StepValue и StepDigits) в процедуре создания поля (см. код ниже):

...
   m_spin_edit_Depo.MaxValue(10000000);
   m_spin_edit_Depo.MinValue(0);
   m_spin_edit_Depo.StepValue(0,01);
   m_spin_edit_Depo.SetDigits(2);
   m_spin_edit_Depo.SetValue(v);
...

И после компиляции получил ошибку: 'StepValue' - no one of the overloads can be applied to the function call.

По логике если количество знаков для значения меньше 1, то и шаг приращения значения тоже может быть меньше единицы. При этом в коде класса, проверка введенного значения идет только на не отрицательность.

...

   //--- Шаг значения

   double            StepValue(void)                          const { return(m_step_value);               }
   void              StepValue(const double value)                  { m_step_value=(value<=0)? 1 : value; }
...

Вопрос в том, что мне не ясно, откуда взялась ошибка.

Далее у меня возник вопрос или пожелание. А если не требуется контролировать минимальное/максимальное значение и оно ограничено только размером используемой для его хранения переменной типа double? Из кода как я понял выставление минимальное/максимальное значений обязательно. Можно ли дописать мое пожелание в список доработок? Т.е. Если минимальное/ максимальное значения для поля не указаны, контроль введенных значений осуществлялся лишь на вхождение его в границы диапазона переменной типа double.

 
Pavel Trofimov:

И после компиляции получил ошибку: 'StepValue' - no one of the overloads can be applied to the function call.

...

Вопрос в том, что мне не ясно, откуда взялась ошибка. 

У вас опечатка. В качестве разделителя используйте точку "." :

   m_spin_edit_Depo.StepValue(0.01);

//---

Далее у меня возник вопрос или пожелание. А если не требуется контролировать минимальное/максимальное значение и оно ограничено только размером используемой для его хранения переменной типа double? Из кода как я понял выставление минимальное/максимальное значений обязательно. Можно ли дописать мое пожелание в список доработок? Т.е. Если минимальное/ максимальное значения для поля не указаны, контроль введенных значений осуществлялся лишь на вхождение его в границы диапазона переменной типа double.

Можете пока принудительно установить максимальное и минимальное. Вот так:

   m_spin_edit_Depo.MaxValue(DBL_MAX);
   m_spin_edit_Depo.MinValue(-DBL_MAX);
 
Anatoli Kazharski:

У вас опечатка. В качестве разделителя используйте точку "." :

//---

Можете пока принудительно установить максимальное и минимальное. Вот так:

Спасибо, огромное, за подсказку насчет опечатки. В своем коде глаза "мылятся". А насчет принудительного выставления максимального минимального - устроит. Запишу себе. Еще раз огромное спасибо!
[Удален]  

Здравствуйте сэр, мне интересна ваша статья, но я новичок в GUI и mql,
не могли бы вы мне подсказать как получить значение Spin edit, чтобы оно могло быть прочитано в советнике.

С уважением

 
Hidayat Nur Wahit:

Здравствуйте, сэр, мне интересна ваша статья, но я пока новичок в GUI и mql,
Можете, пожалуйста, рассказать мне, как получить значение Spin edit, чтобы его можно было прочитать в советнике.

С уважением

Например, из статьи в обработчике события CProgram::OnEvent():

void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Событие нажатия на текстовой метке
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_LABEL)
     {
      ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam);
      //--- Если нажали на первом чекбоксе
      if(lparam==m_checkbox1.Id())
        {
         m_checkbox2.CheckBoxState(m_checkbox1.CheckButtonState());
         m_spin_edit1.SpinEditState(m_checkbox1.CheckButtonState());
         
         Print("m_spin_edit1.GetValue(): ",m_spin_edit1.GetValue());
        }

      if(lparam==m_checkbox3.Id())
        {
         m_checkboxedit1.CheckBoxEditState(m_checkbox3.CheckButtonState());
         
         Print("m_checkboxedit1.GetValue(): ",m_checkboxedit1.GetValue());
        }

      if(lparam==m_checkbox4.Id())
        {
         m_checkcombobox1.CheckComboBoxState(m_checkbox4.CheckButtonState());
        }

      if(lparam==m_checkbox5.Id())
        {
         m_slider1.SliderState(m_checkbox5.CheckButtonState());
         m_dual_slider1.SliderState(m_checkbox5.CheckButtonState());
         
         Print("m_slider1.GetValue(): ",m_slider1.GetValue());
         Print("m_dual_slider1.GetLeftValue(): ",m_dual_slider1.GetLeftValue());
         Print("m_dual_slider1.GetRightValue(): ",m_dual_slider1.GetRightValue());
        }
     }

   if(id==CHARTEVENT_CUSTOM+ON_END_EDIT)
     {
      ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam);
      
      if(lparam==m_spin_edit1.Id())
        {
         Print("m_spin_edit1.GetValue(): ",m_spin_edit1.GetValue());
        }
        
      if(lparam==m_checkboxedit1.Id())
        {
         Print("m_checkboxedit1.GetValue(): ",m_checkboxedit1.GetValue());
        }
      
      if(lparam==m_slider1.Id())
        {
         Print("m_slider1.GetValue(): ",m_slider1.GetValue());
        }
        
      if(lparam==m_dual_slider1.Id())
        {
         Print("m_dual_slider1.GetLeftValue(): ",m_dual_slider1.GetLeftValue());
         Print("m_dual_slider1.GetRightValue(): ",m_dual_slider1.GetRightValue());
        }
     }

   if(id==CHARTEVENT_CUSTOM+ON_CLICK_INC || id==CHARTEVENT_CUSTOM+ON_CLICK_DEC)
     {
      ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam);
      
      if(lparam==m_spin_edit1.Id())
        {
         Print("m_spin_edit1.GetValue(): ",m_spin_edit1.GetValue());
        }
        
      if(lparam==m_checkboxedit1.Id())
        {
         Print("m_checkboxedit1.GetValue(): ",m_checkboxedit1.GetValue());
        }
     }
  }
[Удален]  
Anatoli Kazharski:

Например, из статьи в обработчике события CProgram::OnEvent():

Спасибо, сэр, и теперь он хорошо прочитал значение, и будет применяться на моем советнике.

С уважением.
 

Уважаемый Анатолий Кажарский, большое спасибо за эту замечательную библиотеку!

Мне очень нравится внешний вид и функциональность получаемых интерфейсов.

Когда я начал адаптировать Test Library 10.mq5 к своим личным нуждам, я подумал, что стоит упомянуть, что мне очень помогло добавление метода

void CSpinEdit::LabelText(const string new_text)

в класс CSpinEdit, который не делает ничего, кроме откладывания любого вызова CLabel::Description(const string new_text). Причина в том, что я использую CSpinEdit для разных типов значений в зависимости от состояния CComboBox. После изменения метки с помощью LabelText(text) и выбора соответствующего формата редактирования значения отображаются так, как нужно, после вызова

void CSpinEdit::ChangeValue(const double value)

Еще раз спасибо и с уважением