Anzeige:
Ergebnis 1 bis 15 von 15

Thema: [QT] connect mit Methodenzeigern

  1. #1
    Registrierter Benutzer Avatar von Gartenzwerg
    Registriert seit
    26.06.2003
    Beiträge
    75

    [QT] connect mit Methodenzeigern

    Hallo!

    Ich habe folgendes Problem:
    Ich habe 5 Knöpfe und möchte die in einem Array speichern und entsprechend initialisieren, dafür habe ich folgende Struktur erstellt:

    Code:
    struct Buttons
    {
        typedef void (OptionChangeWindow::*PtrToSlot)( void);
        QString Name;
        PtrToSlot Slot;
    };
    Buttons MyButtons[2] =
    {
        {"Hinzufügen", &OptionChangeWindow::AddOption},
        {"Ändern",  &OptionChangeWindow::ChangeOption},
    };
    Mein connect sieht wie folgt aus:
    Code:
    connect(mCommands[i].get(), SIGNAL(clicked()), this, SLOT( MyButtons[i].Slot ) );
    Wobei mCommands ein vector von boost::shared_ptr auf die QPushButtons ist.
    Das Problem liegt beim letzten Parameter und zwar wird das MyButtons[i].Slot nicht aufgelöst zu der wirklichen Memberfunktion, sondern einfach als String genommen.
    Der Laufzeitfehler ist dann folgender:
    QObject::connect: Parentheses expected, slot OptionChangeWindow::MyButtons[i].Slot
    Kann man eventuell ein eigenes Makro schreiben, das den Zeiger vorher dereferenziert und das ganze dann in einen String umwandelt oder gibt es eine viel einfachere Lösung?
    http://sebastian.familiegibb.de | GiKraSoft | Nachwachsende Rohstoffe
    Ich denke niemals an die Zukunft - sie kommt früh genug.
    Albert Einstein

  2. #2
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    hi,

    gibt es irgendeinen grund warum du sowas probierst? mir erschliesst sich gerade nicht so ganz der sinn deiner methode.

    aber um deine frage teilweise zu beantworten:
    als receiver muss eine funktion angegeben werden, die ausdrücklich als slot definiert wurde.
    http://www.trolltech.com/products/qt...tepaper-3.html

    gruss,
    michael.

  3. #3
    Registrierter Benutzer Avatar von Gartenzwerg
    Registriert seit
    26.06.2003
    Beiträge
    75
    hi,
    warum ich das probiere?
    Ich habe ja nun ein paar mehr Buttons mit Slots zu connecten und da empfinde ich das als reichlich ineffektiv alle einzeln zu connecten. Das sollte eine for-Schleife für mich machen.
    Das Dokument hilft mir nicht wirklich, da mir das Signal-Slot-Prinzip vertraut ist. Die unter connect angegebenen Funktionen im SLOT-Bereich sind auch als public slots: in meiner Klasse definiert.
    Gibt es da keine Möglichkeit?

    Tschau Gartenzwerg
    http://sebastian.familiegibb.de | GiKraSoft | Nachwachsende Rohstoffe
    Ich denke niemals an die Zukunft - sie kommt früh genug.
    Albert Einstein

  4. #4
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    719
    Das was du vorhast, ist gängig, aber deine Umsetzung ist unüblich. Wenn du mehrere Buttons hast und alle sollen mit einem Slot conntected werden, nimmst du eine QButtonGroup, packst die Buttons rein und verbindest das clicked-signal der Group mit deinem Slot.

  5. #5
    Registrierter Benutzer Avatar von Gartenzwerg
    Registriert seit
    26.06.2003
    Beiträge
    75
    hi,
    die Buttons sollen ja nicht alle mit dem selben Slot verbunden werden. Wenn ich für jeden Slot eine Gruppe Buttons erstelle, habe ich immer noch die selbe Arbeit.

    Tschau Gartenzwerg
    http://sebastian.familiegibb.de | GiKraSoft | Nachwachsende Rohstoffe
    Ich denke niemals an die Zukunft - sie kommt früh genug.
    Albert Einstein

  6. #6
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    719
    Anstatt dem connect-aufruf musst du ja jetzt den Funktionspointer in deine Struktur schreiben. Das ist eine Zeile Code. Der connect-Aufruf wäre auch eine Zeile Code. was findest du jetzt an deiner Lösung so viel eleganter?

  7. #7
    Registrierter Benutzer Avatar von microdigi
    Registriert seit
    13.07.2002
    Ort
    Bad Soden-Salmuenster
    Beiträge
    104

    :) ich wuerde ...

    ...die fuenf knoepfe an die jacke naehen.
    das sieht dann so aus:
    gruss mit spass - digi
    Rentner66 (als Nebenberuf)
    'Fossil' der ersten IT-Stunde, weltweit manches 'ausgefressen'
    0173 1047 047
    Intel P4(686)-2,53 GHz, 1GB, 2x80 GB, 2xNW, Sound, CD-RW, DVD-DL-RW, ATI Radeon 9000,
    LINUX (SuSE-9.3-Prof -- KDEvelop-QT-Professional),
    after ten years m$ VS97: C++ & MFC > NO windows anymore! NEVER-EVER! :eek: ...
    e-commerce networker

  8. #8
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    Original geschrieben von axeljaeger
    Anstatt dem connect-aufruf musst du ja jetzt den Funktionspointer in deine Struktur schreiben. Das ist eine Zeile Code. Der connect-Aufruf wäre auch eine Zeile Code. was findest du jetzt an deiner Lösung so viel eleganter?
    zudem frage ich mich, wieviele buttons du erstellen willst, dass es dir zuviele aufrufe sind .
    20? 200?

  9. #9
    Registrierter Benutzer Avatar von Gartenzwerg
    Registriert seit
    26.06.2003
    Beiträge
    75
    hi,
    hab mir schon Nadel und Faden besorgt
    Es geht ja auch ein bisschen um das Design und die Übersichtlichkeit.
    Das sieht doch wohl wesentlich besser und übersichtlicher aus ...
    Code:
    struct Buttons
    {
        typedef void (OptionChangeWindow::*PtrToSlot)( void);
        QString Name;
        PtrToSlot Slot;
    };
    
    Buttons MyButtons[2] =
    {
        {"Hinzufügen", &OptionChangeWindow::AddOption},
        {"Ändern",  &OptionChangeWindow::ChangeOption},
    };
    
    for(unsigned int i = 0; i < sizeof(MyButtons) / sizeof(Buttons); ++i)
    {
    //Einen neuen Button erzeugen mit entsprechendem Namen
    mCommands.push_back(boost::shared_ptr<QPushButton>(new QPushButton(this, MyButtons[i].Name)));
    mCommands[i]->setGeometry(130, 20+40*i, 70, 30);
    mCommands[i]->show();
    mCommands[i]->setText(MyButtons[i].Name);
    connect(mCommands[i].get(), SIGNAL(clicked()), this, SLOT( MyButtons[i].Slot ) );
    // Verursacht: "QObject::connect: Parentheses expected, slot OptionChangeWindow::MyButtons[i].Slot"
    }
    als das:
    Code:
    struct Buttons
    {
        typedef void (OptionChangeWindow::*PtrToSlot)( void);
        QString Name;
        PtrToSlot Slot;
    };
    
    Buttons MyButtons[2] =
    {
        {"Hinzufügen", &OptionChangeWindow::AddOption},
        {"Ändern",  &OptionChangeWindow::ChangeOption},
    };
    
    for(unsigned int i = 0; i < sizeof(MyButtons) / sizeof(Buttons); ++i)
    {
    //Einen neuen Button erzeugen mit entsprechendem Namen
    mCommands.push_back(boost::shared_ptr<QPushButton>(new QPushButton(this, MyButtons[i].Name)));
    mCommands[i]->setGeometry(130, 20+40*i, 70, 30);
    mCommands[i]->show();
    mCommands[i]->setText(MyButtons[i].Name);
    //TODO klappt noch nicht so ganz!
    //connect(mCommands[i].get(), SIGNAL(clicked()), this, SLOT( MyButtons[i].Slot ) );
    }
    //Ich geb mich erstmal geschlagen und connecte sie manuell
    connect(mCommands[0].get(), SIGNAL(clicked()), this, SLOT(AddOption()));
    connect(mCommands[1].get(), SIGNAL(clicked()), this, SLOT(ChangeOption()));
    oder etwa nicht?
    Des Weiteren ist es einfacher zu warten, das spielt auch eine gewisse Rolle.
    Außerdem habe ich das jetzt solange ausprobiert, dass es mich brennend interessiert, wie das funktionieren könnte, ob es etwas nutzt oder nicht. Ich würde es gerne wissen.

    Tschau Gartenzwerg
    http://sebastian.familiegibb.de | GiKraSoft | Nachwachsende Rohstoffe
    Ich denke niemals an die Zukunft - sie kommt früh genug.
    Albert Einstein

  10. #10
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    719
    Ein Slot ist kein Funktionspointer, sondern ein String. Das du deine eine gebastelte Lösung eleganter findest, als die andere gebastelte Lösung, ist nachzuvollziehen, warum du aber überhaupt den QPushButton nochmal in eine Struct kapselst, wo doch Struct in einem C++Programm sowieso fragwürdig ist, nicht.

  11. #11
    Registrierter Benutzer Avatar von Gartenzwerg
    Registriert seit
    26.06.2003
    Beiträge
    75
    hi,
    ich könnte den QPushButton auch in einer Klasse kapseln. Das ist unwichtig.
    Das SLOT-Makro sieht wie folgt aus:
    Code:
    #define SLOT(a) "1"#a
    oder nicht?

    Könnte man das denn irgendwie umschreiben?

    Tschau Gartenzwerg
    http://sebastian.familiegibb.de | GiKraSoft | Nachwachsende Rohstoffe
    Ich denke niemals an die Zukunft - sie kommt früh genug.
    Albert Einstein

  12. #12
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    719
    Warum willst du den überhaupt in eine Klasse kapseln? Ist dir QPushButton noch nicht genug gekapselt?

  13. #13
    Registrierter Benutzer Avatar von Gartenzwerg
    Registriert seit
    26.06.2003
    Beiträge
    75
    hi,
    ich habe doch gesagt, ich könnte! Ich habe nicht gesagt, dass ich das will. Ich würde gern ein Methodenzeiger an SLOT übergeben. Dafür hätte ich gerne einen Lösungsvorschlag oder eine Makroveränderung.

    Tschau Gartenzwerg
    http://sebastian.familiegibb.de | GiKraSoft | Nachwachsende Rohstoffe
    Ich denke niemals an die Zukunft - sie kommt früh genug.
    Albert Einstein

  14. #14
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    719
    du könntest einen Slot in einem String speichern, einfach den Returnvalue von SLOT in einen String schreiben und dann bei connect wieder übergeben. Ich möchte dir aber davon abraten, das perfekt aufeinander abgestimmte System von Signal/Slot/Connect auseinanderzunehmen. Da hast du wirklich nichts davon. Sinn der Sache ist es, keine Funktionspointer mehr zu verwenden. Wenn du das doch machen willst, siehst du dir vielleicht besser GTK an. Wenn du wirklich verstehen willst, was innerhalb von Qt abgeht und wie das mit Signals und Slots funktioniert, schau dir nochmal an, was der MOC so an Ausgaben erzeugt.

  15. #15
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Du brauchst ansich nur den Namen des Slots in einem QCString in des Struct zu speichern.
    Dann kannst du das so aufrufen

    Code:
    connect(myCommands[i], SIGNAL(clicked()), this, SLOT(myButtons[i].slot));
    Da die Buttons offensichtlich nicht dynamisch erzeugt werden, sondern feststehen, frage ich mich ob es nicht sinnvoller wäre sie direkt im Designer anzulegen und zu connecten. Die Slots dabei als virtual protected oder virtual public im Hauptwidget und dann mit ihrer Implementation überschreiben.

    Cheers,
    _
    Qt/KDE Entwickler
    Debian Benutzer

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •