Bilder wechseln, Hintergrundmanipulation

Alles rund um die Programmierung mit Qt
Antworten
Ingeborg
Beiträge: 8
Registriert: 30. Januar 2012 01:32

Bilder wechseln, Hintergrundmanipulation

Beitrag von Ingeborg »

Aloah,

Ich habe folgendes Problem. Ich habe ein kleines GUI geschrieben mit dem ich zwischen Bildern in einem Ordner hin und herschalten möchte. Dies habe ich mit der Signal-Slot funktion wunderbar hinbekommen nur stört mich eins tierisch. Ich habe mal die Slotfunktion für den "vorheriges Bild" Buttonmit eingefügt.

Code: Alles auswählen

    QString qstr = FileName;
    qstr.append(List.at(PicNum).fileName()); // List ist eine QFileInfoList Objekt
    gl_Main->removeWidget(la_View);  // gl_Main ist ein Gridlayout

    image = new QPixmap(qstr);      // Dies ist Teil des Objektes 
    la_View = new QLabel(this);      //  Dies ist Teil des Objektes beides wird einfach überschrieben
    la_View->setPixmap(*image);


    gl_Main->addWidget(la_View, 0, 0, gl_Main->rowCount()-2 ,gl_Main->columnCount(),Qt::AlignCenter);
Mittels der QPixmap Klasse die Member der QLabelklasse ist, habe ich ein Bild eingefügt.Die Dateipfade und Namen sind in der QFileInfoList abgelegt. Diese Pfade sind in Ordnung. Die Symptome sind nun, dass ich zwischen Bildern in einem Ordner hin und herschalten kann und die Bilder angezeigt werden, aber die alten Bilder mit. Dies passiert, wenn das vorherig gewählte Bild größer ist, als das im Moment ausgewählte Bild. Über die Pixelgrenzen des neuen Bildes hinaus, wird das noch das alte Bild sichtbar.In den Grenzen ist das neue zu sehen. Oben in dem Quelltext wird die versuchte Wechsel auf das neue Bild deutlich. Dies geschieht vorrangig durch überschreiben der entsprechenden QLabel und QPixmap klassen.

Kennt jemand das Problem?

Grüße Inge!
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Bilder wechseln, Hintergrundmanipulation

Beitrag von Christian81 »

Du erzeugst zig memory-Leaks und keins davon ist nötig ...

Code: Alles auswählen

image = new QPixmap(qstr); 
Wo löschst Du hier image wieder und warum muss image überhaupt ein Pointer sein?

Code: Alles auswählen

la_View = new QLabel(this);
Wo löschst Du das QLabel wieder und warum muss es überhaupt immer wieder neu angelegt werden?

Es reicht einfach den Pointer auf das QLabel als Member zu halten und diesem mit setPixmap() ein Pixmap zu übergeben. Das Pixmap muss nicht Member der Klasse geschweige denn als Pointer erzeugt werden.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ingeborg
Beiträge: 8
Registriert: 30. Januar 2012 01:32

Re: Bilder wechseln, Hintergrundmanipulation

Beitrag von Ingeborg »

Soweit ich weiß erzeuge ich keine Leaks, da überschreiben von Speicher mit den new Befehlen kein Problem sein sollte. Demnach muss ich letztendlich nur Klassenvariablen im Destruktor sofern das notwendig ist freigeben. Nichtsdestotrotz glaube ich, dass das mit dem genannten Problem nichts zu tun hat. Ich kann auch vll anders fragen. Gibt es noch andere Möglichkeiten als die QLabelklasse, um Bilder anzuzeigen?

Grüße!!
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Bilder wechseln, Hintergrundmanipulation

Beitrag von franzf »

new nimmt sich IMMER neuen Speicher! (Ausnahme: Placement-new, was du nicht machst und das jetzt auch nicht machen sollst!)
Und ads Bild mit new ist tatsächlich völliger Overkill, da du es selber Dereferenzierst und dem Label eine Kopie gibst. Das ist am Ende sogar deutlich langsamer, da new Aufwändig nach ausreichend großem, zusammenhängendem Speicher suchen muss.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Bilder wechseln, Hintergrundmanipulation

Beitrag von Christian81 »

Es gibt nichts einfacherers als QLabel::setPixmap() - wenn man es richtig benutzt so wie ich es gesagt habe...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ingeborg
Beiträge: 8
Registriert: 30. Januar 2012 01:32

Re: Bilder wechseln, Hintergrundmanipulation

Beitrag von Ingeborg »

Hallo Christian!,

danke für deine bisherigen Tipps. Ich habe folgendes gemacht. Ich habe ein paar Bilder in einem Ordner. Dazu schreibe ich eine Qwidget abgeleitet Klasse geschrieben. Unten sieht man den betreffenden Konstruktorausschnitt. Die Bilder-filenamen lade ich mit mittels Klassenfeld mittels der Klasse QFileInfoList und Dialog in den Heap. Ich hoffe ich hab das richtig verstanden. Ich erstelle nun einfach ein Pixmaparray für alle Bilder. und alloziiere ein QLabel-Feld.

Code: Alles auswählen

     List = dir.entryInfoList();
    QPixmap image[List.size()];
    QLabel **la_View = new QLabel*[List.size()];
Weiter lade ich nun per Schleife nun jedes Bild einer Klasse in die entsprechenden Pixmaps und jede Pixmap in das entsrechende QLabel zu.

Code: Alles auswählen

    for(int h = 0; h < List.size(); h++)
    {
        image[h].load( FileName.append(List.at(h).fileName()));
        la_View[h]->setPixmap(image[h]);
    }
Im nächsten Schritt packe ich alle wichtigen Daten in ein gridlayout. Die klappt auch recht wunder bar.

Code: Alles auswählen

    gl_Main->addWidget(pb_Before, 15, 0, 2, 2 );
    gl_Main->addWidget(pb_FullView, 15, 5 ,2 ,2 );
    gl_Main->addWidget(pb_Next, 15, 10, 2, 2 );
    gl_Main->addWidget(la_View[PicNum], 0, 0, gl_Main->rowCount()-2 ,gl_Main->columnCount(),Qt::AlignCenter);

    for(int h = 0; h < 12; h++)
        gl_Main->setColumnStretch(h,(int)round((float)width/12));

    for(int h = 0; h < 16; h++)
        gl_Main->setRowStretch(h,(int)round((float)width/16));
    setLayout(gl_Main);

    connect(pb_Before,SIGNAL(clicked()),this,SLOT(before_tab()));
    connect(pb_Next,SIGNAL(clicked()),this,SLOT(next_tab()));
Der Konstruktor wird über einen anderen Konstruktor in einem Tabwidget aufgerufen und es läuft auch ganz gut. Die Layouts sitzen und das erste Bild erscheint. Mittels zwei der drei Pushbuttons geh ich nun die Qlabels durch, will das eine mit dem anderen ersetzen. Ich gebe dabei mal die eine Slotfunktion durch:

Code: Alles auswählen

gl_Main->removeWidget(la_View[PicNum]);
    if(PicNum == 0)
        PicNum = List.size()-1;
    else
        PicNum--;

gl_Main->addWidget(la_View[PicNum], 0, 0, gl_Main->rowCount()-2 ,gl_Main->columnCount(),Qt::AlignCenter);
PicNum ist die Laufvariable , welches bild im Moment angezeigt wird. und wird bei erreichen von Null oder dem größten Indizee wieder auf Ende oder Anfang gesetzt. Das ist auch nicht so wichtig. Vorher nehme ich das eine QLabel aus dem Gridlayout raus und setze ein neues ein. Leider gibt es in der Laufzeit eine Segmentation Violation. Ich komm hier im moment nicht weiter.

Schöne Grüße und besten Dank im vorraus,

Inge
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Bilder wechseln, Hintergrundmanipulation

Beitrag von Christian81 »

Für Segfaults gibt es wie immer einen Debugger der einem zeigt wo und warum es crasht.
Und wenn wir uns es anschauen sollen dann benötigen wir ein [minimales] kompilierbares Beispiel.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten