Diskussion zum Artikel "Verbessern Sie Ihre Handelscharts mit interaktiven GUI's in MQL5 (Teil III): Ein einfaches, bewegliches Handels-GUI" - Seite 2

 
Maxim Kuznetsov #:

es gibt eine Dunkelheit von aufwendigen Methoden mit schönen Pfeilen "wie UI zu implementieren, so dass es nicht unerträglich schmerzhaft sein wird" :-) MVC und ähnliches. Da kann das Frontend (win,gtk,qt,web) schon mal mit einer leichten Handbewegung geändert werden.

Nichts davon ist in MQL implementiert worden. Alles ist festgenagelt, schlimmer als TurboVision - auch wenn es Klassen von Adam hat, aber es hat Modelle

Einzelpersonen schreiben seit Jahren(!!!) über "leicht und einfach" und "einfache Schnittstelle", aber es ist genau dasselbe wie in diesem Artikel. Eine Menge Code, der nichts einfacher macht. Der einzige Effekt ist ein Bonus für das Konto des Autors.

Oh, die bloße Erwähnung von MVC lässt mich erschaudern.

Es ist seit der Zeit, als ich die Website meiner Frau, ein Online-Shop auf der OcStore-Engine gemacht geblieben.

Mit der Zeit kam zumindest ein gewisses Verständnis dafür, wie es funktioniert, war ich halb grau))))


Wir sollten nicht zu streng urteilen, diese Artikelserie richtet sich an Anfänger.

Die Artikel sind klar und übersichtlich geschrieben, und klar zu schreiben ist keine leichte Aufgabe.

Der Autor, meistert diese Aufgabe perfekt.

 
Aleksandr Slavskii #:

Autsch, allein die Erwähnung von MVC lässt mich erschaudern.

Es ist dort gewesen, seit ich die Website meiner Frau auf der OcStore-Engine gemacht.

Zu der Zeit, als ich verstand, wie es funktioniert, war ich halb grau))))


Wir sollten nicht zu hart urteilen, diese Artikelserie richtet sich an Anfänger.

Die Artikel sind klar und verständlich geschrieben, und es ist gar nicht so einfach, klar zu schreiben.

Der Autor, meistert diese Aufgabe perfekt.

Ich habe eine Erinnerung an das Zählen der Breite/Höhe und der relativen und absoluten Koordinaten einer beschissenen Schaltfläche ist deprimierend :-)

2024 - aber trotzdem muss der Bibliotheksbenutzer Pixel zählen.

den gegebenen Dialog in Form eines Lautstärke-Eingabefeldes und zweier Kauf/Verkauf-Schaltflächen.

wie löst der obige Dialog die Probleme mit der Volumentoleranz und der Handelbarkeit? ja, Lots können nicht kleiner als Minimum sein, um Schritte erhöht werden und nicht größer als Maximum. Kaufen/Verkaufen ist nicht immer möglich.
Irgendwelche Hinweise auf Lösungen? Nein.

WIE ? von Hand zu Hand...innerhalb des EAs alle Optionen einer bestimmten GUI manuell verwalten. Das ist nicht besser als die direkte Verwendung von Terminalfunktionen.

zwischen ObjectSetXXX(chart,objName,propertyName,propertyValue) und obj.SetInteger(value) - der Unterschied wird durch Defines abgedeckt, hier ist kein OOP nötig.

---

es geht nicht um den Artikel, es geht um "Autoren" im Allgemeinen. Sie sollten besser lesen

 
Maxim Kuznetsov # :

Ich habe eine Erinnerung an die Berechnung der Breite/Höhe und der relativen und absoluten Koordinaten eines Buttons, die deprimierend ist :-)

2024 - aber trotzdem muss der Benutzer der Bibliothek die Pixel zählen

der gegebene Dialog, in der Form: Volumen-Eingabefeld und zwei Kauf/Verkauf-Schaltflächen

Wie löst der obige Dialog die Probleme mit der Zulässigkeit von Volumen und der Möglichkeit des Handels? Ja, die Mengen können nicht kleiner als das Minimum sein, sie werden schrittweise erhöht und nicht größer als das Maximum. Kaufen/Verkaufen ist nicht immer möglich. Gibt es Hinweise auf Lösungen? Es gibt keine

WIE? im Nahkampf... innerhalb des Advisors alle Optionen einer bestimmten GUI manuell steuern. Das ist nicht besser als die direkte Verwendung der Terminalfunktionen.

zwischen ObjectSetXXX(chart,objName,propertyName,propertyValue) und obj.SetInteger(value) - der Unterschied wird durch Definitionen abgedeckt, hier ist kein OOP nötig

---

Dies ist nicht mehr im Sinne des Artikels, es geht allgemein um "Schreiber". Es wäre besser, wenn sie lesen würden

Nur eines möchte ich anmerken, diese Serie wurde nicht für diese Buy/Sell GUI geschrieben, sondern für jede GUI und diese Buy/Sell GUI dient als einfaches Beispiel.

Vielen Dank, dass Sie sich solche Gedanken über die Serie gemacht haben, ich würde mich über Anregungen freuen.

Mit freundlichen Grüßen

 
Maxim Kuznetsov #:

Ich habe eine Erinnerung daran, wie ich die Breite/Höhe und die relativen und absoluten Koordinaten einer beschissenen Schaltfläche gezählt habe, was mich verzweifeln lässt :-)

2024 - aber trotzdem muss ein Bibliotheksbenutzer Pixel zählen

der vorgegebene Dialog in Form von: Lautstärke-Eingabefeld und zwei Kauf/Verkauf-Schaltflächen

Wie löst der obige Dialog die Probleme mit der Volumentoleranz und der Handelbarkeit? ja, Lots können nicht kleiner als das Minimum sein, um Schritte erhöht werden und nicht größer als das Maximum. Kaufen/Verkaufen ist nicht immer möglich.
Irgendwelche Lösungsvorschläge? Nein.

WIE ? von Hand zu Hand...innerhalb des EAs alle Optionen einer bestimmten GUI manuell verwalten. Es ist nicht besser als die direkte Verwendung von Terminalfunktionen.

zwischen ObjectSetXXX(chart,objName,propertyName,propertyValue) und obj.SetInteger(value) - der Unterschied wird durch Defines abgedeckt, hier ist kein OOP nötig.

---

es geht nicht um den Artikel, es geht um "Autoren" im Allgemeinen. Sie sollten besser lesen

Mann, das ist erst mein drittes Panel, ich will mich nicht an die ersten beiden erinnern, wenn irgendein Programmierer sie sieht, werde ich mich schämen.

Ich möchte es jetzt machen, damit ich beim nächsten Mal nicht mehr so viel daran herumpfuschen muss.

Jetzt in der Plugin-Datei links nur eine Klasse mit Code für das Ziehen aller Elemente des Panels und eine Reihe von bekommt.

class CreateObject
  {
private:
   string            _name; // Name der Rechteckbeschriftung
   int               previousMouseState, mlbDownX, mlbDownY, mlbDownXDistance, mlbDownYDistance; // Variablen für die Verfolgung des Mauszustands
   bool              movingState; // Zustand, ob sich das Objekt bewegt
   string            addedNames[]; // Array der hinzugefügten Namen
   long              addedXDisDiffrence[], addedYDisDiffrence[]; // Arrays zum Speichern der addierten Abstandsunterschiede
   void              Destroy() {for(int i = 0; i < (int)addedNames.Size(); i++)ObjectDelete(0, addedNames[i]); ObjectDelete(0, _name);} // Zerstörungsmethode für Rechteckbeschriftung
public:
                     CreateObject(void); // Konstrukteur
                    ~CreateObject(void); // Destruktor
   void              SetName(string name) {_name = name;}
   string            GetText(string name) {return ObjectGetString(0, name, OBJPROP_TEXT);} // Methode zum Abrufen des Textinhalts
   long              GetType(string name) {return ObjectGetInteger(0, name, OBJPROP_TYPE);}
   double            GetPrice(string name) {return ObjectGetDouble(0, name, OBJPROP_PRICE);}
   void              OnEvent(int id, long lparam, double dparam, string sparam); // Ereignisbehandlungsmethode
   void              Add(string name); // Methode zum Hinzufügen eines Namens zum Objekt
  };
