Neues Tutorial begonnen ( Advendskalender )

Code-Schnippsel, oder Tipps und Tricks, die einem beim Programmieren mit Qt helfen können.
Antworten
petri253
Beiträge: 6
Registriert: 27. Dezember 2010 21:14
Wohnort: Thüringen

Neues Tutorial begonnen ( Advendskalender )

Beitrag von petri253 » 29. Dezember 2010 19:08

Hallo

ich habe im QTWiki als Diskussionsbeitrag meinen Versuch ein Tutorial zu schreiben eingestellt.

Errreichbar unter

http://www.qtwiki.de/wiki/Benutzer_Diskussion:Petri253

Es ist für Anfänger gedacht ( zu denen ich mich auch zähle ).

Mich interessiert Eure Meinung dazu. ( z.B. braucht das überhaupt jemand )

Danke

Panke
Beiträge: 10
Registriert: 29. Mai 2008 15:44

Beitrag von Panke » 29. Dezember 2010 21:52

Ich habe es eben mal überflogen.

Es fällt mir extrem schwer dieses Tutorial zu lesen. Das hat mehrere Gründe. Zum einen sind Überschriften nicht gut abgesetzt. Die habe ich
teilw. schlicht übersehen. Dann kommt dazu, dass manchmal Code einer Klasse abgesetzt (vorformatierter Text, oder was das ist) dargestellt wird, dann aber public: wieder nicht und so der Code einer Klasse total verstümmelt wird.

Soweit zum Formalen. Inhaltlich finde ich es auch nur so lala. Einmal bin ich nicht der Meinung, dass Screenshots von Entwicklungsumgebungen da nicht reingehören. Ich würde da stärker zw. Qt und dem Qt Creator unterscheiden. Auch finde ich es sehr merkwürdig, dass grundlegende Sachen gar nicht angesprochen werden, aber dann mal irgendwie 24 Buttons irgendwie, irgendwo hingeklatscht werden. Didaktisch meiner Meinung nach unklug.

petri253
Beiträge: 6
Registriert: 27. Dezember 2010 21:14
Wohnort: Thüringen

Re Schwer lesen

Beitrag von petri253 » 30. Dezember 2010 20:55

Mal kurz zu Panke:


Erstmal Danke für die Zeit zum Lesen des 1. Teilentwurfes.


Zum Punkt Überschriften und Markierung Quellcode stimem ich zu. Zur Gliederung mache ich mir zum Schluss Gedanken. Die Markierung des Quellcodes geschah durch den Editor des QT-Wiki automatisch. Da muss ich mal schauen wie es zu ändern geht.

Zu den anderen Punkten:

Ich habe hier aus meinen Erfahrungen bei der Suche nach Lösungen bei der Programmierung mit Qt heraus geschrieben. Sicherlich kann man im jeden Editor schreiben, aber gerade beim Beginn mit der Arbeit einer neuen Entwicklungsumgebung, scheitert man oft an Kleinigkeiten, die für versierte Nutzer selbstverständlich sind.

Zu dem "Hinklatschen der 24 Buttons" weiß ich nicht ob Du da den Beginn ohne Layout gemeint hast oder schon den Punkt, wo die Button in Reihen und Spalten angeordnet sind.

Dann würde mich die bessere Lösung interessieren.

Ich schreibe einfach mal weiter und versuche es zu verbessern.

androphinx
Beiträge: 170
Registriert: 26. Januar 2009 10:19
Wohnort: 127.0.0.2

Re: Re Schwer lesen

Beitrag von androphinx » 3. Januar 2011 17:21

Wunderschönen guten Abend.
petri253 hat geschrieben: Zum Punkt Überschriften und Markierung Quellcode stimem ich zu. Zur Gliederung mache ich mir zum Schluss Gedanken. Die Markierung des Quellcodes geschah durch den Editor des QT-Wiki automatisch. Da muss ich mal schauen wie es zu ändern geht.
http://www.mediawiki.org/wiki/Help:Formatting
petri253 hat geschrieben:Ich habe hier aus meinen Erfahrungen bei der Suche nach Lösungen bei der Programmierung mit Qt heraus geschrieben. Sicherlich kann man im jeden Editor schreiben, aber gerade beim Beginn mit der Arbeit einer neuen Entwicklungsumgebung, scheitert man oft an Kleinigkeiten, die für versierte Nutzer selbstverständlich sind.
Es ist leider so, dass genau das dazu führt, dass dein Tutorial in die falsche Richtung führt. Ich persönlich habe Qt mit Editor und Konsole gelernt. Hat es mir geschadet? Nein. Ich kann heute unter jedem System mit jeder IDE Qt programmieren, weil ich die Backgrounds kenne. Sicherlich ist das schon etwas für Freaks ein Riesenprojekt nur mit Editor und Konsole zu programmieren, aber man sollte zumindest wissen, dass das geht und wie es geht und meiner Meinung nach ist es der beste und einfachste Einstieg in Qt.
petri253 hat geschrieben:Zu dem "Hinklatschen der 24 Buttons" weiß ich nicht ob Du da den Beginn ohne Layout gemeint hast oder schon den Punkt, wo die Button in Reihen und Spalten angeordnet sind.

Dann würde mich die bessere Lösung interessieren.
Ich denke vor allem mal, dass er meinte, dass du von 0 direkt auf 1.000.000 startest. Gehe es ruhiger an. Fang an, indem du erstmal erklärst, was Qt überhaupt ist, wie Qt funktioniert, wie man mit der Doku arbeitet. Fang dann an, eine einfache Anwendung mit einem Label zu programmieren, später kommt noch ein Button dazu, auf dessen Signale man dann reagiert, dann unterhält man sich über Layouts, ... . Alles Schritt für Schritt eben. Du darfst nicht erwarten, dass jeder Mensch gleich bereit ist, ein Riesenprojekt zu programmieren, von dem er nur sehr wenig bis gar nichts versteht. Mach es langsam, erklären kompliziertere Dinge genauer, in einem Tutorial gibt es eigentlich keinen Grund sich kurz zu fassen.

Mfg androphinx

padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh » 8. Januar 2011 02:56

Hmm .. hab mal drübergeschaut.

- du produzierst in deiner main.cpp gleich mal ein Speicherleck :) du machst was mit new, aber nirgends kommt ein delete ... hat nix mit Qt zu tun, eher mit c++
- du hast unnötige Membervariabeln (zB das Layout, du merkst dir den Pointer, brauchst es aber eigentlich nie wieder)
- Warum benutzt du rohe Arrays wenn Qt mit vielen schönen Containern kommt?

Code: Alles auswählen

// statt
QString bildname;
   bildname = (":/Bild")+(QString("%1").arg(j+1));
// lieber
const QString bildname(":/Bild" + QString("%1").arg(j+1) );
// damit erlaubst du dem Compiler Optimierungen bezüglich des Speichers da er nun weiss das bildname sich nicht ändert

Code: Alles auswählen

// statt
            if (j < 8)
            {
                Grid->addWidget(button[j],0,j);
            }
            if ((j > 7) && (j < 16))
            {
                Grid->addWidget(button[j],1,j-8);
            }
            if ((j > 15) && ( j < 24))
            {
                Grid->addWidget(button[j],2,j-16);
            }
// geht auch 
            if (j < 8)
            {
                Grid->addWidget(button[j],0,j);
            } 
            else if (j < 16) 
            {
                Grid->addWidget(button[j],1,j-8);
            } 
            else
            {
                Grid->addWidget(button[j],2,j-16);
            }
// oder einfach so:
            Grid->addWidget(button[j],j/8,j%8);
  /* 
        j Wert      '/8'      '%8'
            0           0         0   
            1           0         1   
            2           0         2   
               und so weiter
            7           0         7   
            8           1         0   
            9           1         1   
           10          1         2   
               und so weiter
           16          2         0   
           17          2         1   
               und so weiter
           23          2         7   
  */
- das Thema fand ich interessant, hab zum Vergleich mal mein Code angehängt. Lizenz: MDWDW


Kritik am eigenen Code:
Die includes werden so nicht gebraucht, sollte man auf die benötigten Header einschränken:

Code: Alles auswählen

//.h
  #include <QtCore/QString>
  #include <QtCore/QMultiMap>
  #include <QtGui/QWidget>[code]
// cpp
#include "adventskalender.h"

#include <QtGui/QGridLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>

#include <QtGui/QImage>
#include <QtGui/QIcon>

#include <QtGui/QMessageBox>
#include <QtGui/QToolButton>
#include <QtCore/QSignalMapper>
#include <QtCore/QDate>[/code]- hab keine Rechtschreibkorrektur drüberlaufen lassen
- hab nur wein Kommentare, keine Doku

Ausbau: statt QString zu verschenken wären QVariants möglich, showGiftForDay() ruft dann nen helper auf der verschiedene QVariants (String, Image, eigene registrierte Metatypes) verschieden anzeigt usw.

Code: Alles auswählen

class AdventsKalender : public QWidget {
// snipp
public slots:
    void addGiftForDay(const int, const QVariant &);

private slots:
    void showGiftForDay(const int);
// snipp

private:
    showGift(const & QVariant);
    QMultiMap<int,QVariant> m_gifts;
// snipp
};

void AdventsKalender::showGift(const & QVariant v)
{
    // pseudo
    if (v.type() == QVariant::dies) zeigeDies(v);
    else if (v.type() == QVariant::das) zeigeDas(v);
    else if (v.type() == QVariant::jenes) zeigeJenes(v);
}

Dateianhänge
screens.png
Mit und ohne Icons
screens.png (70.75 KiB) 10946 mal betrachtet
Advent24.tar.gz
code
(3.16 KiB) 320-mal heruntergeladen
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs

petri253
Beiträge: 6
Registriert: 27. Dezember 2010 21:14
Wohnort: Thüringen

Beitrag von petri253 » 12. Januar 2011 20:34

Danke fürs drüberschauen.

Ein paar Dinge sind für mich noch zu hoch, werde aber versuchen es zu begreifen.

Die Else if Schleife werde ich dann gleich verwenden, dass ist selbst für mich nachvollziehbar logischer.

Eien Frage zu Const bildname habe ich noch. Der Sinn leuchtet mir ein. Das Ziel bei dem Adventskalender soll später mal sein, dass sich der bildname abhängig vom ausgewählten Datum ändern. Da kann ich const doch nicht verwenden oder ??.


Nächste Woche werde ich hoffentlich mehr Zeit haben, mich der bisherigen Hinweise anzunehmen und den Anfang zu überarbeiten.

upsala
Beiträge: 3946
Registriert: 5. Februar 2006 21:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala » 12. Januar 2011 23:01

Else If Schleife
Aus der Wikipedia:
Eine Schleife ist eine Kontrollstruktur in Programmiersprachen. Sie wiederholt einen Anweisungs-Block – den so genannten Schleifenrumpf oder Schleifenkörper – so lange, wie eine Laufbedingung gültig ist oder bis eine Abbruchbedingung eintritt.

padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh » 14. Januar 2011 00:49

petri253 hat geschrieben:Danke fürs drüberschauen.

Eien Frage zu Const bildname habe ich noch. Der Sinn leuchtet mir ein. Das Ziel bei dem Adventskalender soll später mal sein, dass sich der bildname abhängig vom ausgewählten Datum ändern. Da kann ich const doch nicht verwenden oder ??.
Wenn du so ein const meinst:

Code: Alles auswählen

void zeigeBild(const QString & name) { /* ... mache hier was mit name */ }
dann führt das nur dazu, dass in "zeigeBild" der Inhalt von name nicht geändert werden kann. Das & sorgt dafür das der Übergebene Parameter nicht "kopiert" (-> keine Übergabe per Value) sondern "benutzt" (-> Übergabe per Referenz) wird; vergisst du das "const" davor, könntest du den Parameter in der Methode verändern und (da referenz) der übergebene String würde auch geändert.

Das ist mit den meisten Qt Klassen inkl. QString Overkill da kopierte QStrings intern die selbe Referenz benutzen bis einer davon verändert wird (so ne Art smart pointer mit reference count der nur bei Veränderungen wirklich die Daten kopiert) aber ist so eine Angewohnheit - das spart einige Programmzyklen ein. Das sorgt leider manchmal dafür das mir auch ein const int oder sogar const & int unterläuft was dann zT Unsinn ist ....

Edith: grad nochmal drübergeschaut ... du meintest das hier:

Code: Alles auswählen

// statt
QString bildname;
   bildname = (":/Bild")+(QString("%1").arg(j+1));
// lieber
const QString bildname(":/Bild" + QString("%1").arg(j+1) );
// damit erlaubst du dem Compiler Optimierungen bezüglich des Speichers da er nun weiss das bildname sich nicht ändert 
Das heisst das du bildname nach dieser Zeile nicht mehr ändern kannst - was du ja auch garnicht tust, demnach kannst du es const machen und signalisieren das sich das nimmer ändert. Als Beispiel:

Code: Alles auswählen

#include <QDebug>
#include <QDateTime>
int main() {
  QString variablerText("Mein ");
  for (int j=0; j<2; ++j)
  {
    for (int i=0; i < 10; ++i) {
      const QString text(QString("%1").arg(i)); // Geburt von text, den willste nicht ändern
      qDebug() <<  variablerText + text + ". Text";
      // mach noch viele andere Tolle Sachen die text nicht ändern
    } // text "stirbt" hier jedes Mal
  variablerText[0]='D'; // das ginge mit text nicht, da const...
  }
}
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs

pfid
Beiträge: 535
Registriert: 22. Februar 2008 17:59

Beitrag von pfid » 14. Januar 2011 11:23

padreigh hat geschrieben: - du produzierst in deiner main.cpp gleich mal ein Speicherleck :) du machst was mit new, aber nirgends kommt ein delete ... hat nix mit Qt zu tun, eher mit c++

Naja, dann ruf main() halt nicht so oft auf ;)

padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh » 14. Januar 2011 19:34

pfid hat geschrieben: Naja, dann ruf main() halt nicht so oft auf ;)
Einmal reicht, der Rest reparented sich automatisch also wird fast nix abgeräumt ... aber sehr konstruktiv, dein Hinweis :P
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs

pfid
Beiträge: 535
Registriert: 22. Februar 2008 17:59

Beitrag von pfid » 16. Januar 2011 15:18

Das in main erstellte Objekt wird dort nicht mehr gelöscht, also erst beim Beenden der Applikation weggeräumt. Wo ist der Leak?

padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh » 16. Januar 2011 23:58

Wenn du so argumentierst ... dann brauchste NIE deletes da beim Beenden der Application das OS eh alles abräumt . . .
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs

pfid
Beiträge: 535
Registriert: 22. Februar 2008 17:59

Beitrag von pfid » 17. Januar 2011 09:23

padreigh hat geschrieben:Wenn du so argumentierst ... dann brauchste NIE deletes da beim Beenden der Application das OS eh alles abräumt . . .
Ich sehe, du hast meinen Witz mit dem mehrmals main aufrufen verstanden :)
Wenn man wie hier in der main nur einmal pro Laufzeit Speicher holt (z. B. eingelesene Konfigdatei in einem statischen/globalen Speicherbereich), kann man sich das delete in meinen Augen auch schenken, bzw. es passiert nichts wenn mans weg lässt. Dass ein delete pro new sauberer ist mal außer acht gelassen.

Deletes sind natürlich dann ganz essentiell wichtig, wenn der Speicher an einer Stelle allokiert, dann aber nicht mehr freigegeben wird, und diese Stelle mehrmals durchlaufen wird (= Speicherverbrauch wächst) - logisch.

upsala
Beiträge: 3946
Registriert: 5. Februar 2006 21:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala » 17. Januar 2011 10:07

Wer kein delete aufruft, ruft auch keine Destruktor auf.

D.h. es kann passieren, daß Einstellungen nicht zurückgeschrieben werden, Dateipuffer nicht zurückgeschrieben werden, Netzwerkports nicht freigegeben werden...

Antworten