Styles in eigene Gui implementieren



  • Student83 schrieb:

    Es sollen ja auch mehrere Styles verwendet werden können, bzw. die einzelnen Eigenschaften des Button auch individuell angepasst werden können ohne dafür einen neuen Style entwerfen zu müssen.

    Das beantwortet die Frage nicht. Denn das kannst du auch alles ueber die Style Klasse machen. Richtig flexibel ist es natuerlich wenn es einen computed-style gibt wie Fellhuhn beschreibt.

    Aber der Punkt ist, dass du eine Style Klasse hast die sich um Styles kuemmert. Und eine Control Klasse die sich um das Control kuemmert. Dann hast du naemlich auf einen Schlag alle deine Probleme aus deinem ersten Post geloest.

    Ein Button kann ja durchaus auch ein Style-Objekt als Member haben.



  • Wenn ich das also richtig verstanden habe soll ich jeder GUI-Element-Klasse ein Style-Member hinzufügen. Allerdings bräuchte ich dann ja so eine Art Super-Style der die Style-Eigenschaften aller Controls enthält. Damit würde aber, da die unterschiedlichen Styles im Umfang sehr unterschiedlich sind, bei den primitiveren GUI-Element-Klassen viele unnütze Variablen zur Verfügung gestellt und damit viel Speicher verschwendet. Oder habt ihr das anders gemeint?



  • class Style
    {
    public:
      Color ButtonColor();
      Color TextColor();
      Font FontStyle();
      // ....
    };
    
    class Button
    {
    public:
      /*static ?*/void ChangeStyle(const Style& s)
      {
        color_ = s.ButtonColor();
      }
    private:
      /*static ?*/ Color color_;
    };
    


  • Ok, allerdings muss ich die Style-Variablen als private setzen (wegen Gültigkeitsprüfung), damit auf diese nur über Set/Get-Funktionen zugegriffen werden kann.
    Außerdem muss ich die ganzen Variablen so in der Button-Klasse und der Style-Klasse angeben. Wäre es nicht eleganter die Buttonklasse von der Style Klasse abzuleiten:

    class Button : public Style {...};
    

    So hätte ich den Style komplett von der Buttonklasse getrennt. Allerdings kommt es dann ja zum Diamant-Ploblem.

    Nehmen wir mal folgendes Beispiel:

    class Style {...};
    class ControlStyle : public Style {...};
    class ButtonStyle : public ControlStyle {...};
    

    und

    class Control : public ControlStyle {...};
    class Button : public Control, ButtonStyle {...};
    

    Die Klasse Button bekommt nun den ControlStyle und den ButtonStyle vererbt, was so nicht sein soll.



  • Ich verstehe dein Problem nicht, aber Button von Style erben zu lassen ist absoluter Blödsinn. Button ist ein Fesnter oder ein Widget oder was auch immer, aber Button ist kein Style. Es hat einen Style oder benutzt einen Style um sich selber zu zeichnen.



  • Wenn ich den Style als public Member einer Steuerlement-Klasse deklariere kann ich z.B. so:

    m_pControl->Style->SetWidth(50);
    

    darauf zugreifen.
    Ich muss allerdings den Style als private deklarieren da ja sonst der z.B. Control-Style an alle abgeleitete Klassen vererbt werden würde. Jetzt kann allerdings der Style auch nicht mehr von außen verändert werden. Folgendes geht also nicht mehr:

    Button *m_pButton;
    m_pButton = new Button();
    m_pButton->Style->SetWidth(60);
    m_pButton->Style->SetHeight(20);
    

    Also brauche ich für jede Steuerelement-Klasse nun auch noch Set/Get-Funktionen um jede Variable des Styles verändern zu können. Und genau diesen zusätzlichen Wülst an Funktionen möchte ich mir sparen. Darum möchte ich wissen ob es nicht ein besseres Konzept gibt.



  • Student83 schrieb:

    Also brauche ich für jede Steuerelement-Klasse nun auch noch Set/Get-Funktionen um jede Variable des Styles verändern zu können. Und genau diesen zusätzlichen Wülst an Funktionen möchte ich mir sparen. Darum möchte ich wissen ob es nicht ein besseres Konzept gibt.

    Warum nicht ein Get/Set-Paar für den Style?

    class Button
    {
        public:
            Style GetStyle() const;
            void  SetStyle(const Style& style);
    };
    


  • @Nexus
    Das wäre natürlich schonmal viel praktischer. Wie sieht das denn von der Ausführungdsgeschwindigkeit aus wenn ich z.B. nur die Breite eines Button zurückgegeben haben möchte und

    button->GetStyle()->GetWidth();
    

    aufrufe. Wird durch diesen Aufruf wirklich nur die Breite zurückgegeben. Oder im erten Schritt sozusagen zunächst der ganze Style und im zweiten Schritt dann nur noch die Breite?

    Und kann mir evtl. noch jemand erklären wie die Implementation von den Styles bei Qt gelöst ist?

    Dort scheint der Style über einen Zeiger realisiert zu sein:

    public:
        QStyle *style() const;
        void setStyle(QStyle *);
    

    Achso, und was bewirkt eigentlich "() const" hinter einer Variablen?



  • Student83 schrieb:

    Achso, und was bewirkt eigentlich "() const" hinter einer Variablen?

    autsch



  • Autsch, wenn deine fast 1000 anderen Beiträge auch so aussehen 🙄. Erklären kannst du es offensichtlich nicht. Ich programmiere schon lange und das habe ich jetzt zum ersten mal bei Qt gesehen.
    Hab jetzt selbst die Erklärung gefunden:
    http://en.wikipedia.org/wiki/Const-correctness



  • sry, aber diese frage tat wirklich weh.

    Achso, und was bewirkt eigentlich "() const" hinter einer Variablen?

    '()' bewirkt, das es sich um eine memberfunktion handelt und nicht um eine variable. const hast du ja scheinbar inzwischen schon rausgefunden.

    das autsch bezog sich nicht auf das const



  • Student83 schrieb:

    Ich programmiere schon lange und das habe ich jetzt zum ersten mal bei Qt gesehen.

    Nicht böse gemeint, aber programmierst du auch schon lange C++? Sowohl const als auch Memberfunktionen sind etwas ziemlich Grundlegendes und vor allem auch etwas, das einem andauernd im C++-Alltag begegnet.

    Wegen Performance: Du kannst ja Pass by Reference benutzen, wenn es angebracht ist. Ein bisschen kopieren musst du halt je nachdem immer noch. Aber wenn du den Benutzer nicht direkt das Style -Objekt innerhalb Button ändern lässt, muss er halt jeweils einen neuen Style erstellen und den setzen.



  • @ Meep Meep
    Jetzt sehe ich es auch, ich habe da wohl etwas überzogen reagiert. Das const hat mich so irritiert dass ich nicht erkannt habe, dass das ne Funktion und keine Varible ist. Da kann man wirklich nur autsch schreiben ;). Hätten die die Funktion "getStyle" genannt wäre das auch sofort klar gewesen.


Anmelden zum Antworten