Anzeige:
Ergebnis 1 bis 15 von 15

Thema: Mehrere QLineedits auswerten

  1. #1
    Registrierter Benutzer
    Registriert seit
    02.04.2003
    Beiträge
    43

    Mehrere QLineedits auswerten

    moin

    Ich mache grade meine ersten Gehversuche mit QT und hab auch schön brav die Suche benutzt .

    folgendes Problem:

    ich habe 16 QLineedits und möchte diese Werte einlesen, summieren und anschließend den Mittelwert bilden. Das ganze mache ich zu Fuß für jedes QLineedit einzeln. Jetzt mein Frage, ob das ganze eventuell mittels Schleife einfacher zu bewerkstelligen wäre.

    hier mal ein kleiner Code-Ausschnitt

    Code:
    void QtNoten::slotBMittelClicked()
    {
    	int i=0, summe=0;
    	
    	summe+=atoi(m_lineEdit1->text());
    	if(m_lineEdit1->isModified()) i++;
    			
    	summe+=atoi(m_lineEdit2->text());
    	if(m_lineEdit2->isModified()) i++;
    		
    	summe+=atoi(m_lineEdit3->text());
    	if(m_lineEdit3->isModified()) i++;
    
    .....
    Schon mal vielen Dank für nen Denkanstoss


    Gruß HL

  2. #2
    Registrierter Benutzer
    Registriert seit
    25.12.1999
    Ort
    Stuttgart
    Beiträge
    259
    Hi,

    sollte sich mit einem Array bewerkstelligen lassen :

    Code:
    class QNoten
    {
    ...
    private:
    
      QLineEdit *m_lineEdit[16];
    };
    Code:
    void QtNoten::slotBMittelClicked()
    {
            int i=0, summe=0;
            
    	for (int j=0; j < 16; j++) {
            	summe+=atoi(m_lineEdit[j]->text());
            	if(m_lineEdit[j]->isModified()) i++;
    	}
    }
    Gruß
    micha
    IRC: irc.euirc.net #tux

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.04.2003
    Beiträge
    43
    Hi,

    Original geschrieben von micha
    Hi,

    sollte sich mit einem Array bewerkstelligen lassen :

    Gruß
    micha
    Daran hatte ich auch schon gedacht. Allerdings hab ich die Gui mit dem QT Designer erstellt und ich bin mir nicht ganz sicher, ob ich in den von qmake daraus erstellten dateien einfach *rumpfuschen* kann.


    Ich werde das heute Abend einfach mal testen.



    Gruß HL

  4. #4
    Registrierter Benutzer
    Registriert seit
    11.03.2004
    Beiträge
    40
    Einen gewissen Aufwand wirst du hier nicht vermeiden können, da es keinen "einfachen" Weg gibt eine Variable (etwa i) in einen Variablennamen (etwa m_lineEdit) einzubinden.

    Um aber diesen Aufwand möglichs gering zu halten kannst du Listen oder eben Arrays benutzen. Ich würde hier vermutlich eine QPtrList nehmen, das wäre wohl das einfachste. Sieht dann wie folgt aus:

    Code:
    QPtrList<QLineEdit> lineEditList;
    lineEditList.append(m_lineEdit1);
    lineEditList.append(m_lineEdit2);
    lineEditList.append(m_lineEdit3);
    lineEditList.append(m_lineEdit4);
    [...]
    lineEditList.append(m_lineEdit16);
    Und jetzt ist der Verwaltungsaufwand soweit abgeschlossen und du kannst alles weitere elegant in Schleifen machen:

    Code:
    int summe = 0;
    QPtrListIterator<QLineEdit> it(lineEditList);
    while (it.current()) {
      QLineEdit* lineEdit = it.current();
      ++it; // nicht vergessen!! sonst hast du eine Endlosschleife!!
            
      bool ok;
      summe += m_lineEdit1->text().toInt(&ok);
      if (!ok) {
        printf("Im lineEdit stand keine Integer Zahl!! Summe ist ungültig!!\n");
      }
    }
    Die Sache mit dem &ok kannst du weglassen, aber dann hast du keine Fehlerprüfung.

    CU
    Andi

  5. #5
    Registrierter Benutzer
    Registriert seit
    02.04.2003
    Beiträge
    43
    hi bmann

    danke für den tip mit der liste, das spart schon mal ne menge tipparbeit. allerdings hatte sich ein kleiner fehler eingeschlichen. hat ne weile gedauert bis ich rausgefunden hatte, das er immer nur den ersten wert aufaddiert .

    Code:
    	     QPtrListIterator<QLineEdit> it(lineEditList);
    	while (it.current()) {
      		QLineEdit* lineEdit = it.current();
     	        ++it; 
      		bool ok;
      		summe += lineEdit->text().toInt(&ok); //hier war dir ein m_lineEdit1 reingerutscht
      		if (ok) {
        		    i++;
      		}
    	}
    danke nochmal für den tip.

    ps: den tip mit dem vector werde ich bei gelegenheit auch nochmal testen


    Gruß HL
    Geändert von HangLoose (27-04-2004 um 18:46 Uhr)

  6. #6
    Registrierter Benutzer
    Registriert seit
    02.04.2003
    Beiträge
    43
    moin moin

    ich hab noch ein kleines problem beim laden des files, in denen ich die werte gespeichert habe. und ich komme einfach nicht drauf, wo mein fehler liegt.

    Code:
           char c;
    	char temp[5];
    	QPtrList<QLineEdit> lineEditList;
    	lineEditList.append(m_lineEdit1);
    	lineEditList.append(m_lineEdit2);
           ....
           QLineEdit* ptrlineEdit;
    	ptrlineEdit = lineEditList.first();
    	std::ifstream datei("/Users/HL/Desktop/noten.txt");
    	
    	for(int i=0; datei.get(c); i++, ptrlineEdit = lineEditList.next()){
    		if(c!='\n')
    			temp[i]=c;
    		else{
    			temp[i]='\0';
    			ptrlineEdit->setText(temp);  <== hier stürzt das programm ab
    		}
    	}
    ich habe das ganze mal durch den debugger gejagt und in der markierten zeile, steigt das programm aus.

    Program received signal EXC_BAD_ACCESS, Could not access memory


    Gruß HL

  7. #7
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Du prüfts vor dem Pointerzugriff auch nicht ab, ob der Pointer ungleich 0 ist, bzw, hast keine Abbruchbedingung bei dem Zugriff auf temp[i] , was ist wenn i >= 5 ist?

    Vielleicht kannst du kurz Beschreiben, wie die Datei aussieht, vielleicht gibts eine elegantere Methode

    ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  8. #8
    Registrierter Benutzer
    Registriert seit
    02.04.2003
    Beiträge
    43
    hi

    Vielleicht kannst du kurz Beschreiben, wie die Datei aussieht, vielleicht gibts eine elegantere Methode
    die gibt es mit sicherheit, bin noch nicht so fit in c++

    also die datei enthält nur 10 zweistellige zahlen, die untereinander stehen.

    96
    92
    84
    .
    .
    .


    [B]Du prüfts vor dem Pointerzugriff auch nicht ab, ob der Pointer ungleich 0 ist, bzw, hast keine Abbruchbedingung bei dem Zugriff auf temp[i] , was ist wenn i >= 5 ist?
    *argh* ja klar, i wieder auf null zu setzen hab ich ja ganz vergessen


    Code:
            for(int i=0; datei.get(c); i++, ptrlineEdit = lineEditList.next()){
    		if(c!='\n')
    			temp[i]=c;
    		else{
    			temp[i]='\0';
    			i=0;
    			ptrlineEdit->setText(temp);
    	}

    ich bin natürlich an einer eleganteren lösung interessiert .


    ps: bei der gelegenheit mal nen danke schön an dich und tuxipuxi für euer qt tutorial


    Gruß HL

  9. #9
    Registrierter Benutzer
    Registriert seit
    11.03.2004
    Beiträge
    40
    Also ich gehe mal davon aus dass du jeweils eine Zeile in ein lineedit schreiben willst?
    Also wenn ich mich nicht irre sind da ein paar üble Fallen in deinem Code.
    Zum einen ist es i.A. sehr hässlich zwei Anweisungen am Ende der for Zeile zu haben (wie heisst diese Stelle eigentlich??), also ich meine das hier:
    Code:
      for(int i=0; datei.get(c); i++, ptrlineEdit = lineEditList.next()){
    Das wäre so m.E. besser, z.B. leichter zu debuggen:
    Code:
      for(int i=0; datei.get(c); i++){
          [...] // dein Code
          ptrlineEdit = lineEditList.next();
      }
    In der for Zeile sollte man meistens nur den eigentlichen Iterator erhöhen, sonst kommt man schnell durcheinander.
    Damit sieht man jetzt vor allem ein Problem:
    Du liest die Datei Zeichen für Zeichen aus, nach jedem Zeichen wird ptrlineEdit auf das nächste Element in der Liste gesetzt. Du hast 10 Zeilen mit jeweils 3 Zeichen (zweistellige Zahl + \n), du brauchst also mindestens 30 lineedits damit das funktioniert.

    Ich denke du solltest hier ausserdem besser die Qt Klassen für das Einlesen der Datei benutzen. Die sind schlicht und ergreifend intuitiver zu benutzen und sehr viel komfortabler. Das sähe hier dann so aus (ungetesteter Code!!)
    Code:
    QPtrList<QLineEdit> lineEditList;
    lineEditList.append(m_lineEdit1);
    lineEditList.append(m_lineEdit2);
    ...
    QFile file("/Users/HL/Desktop/noten.txt");
    if (!file.open(IO_ReadOnly)) {
       printf("Konnte Datei %s nicht öffnen\n", file.name());
    }
    
    QStringList lines;
    while (!file.atEnd()) {
        char buffer[255];
        file.readLine(buffer, 255);
        lines.append(QString(buffer));
    }
    
    for (int i = 0; i < lineEditList.count(); i++) {
        if (i >= lines.count()) {
            printf("Datei hatte weniger Zeilen als erwartet!\n");
            break;
        }
        QLineEdit* edit = lineEditList.at(i); // kann nie NULL sein, da i >= 0 und i < lineEditList.count(). Ansonsten sollte man jetzt auf NULL überprüfen
        edit->setText(lines[i]);
    }
    Dieser Code liest also erst die gesamte Datei (zeilenweise) ein und setzt die Zeilen in eine QStringList. Mit dieser lässt es sich jetzt komfortabel arbeiten, was in der darauffolgenden Schleife geschieht.
    Insbesondere hängt die Anzahl der Durchläufe der 2. Schleife vor allem von der Anzahl der lineedits in deinem Programm ab, nicht nur von der Zahl der Zeichen (Zeilen, etc.) in der Datei (was zu einem Crash wegen NULL pointer führen würde).

    CU
    Andi

  10. #10
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zeilenweise Lesen ohne Längenbeschränkung geht noch besser mit QTextStream::readLine()

    lines[i] ist nicht so empfohlen, wenn man über die ganze Liste iteriert, denn operator[int] benutzte at(int) und das ist O(n), braucht also für jedes Element lineare Zeit.

    Besser einen QStringList::iterator benutzen.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  11. #11
    Registrierter Benutzer
    Registriert seit
    02.04.2003
    Beiträge
    43
    hi bmann

    deinen code muss ich erstmal sacken lassen .

    in der zwischenzeit war ich aber auch nicht faul und hab es auch hinbekommen.

    Code:
            ptrlineEdit=lineEditList.first();
    	QFile file("/home/rip/Desktop/noten.txt");
    	QTextStream ts( &file );
    	QString line;
    
    	file.open( IO_ReadOnly );
            while ( !ts.atEnd() ) {
        	        line = ts.readLine();
    		ptrlineEdit->setText(line);
    		ptrlineEdit = lineEditList.next();
    	}
    	file.close();
    was noch fehlt ist die abfrage, ob das file auch ordnungsgemäß geöffnet werden konnte und woran ich bisher gar nicht gedacht habe

    Insbesondere hängt die Anzahl der Durchläufe der 2. Schleife vor allem von der Anzahl der lineedits in deinem Programm ab, nicht nur von der Zahl der Zeichen (Zeilen, etc.) in der Datei (was zu einem Crash wegen NULL pointer führen würde).
    da werde ich mich wohl noch mal bei machen. seht ihr neben diesen 2 punkten noch weitere schwachstellen?

    @anda_skoa

    Zeilenweise Lesen ohne Längenbeschränkung geht noch besser mit QTextStream::readLine()

    lines[i] ist nicht so empfohlen, wenn man über die ganze Liste iteriert, denn operator[int] benutzte at(int) und das ist O(n), braucht also für jedes Element lineare Zeit.

    Besser einen QStringList::iterator benutzen.
    hm, hab ich es jetzt richtig gemacht? bin mir nicht ganz sicher


    Gruß HL

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

    was noch fehlt ist die abfrage, ob das file auch ordnungsgemäß geöffnet werden konnte und woran ich bisher gar nicht gedacht habe
    Code:
    if (!file.open(IO_ReadOnly)
    {
        // Fehlermeldung, etc
        return;
    }

    hm, hab ich es jetzt richtig gemacht? bin mir nicht ganz sicher
    Ja, gute Lösung.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  13. #13
    Registrierter Benutzer
    Registriert seit
    11.03.2004
    Beiträge
    40
    @anda_skoa:
    lines[i] ist nicht so empfohlen, wenn man über die ganze Liste iteriert, denn operator[int] benutzte at(int) und das ist O(n), braucht also für jedes Element lineare Zeit.

    Besser einen QStringList::iterator benutzen.
    Das ist zwar einerseits richtig, aber andererseits habe ich mich in diesem Fall ganz bewustt für eine Lösung mit QStringList:perator[] (und daher QValueList:perator[]) entschieden. Es geht hier um eine Liste mit genau 10 Elementen, der Unterschied zwischen O(n) und O(1) ist praktisch nicht existent. Zudem soll diese Liste nur einmal durchlaufen werden. Anders sähe es natürlich aus wenn der Code mehr al 1000 mal pro Sekunde ablaufen müsste, aber dem ist nunmal nicht so.
    Daher habe ich mich dafür entschieden eine Lösung vorzuschlagen die mit weniger Iterator Objekten auskommt und dafür besser zu lesen ist.

    Ich halte nicht allzu viel davon Code unnötig kompliziert zu machen, wenn es auch einfach geht - Iteration anhand von Integer werten, sowie lines[i] sind intuitiv verständlich, ++it und (*it) dagegen nicht, man muss sich da zunächst einarbeiten.
    Diesen Aufwand halte ich bei einer 10 Elementigen Liste jedoch nicht für gerechtfertigt.

    CU
    Andi

  14. #14
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Mein Einwurf war auch mehr als eine Anmerkung gedacht, denn natürlich ist die Lösung mit dem Operator schöner zu lesen.

    Die Problematik mit dem Operator bei QStringList ist auch eher dokumentations technisch, weil man eben leicht den zurghörigen Kommentar in der QValueList Doku übersehen kann.

    Spreche da aus eigener Erfahrung, hab lange mit dem Operator auf Element zugegriffen, unter der Annahme, dass er sich wie ein Array oder Vector Operator verhält, oder zumindest wie bei QPtrList O(1) auf das nächste Element hat.

    @HangLoose:
    Hab letzten übersehen, dass du bei deiner Lösung noch den Pointer kontrollieren musst.
    Am Besten in der Schleifenbedingung, !ts.atEnd() && !pointer == 0

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  15. #15
    Registrierter Benutzer
    Registriert seit
    02.04.2003
    Beiträge
    43
    Original geschrieben von anda_skoa
    @HangLoose:
    Hab letzten übersehen, dass du bei deiner Lösung noch den Pointer kontrollieren musst.
    Am Besten in der Schleifenbedingung, !ts.atEnd() && !pointer == 0

    Ciao,
    _
    thx, werde ich noch reinbasteln.


    Gruß HL

Lesezeichen

Berechtigungen

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