[qt] Konstruktor mit funktionszeiger initialisieren?



  • Hallo!

    Ich möchte von QMainWindow aus ein Widget 2tes, eigenständiges Widget starten (also als Fenster, nicht als child irgendwo), dass sich je anch Konstruktorparameter anders Verhält. So soll es zB in Fall A eine Datei Speichern und in Fall B löschen. Um dem Widget mitzuteilen, was es gerade machen soll, dachte ich an Funtkionszeiger als Parameter im Konstruktor, damit ich dann mit Hilfe diesem Zeiger dein OK-Button mit der jeweiligen Funkition verbinden kann.

    connect(PButton, SIGNAL(clicked()), this, SLOT(funktionszeigerAufSlot()));
    

    Aber wie soll ich in einer Fremden Klasse einen Zeiger auf einen private slot: zeigen lassen?
    Oder ist der ansatz falsch/umständlich/irre? 😃



  • Hmm?
    Der OK Button ist auf diesem Widget? Ja?
    Frage: Warum machst du den Slot private?
    Kann jetzt nicht nachvollziehen wos klemmt..

    public slot:
    void slotAufFunktionszeiger()
    {
        mein_Funktionszeiger();      // als private member, im Ctor initialisiert
    }
    
    //...
    
    connect(PButton, SIGNAL(clicked()), this, SLOT(slotAufFunktionszeiger()));
    

    Oder hab ichs jetzt nicht richtig verstanden?



  • Hmm....
    mein MainWindow ruft dieses Widget auf. Bei diesem Aufruf soll in irgendeiner Weiße die information weitergegeben werden WAS das Widget in diesem Fall machen soll:

    mainwindow.cpp

    newWidget = new MyWidgetClass(!!!ZEIGER!!!);
    

    Der Zeiger soll nun auf eine Funktion der Widget-Klasse ...

    zB: void MyWidgetClass::saveFile() oder void MyWidgetClass::deleteFile() ^^

    ...damit dann das Widget im Konstruktor folgendes macht:

    widget.cpp

    MyWidgetClass::MyWidgetClass(!!!ZEIGER!!!)
    {
    connect(PButton, SIGNAL(clicked()), this, SLOT(!!!ZEIGER!!!));
    }
    

    (Ja, PButton ist auf dem Widget)
    So könnte man steuern wie sich das Widget nun verhalten soll. Oder soll ich für jede Möglichkeit eine eigene WidgetKlasse erzeugen? Ein bisscehn aufwändig find ich...



  • Pigeon schrieb:

    Oder soll ich für jede Möglichkeit eine eigene WidgetKlasse erzeugen? Ein bisscehn aufwändig find ich...

    Wär logischer.
    Aber probiers mal so wie mein Bsp oben, sollte gehen.
    Die Funktion, auf die gezeigt werden soll muss aber wohl public sein,probiers aus.



  • Okay... ist public. Hier (einer) meiner verzweifelten Versuche:

    mainwindow.cpp

    MyWidgetClass *newWidget = new MyWidgetClass(newWidget->createFile());
    

    widget.h

    class MyWidgetClass : public QWidget
    {
    public:
          MyWidgetClass::MyWidgetClass(void* ());
    
    public slots:
          void createFile();
    };
    

    widget.cpp

    MyWidgetClass::MyWidgetClass(void* ())
    

    src/mainwindow.cpp: In member function »void MainWindow::newFile()«:
    src/mainwindow.cpp:125: Fehler: falsche Benutzung eines void-Ausdruckes
    make: *** [mainwindow.o] Fehler 1

    ??? 😞


  • Mod

    Pigeon schrieb:

    Okay... ist public. Hier (einer) meiner verzweifelten Versuche:

    mainwindow.cpp

    MyWidgetClass *newWidget = new MyWidgetClass(newWidget->createFile());
    

    Das geht so nicht, du kannst auf eine noch nicht erstellte Instanz nicht zugreifen.
    &MyWidgetClass::createFile wäre korrekt. Aber du brauchst für eine Methode auch noch die instanz zum aufrufen,
    in diesem Falle this.



  • Vielen Dank erstmal für eure schnellen Antworten!! 😃 😃

    Aber du brauchst für eine Methode auch noch die instanz zum aufrufen,
    in diesem Falle this.

    Ich denk du meinst damit, dass ich in MyWidgetClass::MyWidgetClass(int (MyWidgetClass::*)()) nicht auf den Parameter zugreifen kann? Das seh ich ganz genauso, aber wie soll das mit this funktonieren?


  • Mod

    Pigeon schrieb:

    Vielen Dank erstmal für eure schnellen Antworten!! 😃 😃

    Aber du brauchst für eine Methode auch noch die instanz zum aufrufen,
    in diesem Falle this.

    Ich denk du meinst damit, dass ich in MyWidgetClass::MyWidgetClass(int (MyWidgetClass::*)()) nicht auf den Parameter zugreifen kann? Das seh ich ganz genauso, aber wie soll das mit this funktonieren?

    Hm, kenn mich jetzt mit dem signal slot prinzip nicht so gut aus, aber soll bei clicked nun PButton::newFile,
    oder MyWidgetClass::newFile aufgerufen werden? Und für was hast du einen namenlosen Parameter im Konstruktor?



  • QObject::connect(PButton, SIGNAL(clicked()), this, SLOT(!!ZEIGER!!));

    Der Zeiger soll je nachdem auf MyWidgetClass::newFile() oder MyWidgetClass::deleteFile() zeigen. Aber leider bin ich nicht - auf Grund meiner geringen Klassen-kentnisse - in der Lage einen zeiger mit Variablennamen als Parameter zu setzen. Wie müsste denn der Prototyp des Konstruktors aussehen?

    Dass er vom Typ int (MyWidgetClass::*)() sein muss hat mir der Compiler verraten...

    P.S: Ja ich bins *g* (keine Zugangsdaten da nicht mehr zu Hause)


  • Mod

    Mit Typedef: (liest sich leichter ;))

    typedef int (MyWidgetClass::*mymethodpointer)();
    mymethodpointer p = &MyWidgetClass::newFile;
    

    Dein Konstruktor müsste also einen methodenpointer enthalten, welcher dann an connect übergeben wird:
    QObject::connect(PButton, SIGNAL(clicked()), this, SLOT(&MyWidgetClass::newFile));





  • Hi

    Pigeon schrieb:

    Ich möchte von QMainWindow aus ein Widget 2tes, eigenständiges Widget starten (also als Fenster, nicht als child irgendwo), dass sich je anch Konstruktorparameter anders Verhält. So soll es zB in Fall A eine Datei Speichern und in Fall B löschen. Um dem Widget mitzuteilen, was es gerade machen soll, dachte ich an Funtkionszeiger als Parameter im Konstruktor, damit ich dann mit Hilfe diesem Zeiger dein OK-Button mit der jeweiligen Funkition verbinden kann.

    Dir ist schon klar, dass du, nur weil du eine grafische Oberfläche programmierst, nicht auch Sachen ohne irgendeinem grafischen Ergebnis o.Ä. machen könntest. Wenn sich also bei dir etwas ändert und du darauf mit Löschen / Schreiben / sonstwas einer Datei reagieren willst, kannst du dies auch ohne grafischer Ausgabe erledigen.

    Ansonsten wäre eine Alternative, dass du deinem Widget zwei SLOTS schenkst, einen fürs Löschen, den anderen fürs Schreiben. Das Widget wird ein Member von MainWindow. Wenn sich etwas tut zeig das Widget an (QWidget::show()). Wird der Button gedrückt erledige die Dateioperation, dann QWidget::hide().

    Grüße
    Franz



  • Hmm ... leider hat der typedef Vorschlag von phlox81 nicht funktioniert 😞

    @franz: das ist mir durchaus bewusst. Aber ich dachte, ich packe den Code für das was das neue Widget machen soll in selbige Klasse, da es ja (vorraussichtlich) niemals von QMainWidget ausgeführt werden wird! Erst durch den Klick auf den Button (erst dann und NUR dann) wird gespeichert/gelöscht etc. Ich hielt es daher für ungeschickt alles in mainwindow.cpp zu haben.

    Ich probiere demnächst mal eine andere Variante aus, oder wie seht ihr das?



  • So ... Problem gelöst?

    Ich habe dass connecten meinem MainWindow überlassen und den Parameter im Konstruktor einfach weggelassen, wenn ihr mir folgen könnt *g*

    Vielen herzlichen Dank für eure Bemühungen!!! 🙂 😃 🙂


Log in to reply