Anzeige:
Ergebnis 1 bis 15 von 15

Thema: QT Signals/Slots: Wie der Ochs form Berge

  1. #1
    Registrierter Benutzer
    Registriert seit
    26.02.2004
    Ort
    Grefrath
    Beiträge
    28

    QT Signals/Slots: Wie der Ochs form Berge

    Hi!

    Ich hab gestern mal mit QT angefangen.
    Soweit, so gut.
    Ich programmiere direkt in Kate, also zu Fuß, ohne irgendwelche Designer.

    Ne Oberfläche krieg ich ja noch zusammengebastelt.

    Aber dann kommen die Signals und Slots.
    Öh ja.

    Eigenltich will ich ja nur die 'activated'-Funktion von ner Combobox mit ner äffen void-Funktion verbinden und der index, der von activated kommt soll mit an diese void-funktion übergeben werden.

    aber irgendwie krieg ich das net hin.
    wo muss denn bitte die deklaration von der funktion, die ich aufrufe rein.
    mit in die widget klasse?
    in ne eigene klasse?
    einfach als normale funktion in dem programm?

    ich werd aus den dokus bei trolltech irgendwie nicht schlau

    hoffe hier kann mir einer den tipp geben, damit ich das system komplett durchschaue.

    zeeman

    P.S.: was heißt widget übersetzt eigentlich?

  2. #2
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    719
    so:

    Code:
    class MyWidget : public QWidget{
     Q_OBJECT
      public slots:
         void handleActivated(int id);
    
    };

  3. #3
    Registrierter Benutzer
    Registriert seit
    26.02.2004
    Ort
    Grefrath
    Beiträge
    28
    also hier mal ein paar codestellen von mir:

    Code:
    class MyWidget : public QWidget
    {
    //Q_OBJECT
    public slots:
        void handleActivated(int id);
      public:
        MyWidget( QWidget *parent=0, const char *name=0 );
    };
    wenn ich da Q_OBJECT einfüge prasselt es fehlermeldungen beim kompilieren:
    Code:
    main.o(.text+0x43): In function `MyWidget::MyWidget[not-in-charge](QWidget*, char const*)':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x4f): In function `MyWidget::MyWidget[not-in-charge](QWidget*, char const*)':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x11a3): In function `MyWidget::MyWidget[in-charge](QWidget*, char const*)':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x11af): In function `MyWidget::MyWidget[in-charge](QWidget*, char const*)':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x23ea): In function `main':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x23f5): more undefined references to `vtable for MyWidget' follow
    collect2: ld returned 1 exit status
    Code:
    void handleActivated(int id)
    {
    qWarning( "test" );
    }
    einfach nur mal zum testen

    Code:
    MyWidget::MyWidget( QWidget *parent, const char *name )
            : QWidget( parent, name )
    {
    [...]
        connect ( GK, SIGNAL(activated()), qApp, SLOT (quit()));
    // connect ( GK, SIGNAL(activated(index)), qApp, SLOT (handleActivated(index)));
    beides davon geht nicht
    es kommt immer zur laufzeit:
    Code:
    QObject::connect: No such signal QComboBox::activated()
    QObject::connect:  (sender name:   'GK')
    GK ist ein pointer auf eine QCombobox.

    ich verstehs net.....

  4. #4
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Das Q_OBJECT Macro muss im der Dekaration drinnen sein, weil sonst das Objekte keinen Signals oder Slots hat (sondern nur normale Methoden)

    Der Fehler ist kein MOC File, also moc hat den Header nicht geparst und kein entsprechendes File mit den QObject Sachen angelegt.

    Auch wenn du zu Fuß arbeitest, spricht nichts dagegen, qmake zu Makefilegenerierung zu verwenden.

    Beide Möglichkeiten (händischer moc Aufruf und qmake Benutzung) werden im Qt Tutorial im Tutorial Unterforum beschrieben.

    Widget:
    ist ein Kunstwort, eine Verknüpfung von Window und Gadget.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  5. #5
    Registrierter Benutzer
    Registriert seit
    26.02.2004
    Ort
    Grefrath
    Beiträge
    28
    qmake hab ich eigentlich immer verwendet, gut schau ich da nochmal
    weiß ja jetzt nach was ich ausschau halten muss.

    danke für die erklärung
    nur was ist ein gadget?

  6. #6
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Gadget ist einerseits irgend so n technischer Apparat. Andererseits (und das triffts wohl) ein Zubehörteil.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  7. #7
    Registrierter Benutzer
    Registriert seit
    26.02.2004
    Ort
    Grefrath
    Beiträge
    28
    ich krieg gleich ne kramp.

    nach dem studium der doku von qt hieß es eigenltich qmake macht das alles selber
    qmake -project
    qmake

    und dann
    make

    fertig.
    pustkuchen.

    ich habs jetzt mal mit folgendem versucht:
    qmake -project
    qmake
    dann ganz unten in meine main.cpp (ist nur eine datei das programm)
    include <main.moc>
    abspeichern
    moc main.cpp > main.moc
    make

    soweit so gut

    nu bin ich hier:
    main.o(.text+0x298d): In function `MyWidget::qt_invoke(int, QUObject*)':
    : undefined reference to `MyWidget::handleActivated(int)'
    collect2: ld returned 1 exit status

    also irgendwas stimmt hier net.
    HILFE

  8. #8
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    Hi,

    wenn du qmake benutzt brauchst du dich nicht um moc Dateien zu kümmern, da qmake diese automatisch generiert und mit reinkompiliert.

    Also einfach qmake -project && qmake && make.

    Falls irgendwas schiefläuft, nochmal die .pro Datei überprüfen.

    Gruss,
    Michael.

  9. #9
    Registrierter Benutzer
    Registriert seit
    26.02.2004
    Ort
    Grefrath
    Beiträge
    28
    wie schon oben gepostet, dann kommt das hier:
    Code:
    main.o(.text+0x43): In function `MyWidget::MyWidget[not-in-charge](QWidget*, char const*)':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x4f): In function `MyWidget::MyWidget[not-in-charge](QWidget*, char const*)':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x11a3): In function `MyWidget::MyWidget[in-charge](QWidget*, char const*)':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x11af): In function `MyWidget::MyWidget[in-charge](QWidget*, char const*)':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x23ea): In function `main':
    : undefined reference to `vtable for MyWidget'
    main.o(.text+0x23f5): more undefined references to `vtable for MyWidget' follow
    meine pro-file:
    Code:
    ##############################################
    # Automatically generated by qmake (1.06c) Thu Feb 26 22:01:07 2004
    ##############################################
    
    TEMPLATE = app
    CONFIG -= moc
    INCLUDEPATH += .
    
    # Input
    SOURCES += main.cpp
    also irgendwie stört mich dieses -=
    += heißt ja an liste anfügen
    = liste ersetzen
    aber -=
    von liste abziehen?!?!

  10. #10
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Gib mal das Widget in ein eigenes header/source Paar, also zB mywidget.h und mywidget.cpp

    Dann würde ich das .pro File händisch erzeugen, etwa so

    Code:
    TEMPLATE = app
    CONFIG += qt thread warn_on
    
    HEADERS = mywidget.h
    SOURCES = main.cpp mywidget.cpp
    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  11. #11
    Registrierter Benutzer
    Registriert seit
    26.02.2004
    Ort
    Grefrath
    Beiträge
    28
    ich weiß einfach nicht mehr weiter, bitte einer mal drauf schaun:
    Code:
    #include <qapplication.h>
    #include <qapplication.h>
    #include <qpushbutton.h>
    #include <qfont.h>
    #include <qlineedit.h>
    #include <qlabel.h>
    #include <qcombobox.h>
    #include <qtextedit.h>
    #include <qsqldriver.h>
    #include <qsqldatabase.h>
    
    #define DB_ADRESS_DRIVER	"QMYSQL3"
    #define DB_ADRESS_DBNAME	"stundenplan"
    #define DB_ADRESS_USER		"xxxx"
    #define DB_ADRESS_PASSWD	"xxxxx"
    #define DB_ADRESS_HOST		"wodan"
    
    
    class Hausaufgabe: public QObject
    {
       Q_OBJECT
    public slots:
    
    signals:
    
    private:
      char *username;
      char *password;
      char *dateiname;
      char *titel;
      char *nachricht;
    public:
      void SetUsername(char *user);
      void SetPassword(char *pw);
      void SetDateiname(char *filename);
      void SetTitle(char *text);
      void SetNachricht(char *text);
    };
    
    
    
    class MyWidget : public QWidget
    {
    Q_OBJECT
    public slots:
        void handleActivated( int Schiene);
      public:
        MyWidget( QWidget *parent=0, const char *name=0 );
    };
    
    MyWidget::MyWidget( QWidget *parent, const char *name )
            : QWidget( parent, name )
    {
        setMinimumSize( 400, 600 );
        setMaximumSize( 400, 600 );
    
        QLabel *lbUsername = new QLabel(this);
        QLabel *lbPassword = new QLabel(this);
    
        QLineEdit *username = new QLineEdit("", this, "username");
        QLineEdit *password = new QLineEdit("", this, "password");
        QLineEdit *filename = new QLineEdit("", this, "filename");
    
        QPushButton *quit = new QPushButton( "Beenden", this, "quit" );
        QPushButton *login=new QPushButton("Einloggen",this,"login");
        QPushButton *datei=new QPushButton(". . .", this, "datei");
        QPushButton *upload=new QPushButton("Hochladen", this, "upload");
    
        QComboBox *GK = new QComboBox( FALSE, this, "GK" );
        QComboBox *Fach = new QComboBox( FALSE, this, "Fach" );
    
        QTextEdit *Nachricht = new QTextEdit (this, "Nachricht");
    
        quit->setFont( QFont( "Arial", 10 ) );
        quit->setGeometry(320, 565, 75, 30 );
    
        login->setFont(QFont("Arial,10"));
        login->setGeometry(320,45,75,25);
    
        lbUsername->setText ( "Benutzername:");
        lbUsername->setGeometry(5,10,100,25);
        lbUsername->setFont( QFont("Arial",10));
    
        lbPassword->setText("Passwort:");
        lbPassword->setFont(QFont("Arial",10));
        lbPassword->setGeometry(210,10,70,25);
    
        username->setFont(QFont("Arial",10));
        username->setGeometry(105,10,100,25);
    
        password->setFont(QFont("Arial",10));
        password->setGeometry(285,10,100,25);
        password->setEchoMode(QLineEdit::Password);
    
        GK->setFont(QFont("Arial",10));
        GK->setGeometry(105, 80, 100, 25);
        GK->insertItem("LK 1",-1);
        GK->insertItem("LK 2",-1);
        GK->insertItem("GK 1",-1);
        GK->insertItem("GK 2",-1);
        GK->insertItem("GK 3",-1);
        GK->insertItem("GK 4",-1);
        GK->insertItem("GK 5",-1);
        GK->insertItem("GK 6",-1);
        GK->insertItem("GK 7",-1);
        GK->insertItem("GK 8",-1);
    
        Fach->setFont(QFont("Arial",10));
        Fach->setGeometry(285, 80, 100, 25);
    
        Nachricht->setFont(QFont("Arial",10));
        Nachricht->setGeometry(5, 115, 390,350);
    
        filename->setFont(QFont("Arial",10));
        filename->setGeometry(5,475,355,25);
    
        datei->setFont(QFont("Arial",10));
        datei->setGeometry( 365,475,30,25);
    
        upload->setFont(QFont("Arial",10));
        upload->setGeometry(150,510,100,50);
    
        connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );
        connect ( GK, SIGNAL(activated(index)), qApp, SLOT(handleActivated(index)));
    
        }
    
    void MyWidget::handleActivated( int Schiene)
    {
    Schiene=1;
    qWarning( "test" );
    }
    
    int main( int argc, char **argv )
    {
        QApplication a( argc, argv );
    
        MyWidget w;
        w.setGeometry( 100, 100, 200, 120 );
        a.setMainWidget( &w );
        w.show();
           QSqlDatabase *defaultDB = QSqlDatabase::addDatabase( DB_ADRESS_DRIVER );
        if ( ! defaultDB )
    		{
    			qWarning( "main: Keine Verbindung zur Datenbank" );
    			return 1;
        }
        return a.exec();
    }
    
    #include "main.moc"
    dann krieg ich das programm auch so kompiliert:
    # qmake -project
    # qmake
    # moc main.cpp > main.moc
    # make

    nur dann kommt das (wie orginell):
    Code:
    QObject::connect: No such signal QComboBox::clicked()
    QObject::connect:  (sender name:   'GK')
    QObject::connect:  (receiver name: 'Hausaufgaben')
    - ja, ich weiß, die schriftart hätte man auch global definieren können
    - die klasse hausaufgaben ist untinteressant, ich hab sie nur schonmal definiert
    - meine void-funktion is erstmal nur ne dummyfunktion. das soll erstmal laufen
    der rest sollte klar sein, ansonsten bitte mal melden.
    ich seh da echt keine fehler mehr

    MfG
    Sebastian

  12. #12
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Original geschrieben von zeeman
    ich weiß einfach nicht mehr weiter, bitte einer mal drauf schaun:
    Code:
    #include <qapplication.h>
    #include <qapplication.h>
    zweimal?

    Code:
    private:
      char *username;
      char *password;
      char *dateiname;
      char *titel;
      char *nachricht;
    Bitte, bitte, bitte QString!

    Code:
    public:
      void SetUsername(char *user);
      void SetPassword(char *pw);
      void SetDateiname(char *filename);
      void SetTitle(char *text);
      void SetNachricht(char *text);
    };
    const QString& statt char*

    Code:
        QLineEdit *username = new QLineEdit("", this, "username");
        QLineEdit *password = new QLineEdit("", this, "password");
        QLineEdit *filename = new QLineEdit("", this, "filename");
    Gefährlich lokale Variablen wie Instanzvariablen zu benennen, da kann man schnell durcheinander kommen.

    Code:
        connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );
        connect ( GK, SIGNAL(activated(index)), qApp, SLOT(handleActivated(index)));
    Die Macros SIGNAL und SLOT brauchen bei den Parametern nur den Typ, nicht den Namen des Parameters, also
    Code:
        connect ( GK, SIGNAL(activated(int)), qApp, SLOT(handleActivated(int)));
    Ich denke bei einer UI mir mehreren Elementen ist es wesentlich einfacher im Designer.
    Dann die eigentliche Klasse davon ableiten und die Sachen wie zB Slots implementieren.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  13. #13
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    719
    QComboBox hat ja auch kein Signal clicked():

    Signals

    *
    void activated ( int index )
    *
    void highlighted ( int index )
    *
    void activated ( const QString & string )
    *
    void highlighted ( const QString & string )
    *
    void textChanged ( const QString & string )

    von http://doc.trolltech.com/3.3/qcombobox.html

  14. #14
    Registrierter Benutzer
    Registriert seit
    26.02.2004
    Ort
    Grefrath
    Beiträge
    28
    es geht.
    lag nur an dem 'int' was für das signal mit rein muss

    *freufreu*

    das mit den lokalen, gleichen vars
    da ich net gleichzeitig auf beide zugreifen kann (sind ja privat in der klasse, nur über SetXXX) fand ich das vertrebar.

    zu den qstrings mach ich mich mal schlau (das sind dann wohl irgendwelche eierlegenden wollmilchsäue die overflows und sowas abfangen. ich schau mal)

    qmake will zwar noch net ganz automatisch, aber das krieg ich selber hin.

    nochmal dickes Danke an alle die geholfen haben

  15. #15
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Original geschrieben von zeeman

    das mit den lokalen, gleichen vars
    da ich net gleichzeitig auf beide zugreifen kann (sind ja privat in der klasse, nur über SetXXX) fand ich das vertrebar.
    Die lokalen Variablen waren im Konstruktor der Klasse und der Code des Konstruktors hat üblicherweise direkten Zugriff auf die private Variablen, wie andere Methoden auch.


    zu den qstrings mach ich mich mal schlau (das sind dann wohl irgendwelche eierlegenden wollmilchsäue die overflows und sowas abfangen. ich schau mal)
    Unter anderem.
    In C++ verwendet man praktisch immer eine Stringklasse, nur bei der Benutzung von C Funktionen geht man auf das char* zurück.
    char* ist nämlich wesentlich umständlicher in der Handhabung und warum sollte man sich das Lebem unnötig schwer machen.

    In Qt benutzt man praktisch immer QString, in C++ ohne Qt meistens std::string

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

Lesezeichen

Berechtigungen

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