Seite 1 von 1

Neues Tutorial begonnen ( Advendskalender )

Verfasst: 29. Dezember 2010 19:08
von petri253
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

Verfasst: 29. Dezember 2010 21:52
von Panke
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.

Re Schwer lesen

Verfasst: 30. Dezember 2010 20:55
von petri253
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.

Re: Re Schwer lesen

Verfasst: 3. Januar 2011 17:21
von androphinx
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

Verfasst: 8. Januar 2011 02:56
von padreigh
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);
}


Verfasst: 12. Januar 2011 20:34
von petri253
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.

Verfasst: 12. Januar 2011 23:01
von upsala
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.

Verfasst: 14. Januar 2011 00:49
von padreigh
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...
  }
}

Verfasst: 14. Januar 2011 11:23
von pfid
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 ;)

Verfasst: 14. Januar 2011 19:34
von padreigh
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

Verfasst: 16. Januar 2011 15:18
von pfid
Das in main erstellte Objekt wird dort nicht mehr gelöscht, also erst beim Beenden der Applikation weggeräumt. Wo ist der Leak?

Verfasst: 16. Januar 2011 23:58
von padreigh
Wenn du so argumentierst ... dann brauchste NIE deletes da beim Beenden der Application das OS eh alles abräumt . . .

Verfasst: 17. Januar 2011 09:23
von pfid
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.

Verfasst: 17. Januar 2011 10:07
von upsala
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...