MQL로 작성된 UI 갤러리 - 페이지 77

 

VE 개발의 현재 단계:

  • 코어의 약 400여 개의 창 속성, 요소 및 매개변수가 에디터 창에 통합되어 탭으로 표시됩니다. 이들 모두는 VE에서 생성된 GUI 요소의 제어 가능한 설정이 됩니다.
  • 사용자 작업에 필요한 다양한 제어 요소의 52개 템플릿이 통합되어 있습니다.
  • 디자인과 스타일링에 많은 노력을 기울였습니다. VE GUI의 실용성과 사용성을 확보하기 위해 다양한 솔루션을 계속 검토하고 있습니다.
  • 템플릿과 속성의 통합과 정렬 및 배포가 완료되면 기능에 대한 작업이 시작됩니다.
  • 현재 GUI는 KIB 마크업 언어로 작성되어 있어 상당히 지루한 작업입니다. 시각적 편집으로의 전환은 아직 이루어지지 않았습니다. 그러나 이것은 가까운 장래에 일어날 것입니다.
  • 그래픽 결함이 있습니다. 일시적인 현상입니다.
  • 공간을 절약하기 위해 작업 표시줄의 높이가 줄었습니다.
  • 편집기 창의 프레임이 시야 밖으로 이동되어 공간이 더 넓어졌습니다.


 
피터, VE를 사용하여 자체적으로 빌드하면 UI 디자인이 어떻게 작동하는지에 대한 귀중한 통찰력을 얻을 수 있을 것 같습니다.
다음 개발 업데이트가 기대됩니다.
 
Douglas Prager #:
멋진 말씀이네요, 피터. VE를 사용하여 직접 빌드하면 UI 디자인이 어떻게 작동하는지에 대한 귀중한 통찰력을 얻을 수 있을 것 같습니다.
다음 개발 업데이트가 기대됩니다.
고마워요, 더글러스. 네, 맞습니다. 극복해야 할 최소한의 기술적 '문턱'이 있습니다.

저도 관심을 가지고 근본적인 개발 과정을 지켜보겠습니다.
 
Doerk Hilger #:

모든 벡터 기반이며 완전히 확장 가능하고 모든 디스플레이에 맞게 조정 가능합니다.
모든 시각적 디스플레이는 구독 설정에 따라 이벤트 우선 순위에 따라 모든 MQL 이벤트를 처리하고 객체에 배포하는 핵심 클래스 내에서 비동기적으로 작동합니다.

나는 내가 매우 흥미로운 스레드를 훔치는 것이 아니기를 바라며, 만약 그렇다면 피터를 용서하십시오, 그것은 단지 이론적 인 관심에 대한 짧은 대답을 바라는 토론이 아닐 것입니다 - 당신은 시스템에 인스턴스화 된 모든 클래스 객체를 알고 (모든 객체 포인터를 추적) 각 객체가 해당 제어 정적 클래스에 필요한 이벤트를 구독 할 수있는 액세스 권한을 가지고 있고 그 정적 제어 싱글 톤 클래스가 모든 객체에 이벤트를 전달하는 일종의 정적 클래스가 있다는 것을 의미합니까? 그렇다면 OOP 측면에서 올바른 것으로 보십니까 아니면 허용되는 이벤트 중심 프로그래밍입니까? 당신이 그것에 대해 썼기 때문에 그것에 대한 질문을 받아들이고 싶을 것 같고, 그렇다면 관련성이 있지만이 스레드를 가로 채지 않도록 가능한 한 짧게 유지합시다.

 
Amir Yacoby #:

나는 내가 매우 흥미로운 스레드를 훔치는 것이 아니기를 바라며, 만약 내가 그렇게한다면, 그것은 이론적 인 관심에 대한 짧은 대답을 바라는 토론이 아닐 것입니다 - 당신은 시스템에 인스턴스화 된 모든 클래스 객체를 알고 (모든 객체 포인터를 추적) 각 객체가 해당 제어 정적 클래스에 필요한 이벤트를 구독 할 수있는 액세스 권한을 가지고 있고 그 정적 제어 싱글 톤 클래스가 모든 객체에 이벤트를 전달하는 일종의 정적 클래스가 있음을 의미합니까? 그렇다면 OOP 측면에서 올바른 것으로 보십니까 아니면 허용되는 이벤트 중심 프로그래밍입니까? 당신이 그것에 대해 썼기 때문에 그것에 대한 질문을 받아들이고 싶을 것 같고, 그렇다면 관련성이 있지만이 스레드를 가로 채지 않도록 가능한 한 짧게 유지합시다.


간단한 설명:

코어는 모든 메타트레이더 이벤트를 수신하고 모든 객체가 코어에 구독할 수 있습니다. 따라서 모든 객체가 "공용: 가상 void OnEACycle(CCycleParams * cpm)"이라는 함수를 갖도록 CObject 클래스도 재설계/수정해야 했습니다. 그런 다음 이러한 주기는 차트 이벤트, 초기화, 해제 등이 될 수 있습니다. 모든 객체에는 "public: 가상 void OnEATick()"이 있을 수도 있습니다. 이렇게 하면 어떤 주기의 끝을 구독할 수 있기 때문에 추가 기능을 얻을 수 있다는 장점이 있습니다. 어떤 주기가 끝날 때 파일을 닫거나 다른 작업을 완료하는 데 매우 유용합니다.

또한 모든 CObject 객체는 자식과 구독자를 가질 수 있습니다. 즉, 객체가 sth. 를 클릭했을 때와 같은 자체 이벤트를 트리거할 수 있습니다. 그런 다음 object.SubEvent(STH_CLICKED, params)를 수행하기만 하면 됩니다. 이렇게 하면 객체 자체는 누가 이 정보를 필요로 하는지 신경 쓰지 않고 구독자에게만 배포되며, 구독자는 OnSubEvent(int msg, CSubEventParams * sep)를 받고 원하는 대로 할 수 있습니다.

대체로 이렇게 하면 C#에서 우리가 아는 코딩 방식에서 더 자유로워지며, 여기서도 .Invoke()를 사용하여 이벤트를 실행하고 누가 이벤트를 받는지 신경 쓰지 않아도 됩니다.

실제로 구현하기가 그렇게 복잡하지는 않지만, 모든 시나리오에서 작동해야 하는 모든 단일 EA 또는 미래의 지표의 핵심/기반이기 때문에 세부 사항은 결국 어려운 문제입니다.

 
좀 더 이해하기 쉽게 설명하자면, 이것은 구현 후 모든 EA 또는 지표의 기본 클래스입니다.
class CEAMain : public CObject
   {
   public: CEAMain()
      {
      m_classname="CEAMain";
      SubscribeToCycle(EA_CYCLE_LOAD);
      SubscribeToCycle(EA_CYCLE_PARAMS);   
      SubscribeToCycle(EA_CYCLE_INIT);   
      SubscribeToCycle(EA_CYCLE_ACTIVATE);
      SubscribeToCycle(EA_CYCLE_TICK);
      SubscribeToCycle(EA_CYCLE_DEINIT);
      SubscribeToCycle(EA_CYCLE_UNLOAD);
      }
      //+------------------------------------------------------------------+
      //| Cycles handler                                                   |
      //+------------------------------------------------------------------+
      public: virtual void OnEACycle(CEACycleParams * cpm)
         {
         switch (cpm.Cycle)
            {
            case EA_CYCLE_LOAD:        cpm.CycleResult(OnEALoad(PTR(cpm.Init))); break;
            case EA_CYCLE_PARAMS:      cpm.CycleResult(OnEAParams()); break;
            case EA_CYCLE_INIT:        cpm.CycleResult(OnEAInit(PTR(cpm.Init))); break;
            case EA_CYCLE_ACTIVATE:    OnEAActivate(); break;
            case EA_CYCLE_DEINIT:      OnEADeinit(PTR(cpm.Deinit)); break;
            case EA_CYCLE_UNLOAD:      OnEAUnload(PTR(cpm.Deinit)); break;
            case EA_CYCLE_BOOKEVENT:   OnEABookEvent(PTR(cpm.BookEvent)); break;
            }
         }
      //+------------------------------------------------------------------+
      //| Cycles override                                                  |
      //+------------------------------------------------------------------+
      protected: virtual bool OnEALoad(CEAInitParams * ipm)                   { return true; }
      protected: virtual bool OnEAParams(void)                                { return true; }
      protected: virtual bool OnEAInit(CEAInitParams * ipm)                   { return true; } 
      protected: virtual void OnEAActivate(void)                              {}
      protected: virtual void OnEADeinit(CEADeinitParams * dpm)               {}
      protected: virtual void OnEAUnload(CEADeinitParams * dpm)               {}
      protected: virtual void OnEAChartEvent(CEAChartEventParams * cep)       {}
      protected: virtual void OnEABookEvent(CEABookEventParams * cpm)         {}
         
   };
그러면 최종 EA는 다음과 같습니다:

class CMain : public CEAMain
   {
      public: CMain()
         {
         m_classname="MainEA";
         }
      public: ~CMain()
         {
         }         

      //+------------------------------------------------------------------+
      //| Load                                                             |
      //+------------------------------------------------------------------+
      protected: virtual bool OnEALoad(CEAInitParams * ipm)
         {
         Print("Welcome :)");
         return true;
         }
      //+------------------------------------------------------------------+
      //| Expert initialization function                                   |
      //+------------------------------------------------------------------+
      protected: virtual bool OnEAInit(CEAInitParams * ipm)
         { 
         if (ipm.IsFirstInit) return true;
         //--- Account changed init
         if (ipm.IsAccountChanged)
            {
            }
         //--- Symbol change init
         else if (ipm.IsSymbolChanged)    
            {
            }
         return true;
        }
        
      //+------------------------------------------------------------------+
      //| Expert deinitialization function                                 |
      //+------------------------------------------------------------------+
      protected: virtual void OnEADeinit(CEADeinitParams * dpm)
        {
        }
      protected: virtual void OnEAUnload(CEADeinitParams * dpm)
         {
         DeInit();
         Print("Bye.");
         }  
      ...
      ...
};

// Create the main EA object on a global scope. 
CMain __MainEA;
 
물론 로드/언로드/활성화 등은 사용자 지정이지만, 이 이벤트 코어를 사용하면 없는 것보다 훨씬 더 유연하게 모든 것을 제어할 수 있습니다.
시간이 있었다면 기사를 작성하고 출처를 제공했을 것입니다. 비밀도 아니고 마술도 아닙니다.
 
Doerk Hilger 제어할 수 있습니다.
여러분이 만든 GUI를 보았습니다. 아주 마음에 들어요. 직접 작성하셨나요, 아니면 MQL 라이브러리를 사용하셨나요?
 
Реter Konow #:
만든 GUI를 보았습니다. 아주 마음에 드네요. 직접 작성하신 건가요, 아니면 MQL 라이브러리를 사용하신 건가요?

고맙습니다.
아니요, 라이브러리는 사용하지 않았습니다. 처음부터 제가 직접 디자인했습니다. 사실 원래의 CCanvas만 수정했을 뿐 다른 것은 아무것도 사용하지 않았습니다.

 
Doerk Hilger #:

고맙습니다.
아니요, 라이브러리는 없습니다. 제가 처음부터 직접 개발했습니다. 사실 CCanvas만 원본에서 변형한 것일 뿐 다른 것은 없습니다.

이런 것을 만드는 것은 쉽지 않습니다. )

제가 알기로는 표준 C캔버스 클래스에는 색상 그라데이션을 그리는 기능이 없는데, GUI에서 그라데이션 문제를 어떻게 해결하셨나요?