//+------------------------------------------------------------------+
CreateObject::CreateObject(void) {}
//+------------------------------------------------------------------+
CreateObject::~CreateObject(void) {Destroy();}
//+------------------------------------------------------------------+
//| Ereignisbehandlung für Mausbewegungen |
//+------------------------------------------------------------------+
void CreateObject::OnEvent(int id, long lparam, double dparam, string sparam)
  {
// Verarbeitung von Mausbewegungsereignissen zum Ziehen der Rechteckbeschriftung
   if(id == CHARTEVENT_MOUSE_MOVE && lparam > 20 && dparam > 20 &&
      lparam < ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) - 20 && dparam < ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS) - 20)
     {
      int X = (int)lparam;
      int Y = (int)dparam;
      int MouseState = (int)sparam;

      string name = _name;
      int XDistance = (int)ObjectGetInteger(0, name, OBJPROP_XDISTANCE);
      int YDistance = (int)ObjectGetInteger(0, name, OBJPROP_YDISTANCE);
      int XSize = (int)ObjectGetInteger(0, name, OBJPROP_XSIZE);
      int YSize = (int)ObjectGetInteger(0, name, OBJPROP_YSIZE);

      if(previousMouseState == 0 && MouseState == 1)
        {
         mlbDownX = X;
         mlbDownY = Y;
         mlbDownXDistance = XDistance;
         mlbDownYDistance = YDistance;

         if(X >= XDistance && X <= XDistance + XSize && Y >= YDistance && Y <= YDistance + YSize)
           {
            movingState = true;
           }
        }

      if(movingState)
        {
         ChartSetInteger(0, CHART_MOUSE_SCROLL, false);
         ObjectSetInteger(0, name, OBJPROP_XDISTANCE, mlbDownXDistance + X - mlbDownX);
         ObjectSetInteger(0, name, OBJPROP_YDISTANCE, mlbDownYDistance + Y - mlbDownY);
         for(int i = 0; i < ArraySize(addedNames); i++)
           {
            ObjectSetInteger(0, addedNames[i], OBJPROP_XDISTANCE, mlbDownXDistance + X - mlbDownX - addedXDisDiffrence[i]);
            ObjectSetInteger(0, addedNames[i], OBJPROP_YDISTANCE, mlbDownYDistance + Y - mlbDownY - addedYDisDiffrence[i]);
           }
         ChartRedraw(0);
        }

      if(MouseState == 0)
        {
         movingState = false;
         ChartSetInteger(0, CHART_MOUSE_SCROLL, true);
        }

      previousMouseState = MouseState;
     }
  }
//+------------------------------------------------------------------+
//| Methode zum Hinzufügen eines Objekts mit Namen zur Rechteckbeschriftung |
//+------------------------------------------------------------------+
void CreateObject::Add(string name)
  {
// Fügen Sie der Rechteckbeschriftung ein neues Objekt mit Namen hinzu und verfolgen Sie die Abstände
   ArrayResize(addedNames, ArraySize(addedNames) + 1);
   ArrayResize(addedXDisDiffrence, ArraySize(addedXDisDiffrence) + 1);
   ArrayResize(addedYDisDiffrence, ArraySize(addedYDisDiffrence) + 1);

   addedNames[ArraySize(addedNames) - 1] = name;
   addedXDisDiffrence[ArraySize(addedXDisDiffrence) - 1] = ObjectGetInteger(0, _name, OBJPROP_XDISTANCE) - ObjectGetInteger(0, name, OBJPROP_XDISTANCE);
   addedYDisDiffrence[ArraySize(addedYDisDiffrence) - 1] = ObjectGetInteger(0, _name, OBJPROP_YDISTANCE) - ObjectGetInteger(0, name, OBJPROP_YDISTANCE);
  }
//+------------------------------------------------------------------+

Und unten habe ich nur Funktionen zum Zeichnen von Objekten, die ich aus der Hilfe kopiert habe, es scheint so praktisch, alles auf einem Haufen zu haben.

Infolgedessen war der Code im Expert Advisor lang, jetzt ist er breit, im Allgemeinen habe ich von einer Sache zur anderen gewechselt.

Eine weitere Plug-in-Datei mit häufig verwendeten Handelsfunktionen, wie z. B. alle Positionen berechnen, Preis normalisieren, Positionen schließen und so weiter.

Aber es ist immer noch ein bisschen umständlich und nicht universell.

Im nächsten Panel müssen wir jedes Feld berechnen und die Verarbeitung für diese Felder schreiben (Schaltflächen/Eingabefeld).

Und mir fällt kein Schema ein, wie man das alles universeller machen könnte.

Können Sie mir ein paar gute Tipps geben, wie ich den Code gestalten kann?

 
Aleksandr Slavskii #:

Aber es ist immer noch etwas umständlich und nicht vielseitig.

Im nächsten Panel müssen wir jedes Feld berechnen und eine Verarbeitung für diese Felder schreiben (Schaltflächen/Eingabefeld).

Und mir fällt keine Möglichkeit ein, es universeller zu machen.

Können Sie mir einige gute Tipps geben, wie ich den Code gestalten kann?

Die praktischste und universellste Variante ist es, Formulare visuell zu gestalten, ohne sich überhaupt um den Layout-Code zu kümmern - das ist es, was Klassen tun sollten. Eine der möglichen Lösungen war in dem Artikel.

Язык MQL как средство разметки графического интерфейса MQL-программ (Часть 3). Дизайнер форм
Язык MQL как средство разметки графического интерфейса MQL-программ (Часть 3). Дизайнер форм
  • www.mql5.com
В этой статье мы завершаем описание концепции построения оконного интерфейса MQL-программ с помощью конструкций языка MQL. Специальный графический редактор позволит интерактивно настраивать раскладку, состоящую из основных классов элементов GUI, и затем экспортировать её в MQL-описание для использования в вашем MQL-проекте. Представлено внутреннее устройство редактора и руководство пользователя. Исходные коды прилагаются.
 
Stanislav Korotky #:

Die praktischste und universellste Möglichkeit ist es, Formulare visuell zu gestalten, ohne sich um den Layout-Code zu kümmern - das ist genau das, was Klassen tun sollten. Eine der möglichen Lösungen war in dem Artikel.

Ich habe mich erinnert :-)

für diejenigen, die nicht für den Markt sind, mehr oder weniger komplexe, aber schöne, und es ist zu faul, DLL zu schreiben, gibt es GtkServer https://sourceforge.net/projects/gtk-server/ und Glade form designer dazu.

Methodik: GtkServer wird als tcp-Listener gestartet, Berater mit SocketOpen/SocketSend sendet Text "load form" (oder selbst durch Schritte bildet gtk Widgets) und liest auch das Ergebnis....

GTK-server
  • 2018.11.27
  • sourceforge.net
From AI to Wasm, eBPF, and environmental sustainability, KubeCon + CloudNative Con Europe is the place to experience everything cloud native has to offer and also take a deep dive into new and promising...
 
Stanislav Korotky #:

Die praktischste und universellste Möglichkeit ist es, Formulare visuell zu gestalten, ohne sich um den Layout-Code zu kümmern - das ist genau das, was Klassen tun sollten. Eine der möglichen Lösungen war in dem Artikel.

Stanislav, unter dem Artikel für Anfänger gibt es einen Link zu dem Artikel für Fortgeschrittene :)

Ich habe ihn gelesen, nicht gelesen, sondern nur gelesen, denn mein Niveau in der Programmierung ist viel niedriger als ich brauche, um zu verstehen, was dort geschrieben steht.

Ich versuche, das, was ich nicht verstehe, so wenig wie möglich zu benutzen. Eine aktuelle Situation hat mich darin noch stärker bestärkt.

Sie lesen wahrscheinlich das Thema "Fehler, Bugs, Fragen", also hatte ich die Aufgabe, Pfeile von geschlossenen Positionen auf einem Renko-Graphen darzustellen, Eingang-Ausgang zwischen ihnen - eine Linie.

Ich beschloss, es nicht selbst zu schreiben, sondern einen fertigen Code von Saiber zu nehmen, was einen halben Tag Zeitverschwendung bedeutete. Saiber hat seinen Code am Ende korrigiert, aber ich habe Zeit verloren.

Und wenn ich den Code aus Ihrem Artikel nehmen wollte und etwas ändern müsste, nun ja, Sie verstehen, es würde nichts Gutes dabei herauskommen.

Ich habe eine einfachere Aufgabe, als Sie sie sich beim Schreiben Ihres Artikels gestellt haben. Ich muss nur dafür sorgen, dass ich das nächste Panel aus vorgefertigten Codestücken bauen kann, so wie Kinder Häuser aus Lego bauen.

Meiner Meinung nach brauche ich dafür überhaupt kein OOP. Ich kenne es nicht, also mag ich es nicht.

Das MVC-Prinzip ist für meine Zwecke durchaus geeignet, wenn ich es richtig verstanden habe)))))

Generell habe ich schon ein Bild davon, wie es sein sollte.


Kannst du mir übrigens sagen, wie ich es hinbekomme, dass ich, wenn ich vom Programm aus auf die Funktionen der Erbenklasse zugreife, die Funktionen der Basisklasse nicht sehe? Wenn das möglich ist.

 
Maxim Kuznetsov #:

es fiel mir ein :-)

für diejenigen, die nicht für den Markt sind, mehr oder weniger komplex aber schön wollen, und zu faul sind, eine DLL zu schreiben, gibt es GtkServer https://sourceforge.net/projects/gtk-server/ und Glade form designer dazu.

Methodik: GtkServer wird als tcp-Listener gestartet, Berater mit SocketOpen/SocketSend sendet Text "load form" (oder selbst durch Schritte bildet gtk Widgets) und liest auch das Ergebnis....

Sie auch :)

Ichempfinde Wörter wie tcp listener, SocketOpen/SocketSend generellals Schimpfwort , ichkenne nicht einmal ihre Bedeutung ohne Google, und Sie schlagen vor, sie zu benutzen.

Meine Herren, haben Sie ein Gewissen, hören Sie auf, Leute mit Ihrer Terminologie zu erschrecken)))))

 
Aleksandr Slavskii #:

Stanislav, gut yo-ma-yo, unter dem Artikel für Anfänger wirfst du einen Link zu dem Artikel für Fortgeschrittene :)

Ich habe es gelesen, nicht lesen, aber nur lesen, weil mein Niveau in der Programmierung ist viel niedriger als ich brauche, um zu verstehen, was dort geschrieben wird.

Ich versuche, das, was ich nicht verstehe, so wenig wie möglich zu benutzen. Eine kürzlich eingetretene Situation hat mich darin noch stärker verwurzelt.

Leider ist die Situation bei Software so, dass es unmöglich ist, alles selbst zu verstehen. Nach dieser Logik sollte das Betriebssystem angepasst werden (was einige Linux-Apologeten auch tun).

Deshalb besteht der moderne Ansatz darin, fertige Bausteine zu nehmen (die mehr oder weniger das tun, was man braucht) und sie anzudocken (ohne tief in die Implementierung einzusteigen).

Ich habe lediglich auf die Frage geantwortet, wie man universeller vorgehen kann. Man kann nicht bestreiten, dass mein Artikel kompliziert ist, aber der Punkt ist, dass man die notwendige GUI als Vorlage ohne Programmierung beschreiben kann, indem man einfach Gehäuse einsteckt, um Controller, das Ziehen von Fenstern, die Größenänderung und so weiter zu erhalten.

 
Ausgezeichnet, sehr gut, ich kann basteln, was ich nicht programmieren kann, aber es gibt einige Funktionen, mit denen ich nicht umgehen kann, ist es einfach, mir zu helfen, zu ändern? Fügen Sie ein Eingabefeld mit einem +- Zeichen hinzu. Ich danke Ihnen!