Funktionscontainer?



  • hallo

    ich verweise mal auf diesen Thread: http://www.c-plusplus.net/forum/viewtopic-var-p-is-1932903.html#1932903

    Da geht es um das Problem, dass ein GTK/Gtkmm Objekt nicht mehr als ein Event vom selben EventTyp haben kann. Was in meinem Fall ziemlich einschränkt.

    meine Buttonklasse schaut grob so aus:

    class Button
    {
    public:
        Button(...) // X,Y,Width,Height, usw.
    private:
        bool releaseEvent(...); // Jeder Button soll einen bestimmten Effekt machen, wenn er angeklickt wird.
        // std::vector<Funktionstyp> m_releaseEventContainer; // Wird unten erklärt.
    };
    
    class Menu
    {
    public:
        Menu(...); // X,Y...
        /* hier wird ein button übergeben und ein weiterer 'releaseEvent' sollte sich an dem Button ankoppeln.
           geht nur leider nicht, da wie oben schon erwähnt ein GTK/Gtkmm Objekt nur ein Event vom selben EventTyp haben kann.
        */
        void addButtonItem(Button& button); 
    };
    

    Meine Idee wäre jetzt einen 'Funktionscontainer' in die Klasse 'Button' zu implementieren. Nur habe ich gar keine Ahnung was für ein Typ so eine Funktion hat? Es sollte auch möglichst nicht eingeschränkt sein, da manche Funktionen zwei Parameter haben und manche drei,...

    Kann mir wer helfen?

    Danke im voraus.



  • Ehrlich gesagt habe ich keinen Plan, was du genau vor hast.

    Wenn du einen Funktionszeiger hast, dann musst du dich auf die genauen
    Parameter festlegen. Du kannst ja schlecht einer Funktion mit 3 Parametern
    nur 2 übergeben.

    Falls du nicht weißt, wie du Funktionszeiger in einen Container kriegst,
    hier mal ein Beispiel, sowohl mit normalen Funktionszeigern als auch
    mit Member-Funktionszeigern:

    #include <iostream>
    #include <vector>
    class A{
    
    public:
    
            int j;
    
            int multiply(int i){
                    return i*j;
            }
            int add(int i){
                    return i+j;
            }
    };
    
    int multiply(int i, int j){
            return i*j;
    }
    
    int add(int i, int j){
            return i+j;
    }
    
    typedef int (*foo)(int, int);
    typedef int (A::*bar)(int);
    
    int main() {
            std::vector<foo> vec;
            vec.push_back(&multiply);
            vec.push_back(&add);
            for(std::vector<foo>::const_iterator it = vec.begin(); it!=vec.end(); ++it){
                    std::cout << (*it)(5,7) << std::endl;
            }
            A a1;
            a1.j = 5;
            A a2;
            a2.j = 3;
            std::vector<bar> vec2;
            vec2.push_back(&A::multiply);
            vec2.push_back(&A::add);
            for(std::vector<bar>::const_iterator it = vec2.begin(); it!=vec2.end(); ++it){
                    std::cout << (a1.**it)(7) << std::endl;
                    std::cout << (a2.**it)(7) << std::endl;
            }
            return 0;
    }
    

    Ich weiß nicht, ob dich das weiterbringt...
    Aber wenn du eine Schnittstelle haben möchtest, musst du sie auch definieren 😉
    Also brauchst du eine genaue Funktions-Spezifikation

    EDIT: Achso: Du kannst natürlich alle zur verfügungstehenden Parameter an der
    Funktionszeiger übergeben. Dann kannst du ja Funktionen schreiben, die den
    Aufruf mit den passenden Parametern delegieren.



  • Ich verstehe auch nicht, was Du willst. Das mag daran liegen, dass ich mich mit Gtk/mm nicht auskenne oder auch daran, dass Du eine sehr komische Terminologie verwendest.

    "dass ein GTK/Gtkmm Objekt nicht mehr als ein Event vom selben EventTyp haben kann"

    Was meinst Du damit?
    Wie "hat" ein Objekt denn ein "Event" bzw "EventTyp"?

    Kannst Du Dein Problem ohne "Event", "EventTyp" und "GTK Objekt" formulieren?

    Was soll das für ein Container sein, wie willst Du ihn benutzen?



  • krümelkacker schrieb:

    "dass ein GTK/Gtkmm Objekt nicht mehr als ein Event vom selben EventTyp haben kann"

    Was meinst Du damit?
    Wie "hat" ein Objekt denn ein "Event" bzw "EventTyp"?

    blöde wörter benutze ich da aber mir fällt das beschreiben etwas schwer 😞
    EventTyp: "signal_release_event".
    (release)Event: die funktion die aufgerufen wird, wenn man auf ein GTK-Objekt ( was in meinem Fall der Button ist) klickt.

    Kannst Du Dein Problem ohne "Event", "EventTyp" und "GTK Objekt" formulieren?

    class Button
    {
    public:
        Button(int x, int y, int width, int height);
    
        void addAnotherEventHandlerForReleaseEvent(functionType function);
    
    private:
        bool eventHandlerForReleaseEvent(); // Ruft alle funktionen im functionContainer auf. *** 
        std::vector<functionType> functionContainer;
    };
    

    Was soll das für ein Container sein, wie willst Du ihn benutzen?

    ***

    Das Problem ist dass man in GTK+ / Gtkmm an einem Widget(GTK Objekt) nur ein EventHandler(event) für ein ReleaseEvent(eventtyp) anbinden kann. ich bräuchte aber N EventHandler für das ReleaseEvent.

    Irgendwie ist das für mich jetzt klarer geworden 😃
    Dann wäre meine eigentliche Frage beantwortet worden. Danke CSpille und krümelkacke.
    noch eine frage:
    Könnte man den functionType wirklich nicht flexibler machen?



  • Wäre std::tr1::function (respektive boost::function ) etwas? Für komplette Signal/Slot-Systeme kannst du auch boost::signals verwenden...

    Insbesondere mit bind() bist du nämlich schon sehr flexibel.



  • Nexus schrieb:

    Wäre std::tr1::function (respektive boost::function ) etwas?

    Nexus wie immer eine große Hilfe! http://www.boost.org/doc/libs/1_43_0/doc/html/signals/tutorial.html#id1729727

    das hilft mir sehr! danke 🙂



  • gtkmm kommt, soweit ich weiß, mit seiner eigenen signal/slot Implementierung daher, welche ausgegliedert wurde und separat nutzbar ist. Damit sollte es eigentlich auch gehen. Man kann scheinbar auch ein "Signal" mit mehreren "Slots" verbinden.



  • krümelkacker schrieb:

    gtkmm kommt, soweit ich weiß, mit seiner eigenen signal/slot Implementierung daher, welche ausgegliedert wurde und separat nutzbar ist. Damit sollte es eigentlich auch gehen. Man kann scheinbar auch ein "Signal" mit mehreren "Slots" verbinden.

    Hab was gefunden. Danke krümelkacker: http://library.gnome.org/devel/gtk/stable/GtkWidget.html#GtkWidget-button-press-event

    achtet auf den Satz:

    Returns :
    TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.

    That's it!


Anmelden zum Antworten