MQL ile yazılmış kullanıcı arayüzleri galerisi - sayfa 77

 

VE geliştirmenin mevcut aşaması:

  • Çekirdekten yaklaşık 400 küsur pencere özelliği, öğe ve parametre editör pencerelerine entegre edilmiş ve sekmelenmiştir. Bunların hepsi VE'de oluşturulan GUI öğelerinin kontrol edilebilir ayarları haline gelecektir.
  • Kullanıcıların çalışmalarında gerekli olan çeşitli kontrol elemanlarının 52 şablonu entegre edilmiştir.
  • Tasarım ve stil üzerinde çok fazla çalışma yapıldı. VE GUI'nin pratikliğini ve kullanılabilirliğini sağlamak için çeşitli çözümleri tartmaya devam ediyorum.
  • Şablonların ve özelliklerin entegrasyonunun yanı sıra bunların sıralanması ve dağıtımı tamamlandığında, işlevsellik üzerinde çalışmaya başlanacaktır.
  • Şu anda GUI, oldukça sıkıcı olan KIB biçimlendirme dilinde yazılmıştır. Görsel düzenlemeye geçiş henüz gerçekleşmedi. Ancak, bu yakın gelecekte gerçekleşecektir.
  • Grafiksel kusurlar var. Bunlar geçicidir.
  • Yer kazanmak için Görev Çubuğunun yüksekliği azaltıldı.
  • Düzenleyici penceresinin çerçevesi daha fazla alan için görüş alanının dışına taşınmıştır.


 
Kulağa harika geliyor Peter, bence VE'yi kendi kendine inşa etmek için kullandığınızda, kullanıcı arayüzü tasarımınızın nasıl çalıştığı konusunda size kesinlikle değerli bilgiler verecektir.
Bir sonraki geliştirme güncellemesini dört gözle bekliyorum.
 
Douglas Prager #:
Kulağa harika geliyor, Peter. Bence VE'yi kendiniz inşa etmek için kullandığınızda, kullanıcı arayüzü tasarımınızın nasıl çalıştığına dair size değerli bilgiler verecektir.
Bir sonraki geliştirme güncellemesini dört gözle bekliyorum.
Teşekkür ederim, Douglas. Haklısın, bu kesinlikle doğru. Üstesinden gelinmesi gereken asgari bir teknik "treshhold" var.

Temel gelişiminizi de ilgiyle takip edeceğim.
 
Doerk Hilger #:
Kullanıcı arayüzü hala %100 saf MQL'dir.
Tümü vektör tabanlıdır, tamamen ölçeklenebilir ve herhangi bir ekrana ayarlanabilir.
Tüm görsel ekranlar, abonelik ayarlarına ve olay önceliklerine bağlı olarak tüm MQL olaylarını işleyen ve nesnelere dağıtan bir çekirdek sınıf içinde asikronik olarak çalışır.

Umarım çok ilginç bir konuyu çalmıyorumdur ve eğer yaparsam beni affet Peter, bu bir tartışma olmayacak, sadece teorik ilgi için kısa bir cevap umuyorum - sistemde kurulan tüm sınıf nesnelerini bilen (tüm nesne işaretçilerini takip eden) bir tür statik sınıfınız olduğunu ve her nesnenin bu kontrol statik sınıfındaki gerekli olaylara abone olma erişimine sahip olduğunu ve bu statik kontrol singleton sınıfının sadece olayları tüm nesnelere ilettiğini mi kastediyorsunuz? Eğer öyleyse, bunu OOP açısından doğru olarak mı görüyorsunuz yoksa kabul edilebilir olay güdümlü programlama mı? Bu konuda yazdığınız için, sanırım bu konudaki soruları kabul etmek istersiniz ve eğer öyleyse, lütfen ilgili olmasına rağmen bu konuyu kaçırmamak için mümkün olduğunca kısa tutalım.

 
Amir Yacoby #:

Umarım çok ilginç bir konuyu çalmıyorumdur ve eğer yaparsam beni affet Peter, bu bir tartışma olmayacak, sadece teorik ilgi için kısa bir cevap umuyorum - sistemde kurulan tüm sınıf nesnelerini bilen (tüm nesne işaretçilerini takip eden) bir tür statik sınıfınız olduğunu ve her nesnenin bu kontrol statik sınıfındaki gerekli olaylara abone olma erişimine sahip olduğunu ve bu statik kontrol singleton sınıfının sadece olayları tüm nesnelere ilettiğini mi kastediyorsunuz? Eğer öyleyse, bunu OOP açısından doğru olarak görüyor musunuz veya belki de kabul edilebilir olay güdümlü programlama mı? Bu konuda yazdığınız için, sanırım bu konudaki soruları kabul etmek istersiniz ve eğer öyleyse, lütfen ilgili olmasına rağmen bu konuyu kaçırmamak için mümkün olduğunca kısa tutalım.

Evet, tam olarak bu.
Kısa açıklama:

Çekirdek tüm MetaTrader olaylarını alır ve herhangi bir nesne çekirdeğe abone olabilir. Bu nedenle, CObject sınıfının da yeniden tasarlanması / değiştirilmesi gerekiyordu, böylece herhangi bir nesnenin "public: virtual void OnEACycle(CCycleParams * cpm)" adlı bir işlevi vardı. Böyle bir döngü daha sonra bir grafik olayı, init, deinit vb. olabilir. Her nesne ayrıca bir "public: virtual void OnEATick() "e sahip olabilir. Güzel bir yan etki, bu şekilde ekstra bir özellik elde etmenizdir, çünkü hangisi olursa olsun herhangi bir döngünün sonuna da abone olabilirsiniz. Herhangi bir döngünün sonunda bir dosyayı kapatmak veya başka bir şeyi bitirmek için oldukça kullanışlıdır.

Ayrıca, her CObject nesnesinin çocukları ve ayrıca aboneleri olabilir. Yani, bir nesne tıklandığında ya da benzeri bir durumda kendi olaylarını tetikleyebilir. Sonra basitçe bir object.SubEvent(STH_CLICKED, params) gerçekleştirirsiniz. Bu şekilde, nesnenin kendisi bu bilgiye kimin ihtiyaç duyduğuyla ilgilenmez, sadece abonelere dağıtılır, bir OnSubEvent(int msg, CSubEventParams * sep) alırlar ve bununla ne isterlerse yapabilirler.

Sonuç olarak, bu şekilde C#'tan bildiğimiz kodlama yöntemine daha yakındır, burada da sadece .Invoke() kullandığınız ve bunları kimin aldığını umursamadığınız C#'tan bildiğimiz kodlama yöntemine daha yakındır.

Aslında uygulaması o kadar da karmaşık değildir, ancak elbette ayrıntılar sonunda zorlayıcıdır, çünkü bu, her senaryoda çalışması gereken gelecekteki her bir EA veya gösterge için bir çekirdek / temeldir.

 
Biraz daha iyi anlamak için, bu, uygulamadan sonra herhangi bir EA veya gösterge için temel sınıftır.

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)         {}
         
   };
Ve nihai bir EA şu şekilde görünür:

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;
 
Elbette, Load/Unload/Activate vb. özeldir, ancak bu olay çekirdeğine sahip olduğunuz için, sahip olmadığınızdan çok daha fazla esnekliğe ve kesinlikle her şey üzerinde çok daha fazla kontrole sahipsiniz.
Zamanım olsaydı, bir makale yazardım ve kaynakları sağlardım. Bu bir sır değil, hiç sihir yok.
 
Doerk Hilger kontrole sahipsiniz.
Oluşturduğunuz GUI'yi izledim. Çok beğendim. Söyleyin bana, kendiniz mi yazdınız yoksa bazı MQL kütüphanelerini mi kullandınız?
 
Реter Konow #:
Oluşturduğunuz GUI'yi izledim. Çok beğendim. Söyleyin bana, kendiniz mi yazdınız yoksa bazı MQL kütüphanelerini mi kullandınız?

Teşekkür ederim.
Hayır, kütüphane yok. Sıfırdan kendim tasarladım. Aslında orijinallerinden sadece CCanvas uyarlandı, başka bir şey yok.

 
Doerk Hilger #:

Teşekkür ederim.
Hayır, kütüphane yok. Sıfırdan kendim geliştirdim. Aslında, sadece CCanvas orijinallerinden uyarlanmıştır, başka bir şey değil.

Böyle bir şey yapmak kolay değil. )

Bildiğim kadarıyla, standart Ccanvas sınıfında renk gradyanı çizmek için bir işlevsellik yok, GUI'nizde gradyanla sorunu nasıl çözdünüz?