[gelöst] connect mit dynamisch erzeugten Objekten?

Alles rund um die Programmierung mit Qt
Antworten
pumuckl
Beiträge: 23
Registriert: 26. November 2006 22:01

[gelöst] connect mit dynamisch erzeugten Objekten?

Beitrag von pumuckl »

Hallo!

ich hatte ich hier letztens mit eurer Hilfe QComboBoxen mit Qlist dynamisch erzeugt (siehe auch http://qtforum.de/forum/viewtopic.php?t=3489!

Nun fehlt mir nur noch das i-Tüpfelchen, wobei ich mir nicht sicher bin, ob das überhaupt geht: Ich möchte, dass, wenn in einer der dynamisch erzeugten QComboboxen eine neue Auswahl getroffen wird, eine entsprechende Procedure (hier "clickcombobox") gestartet wird. Dies geschieht üblicherweise mit connect (Signal-Slot)!

Den Slot zu schreiben ist kein Problem, aber wie sieht die connect-Anweisung aus? Wenn ich auf den Pushbutton "einfuegen" drücke, wird der Text geschrieben!! Wenn ich in der ersten Combobox was neues auswähle nicht?

Ich habe auch zwei Varianten: Die 1. wird kompiliert, funktioniert aber nicht, d.h. es wird kein Text in Line2 geschrieben. Die 2. wird gar nicht erst kompiliert -> Fehlermeldung.

Variante 1:
Headerdatei:

Code: Alles auswählen

#ifndef TABLEEDITOR_H
 #define TABLEEDITOR_H

 #include <QDialog>
 #include <QtCore>
 
 class QSqlTableModel;
 class QSqlQueryModel;
 class QLineEdit;
 class QComboBox;
 class QList<QComboBox>;

 class TableEditor : public QDialog
 {
     Q_OBJECT

 public:
     TableEditor(const QString &tableName, QWidget *parent = 0);

 private slots:
     void clickcombobox();

 private:
     QPushButton *pbeinfuegen;
     QSqlTableModel *tablemodel;
     QSqlQueryModel *querymodel;
     QLineEdit *line2;
     QComboBox *tmpp;
 };

 #endif
cpp-Datei:

Code: Alles auswählen

 #include <QtGui>
 #include <QtSql>
 #include <QTabWidget>
 #include <QString>

 #include "tableeditor.h"

 TableEditor::TableEditor(const QString &tableName, QWidget *parent)
     : QDialog(parent)
 {
    
line2 = new QLineEdit;
pbeinfuegen = new QPushButton(tr("Einfuegen"));

QSqlQuery query; //Objekt Datenbankabfrage
query.exec("select zobergruppe, zuntergruppe FROM zweck ORDER BY zobergruppe ASC "); //ca. 12 Datensätze selektieren
QString h1 = "xyz";
int i=0; int zeile=0; //Laufvariablen
QList<QComboBox*> listcbzweck; //QList mit Comboboxen erzeugen
while (query.next()) {          //12 Datensätze aus Datenbankabfrage durchlaufen
   if (h1 != query.value(0).toString()){
       h1 = query.value(0).toString();
       QComboBox *tmpp =  new QComboBox(); //neue Combobox erzeugen
       listcbzweck.append(tmpp); //Combobox zur Liste hinzufügen
       vblgroupbox1->addWidget(listcbzweck.at(i),zeile+1,i-zeile*3); //Combobox zum Layout
       listcbzweck.at(i)->addItem(query.value(1).toString()); //Combobox füllen
       ++i;
       if (i==6){zeile=zeile+2;}
   } else {
       listcbzweck.at(i-1)->addItem(query.value(1).toString()); //Comboboxen füllen
   }
}

connect(pbeinfuegen, SIGNAL(clicked()), this, SLOT(clickcombobox()));
connect(listcbzweck.at(0), SIGNAL(currentIndexChanged()), this, SLOT(clickcombobox()));
}

void TableEditor::clickcombobox()
{
    line2->setText(tr("test"));
}
Variante 2 (Änderung in der 2. connect-Anweisung):
Headerdatei:

Code: Alles auswählen

#ifndef TABLEEDITOR_H
 #define TABLEEDITOR_H

 #include <QDialog>
 #include <QtCore>
 
 class QSqlTableModel;
 class QSqlQueryModel;
 class QLineEdit;
 class QComboBox;
 class QList<QComboBox>;

 class TableEditor : public QDialog
 {
     Q_OBJECT

 public:
     TableEditor(const QString &tableName, QWidget *parent = 0);

 private slots:
     void clickcombobox();

 private:
     QPushButton *pbeinfuegen;
     QSqlTableModel *tablemodel;
     QSqlQueryModel *querymodel;
     QLineEdit *line2;
     QComboBox *tmpp;
 };

 #endif
cpp-Datei:

Code: Alles auswählen

 #include <QtGui>
 #include <QtSql>
 #include <QTabWidget>
 #include <QString>

 #include "tableeditor.h"

 TableEditor::TableEditor(const QString &tableName, QWidget *parent)
     : QDialog(parent)
 {
    
line2 = new QLineEdit;
pbeinfuegen = new QPushButton(tr("Einfuegen"));

QSqlQuery query; //Objekt Datenbankabfrage
query.exec("select zobergruppe, zuntergruppe FROM zweck ORDER BY zobergruppe ASC "); //ca. 12 Datensätze selektieren
QString h1 = "xyz";
int i=0; int zeile=0; //Laufvariablen
QList<QComboBox*> listcbzweck; //QList mit Comboboxen erzeugen
while (query.next()) {          //12 Datensätze aus Datenbankabfrage durchlaufen
   if (h1 != query.value(0).toString()){
       h1 = query.value(0).toString();
       QComboBox *tmpp =  new QComboBox(); //neue Combobox erzeugen
       listcbzweck.append(tmpp); //Combobox zur Liste hinzufügen
       vblgroupbox1->addWidget(listcbzweck.at(i),zeile+1,i-zeile*3); //Combobox zum Layout
       listcbzweck.at(i)->addItem(query.value(1).toString()); //Combobox füllen
       ++i;
       if (i==6){zeile=zeile+2;}
   } else {
       listcbzweck.at(i-1)->addItem(query.value(1).toString()); //Comboboxen füllen
   }
}

connect(pbeinfuegen, SIGNAL(clicked()), this, SLOT(clickcombobox()));
connect(listcbzweck, SIGNAL(currentIndexChanged()), this, SLOT(clickcombobox())); //--> was ist hier falsch??
}

void TableEditor::clickcombobox()
{
    line2->setText(tr("test"));
}
Fehler zu Variante 2:

Code: Alles auswählen

g++ -c -pipe -O2 -Wall -W -D_REENTRANT  -DQT_NO_DEBUG -DQT_SQL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/Trolltech/Qt-4.2.0/mkspecs/linux-g++ -I. -I/usr/local/Trolltech/Qt-4.2.0/include/QtCore -I/usr/local/Trolltech/Qt-4.2.0/include/QtCore -I/usr/local/Trolltech/Qt-4.2.0/include/QtGui -I/usr/local/Trolltech/Qt-4.2.0/include/QtGui -I/usr/local/Trolltech/Qt-4.2.0/include/QtSql -I/usr/local/Trolltech/Qt-4.2.0/include/QtSql -I/usr/local/Trolltech/Qt-4.2.0/include -I. -I. -I. -o tableeditor.o tableeditor.cpp
tableeditor.cpp: In constructor ‘TableEditor::TableEditor(const QString&, QWidget*)’:
tableeditor.cpp:178: error: no matching function for call to ‘TableEditor::connect(QList<QComboBox*>&, const char [23], TableEditor* const, const char [17])’
/usr/local/Trolltech/Qt-4.2.0/include/QtCore/qobject.h:181: note: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
/usr/local/Trolltech/Qt-4.2.0/include/QtCore/qobject.h:282: note:                 bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const
make: *** [tableeditor.o] Fehler 1
Danke!
Zuletzt geändert von pumuckl am 8. Januar 2007 21:51, insgesamt 1-mal geändert.
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Du musst auch für jede ComboBox einen Connect einrichten. Der 2. Connect muss also in die while-Schleife.

Code: Alles auswählen

connect(listcbzweck.at(i), SIGNAL(currentIndexChanged()), this, SLOT(clickcombobox())); 
pumuckl
Beiträge: 23
Registriert: 26. November 2006 22:01

Beitrag von pumuckl »

Danke! Ist eigentlich auch logisch! Muss ich heute abend mal ausprobieren. Hätte halt gedacht, die connect-Anweisung muss zur Entwurfszeit festgelegt werden.

Laut deiner Aussage müsste dann doch aber in der Variante 1 die connect-Anweisung

Code: Alles auswählen

connect(listcbzweck.at(0), SIGNAL(currentIndexChanged()), this, SLOT(clickcombobox())); 
funktionieren, oder? - tut Sie aber nicht! Das Programm kompiliert, die Procedure wird aber nicht ausgeführt. Muss ich in der Headerdatei noch was beachten?
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Bringt der connect eine Debugausgabe? Ich arbeite auch öfter mit dynamischen Objekten und connects, allerdings nutze ich dann nicht Objekt.at(i), sondern direkt Objekt.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

macman hat geschrieben:Ich arbeite auch öfter mit dynamischen Objekten und connects, allerdings nutze ich dann nicht Objekt.at(i), sondern direkt Objekt.

Das was du nutzt ist wurscht! QList überlädt den Index-Operator, QList::at( int index) ist eine Alternative. genauso wie du append() und operator<<() zum Anhängen an die Liste verwenden kannst.

Grüße
Franz
pumuckl
Beiträge: 23
Registriert: 26. November 2006 22:01

Beitrag von pumuckl »

In Ordnung! Ich hab es jetzt in die Schleife eingebaut, aber es funktioniert nicht. Der Quelltext wird ohne Probleme kompiliert und das Programm bringt zur Laufzeit auch keine Fehler (hab auch keine Ahnung, wie ich die abfangen könnte).

Ich tippe mal, dass in der Headerdatei eine Deklaration irgendwie nicht 100-% passt, da "QList" unter "privat" nicht deklariert ist!?? Hatte da auch schon verschiedene Varianten, die der Compiler aber alle nicht wollte!

Gruß Pumckl
pumuckl
Beiträge: 23
Registriert: 26. November 2006 22:01

Beitrag von pumuckl »

Ok! Ich probier das jetzt seit 2 h, aber ich krieg das nicht auf die Reihe! Hab auch schon diverse Examples aus dem Assistant studiert, aber mit der dort vorhandenen Syntax haut das einfach nicht hin. Hab den Code in der cpp- und header-Datei nochmal etwas modifiziert:

cpp

Code: Alles auswählen

QList<QComboBox*> listcbzweck;
...
QComboBox *tmpp =  new QComboBox();
connect(tmpp, SIGNAL(currentIndexChanged()), this, SLOT(clickcombobox()));
tmpp->addItem(query.value(1).toString());
listcbzweck.append(tmpp);
header

Code: Alles auswählen

 #ifndef TABLEEDITOR_H
 #define TABLEEDITOR_H

 #include <QDialog>
 #include <QtCore>
 #include <QList>
 
 class QComboBox;
 class QList<QComboBox>;

 class TableEditor : public QDialog
 {
     Q_OBJECT

 public:
     TableEditor(const QString &tableName, QWidget *parent = 0);

 private slots:
     void clickcombobox();

 private:
     QComboBox *tmpp;
     Qlist<QComboBox *> listcbzweck; // steht so in den Examples
 };
 #endif
Obwohl "Qlist<QComboBox *> listcbzweck;" so in den Beispielen des Assistants steht, funktioniert es nicht:

Code: Alles auswählen

tableeditor.h:64: error: ISO C++ forbids declaration of ‘Qlist’ with no type
tableeditor.h:64: error: expected ‘;’ before ‘<’ token
make: *** [main.o] Fehler 1
Hat jemand eine Idee?
pumuckl
Beiträge: 23
Registriert: 26. November 2006 22:01

Beitrag von pumuckl »

In Ordnung! In einsetzender geistiger Umnachtung hab ich den Fehler gefunden!

Code: Alles auswählen

connect(tmpp, SIGNAL(activated(int)), this, SLOT(clickcombobox()));
Das "int" bzw. der zu übergebene Parameter hat gefehlt!!

Also bis zum nächsten Mal! Gute Nacht!
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Das hätte aber zu einer Debug-Ausgabe beim connect führen müssen, "No such signal" oder so ähnlich.
pumuckl
Beiträge: 23
Registriert: 26. November 2006 22:01

Beitrag von pumuckl »

Also beim Kompilieren gab es keinen Fehler und wie ich die Debug- Meldungen abfange, hab ich noch nicht probiert! Muss ich mich noch reinlesen!

Oder kannst du kurz was dazu sagen?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Starte dein Programm in der Konsole (DOSBox oder sonstwie), da werden dann solche Meldungen ausgespuckt.
uhu01
Beiträge: 150
Registriert: 10. Juli 2005 20:46

Beitrag von uhu01 »

Hy!

Damit dieses Fenster kommt, kann man auch einfach

Code: Alles auswählen

CONFIG += console
im pro File eintragen.

Funktioniert meines wissens nach nur unter Windows, da unter Linux die Messages an den Debugger geschickt werden.

mfg
uhu01
pumuckl
Beiträge: 23
Registriert: 26. November 2006 22:01

Beitrag von pumuckl »

"CONFIG += console" bringt auch kein Erfolg! Ich arbeite überwiegend unter Lin, werde es aber auch mal unter Win probieren!

Lt. dem Qt Assistant ist QtDebug zu includen, damit man die Stderr Ausgabe benutzen kann. Das Programm läßt sich aber von der Konsole aus nicht starten ("command not found").

In der Regel debugge ich mit Zwischenausgaben in Komponenten (z.B. QLineEdit). Manchmal sind die Debuggerhinweise aber bestimmt hilfreich bzw. verkürzen die Problemsuche!

Danke für die Hilfe!
Antworten