[gelöst] Zugriff auf QStringList zwischen zwei Klassen

Alles rund um die Programmierung mit Qt
Antworten
Thomas
Beiträge: 45
Registriert: 9. September 2005 16:26

[gelöst] Zugriff auf QStringList zwischen zwei Klassen

Beitrag von Thomas »

Hallo,

ich habe in meiner Klasse eine private QStringList Variable, dich ich mit Einträgen fülle:

Header:
...
class ProjectDialog : public QDialog
{
Q_OBJECT

public:
ProjectDialog(QWidget *parent = 0);
~ProjectDialog() {};

void setImageList(QStringList *list) {strImageList = list;}
QStringList* getImageList() {return strImageList;}
...
private:
Ui::ProjectDialog ui;
ModelDialog *modelDial;

QStringList *strImageList;
QListWidgetItem *listItem;
...
};


Cpp:
...

void ProjectDialog::on_ModelButton_clicked()
// call model definition dialog
{
strImageList = new QStringList;
listItem = new QListWidgetItem;
int number = ui.imageList->count();

for(int i = 0; i < number; i++)
{
listItem = ui.imageList->item(i);
imageName = listItem->text();
strImageList->append(imageName);
}

modelDial = new ModelDialog(this);
modelDial->exec();
}
...

Das Füllen der strImageList mit Einträgen funtioniert. Ich habe es überprüft. Nun möchte ich aus einer anderen Klasse über die Zugriffsfunktion getImageList() auf die QStringListe zugreifen:

Header:

#ifndef MODELDIALOG_H
#define MODELDIALOG_H

#include "ui_modeldialog.h"

class ProjectDialog;
class QListWidgetItem;

class ModelDialog : public QDialog
{
Q_OBJECT

public:
ModelDialog(QWidget *parent = 0);
~ModelDialog() {};

void setList(QStringList *list) {strList = list;}
QStringList* getList() {return strList;}

private:
Ui::ModelDialog ui;

ProjectDialog *projDial;
QStringList *strList;
QStringList *strModelList;
};
#endif

Cpp:
#include <QtGui>

#include "modeldialog.h"
#include "projectdialog.h"

ModelDialog::ModelDialog(QWidget *parent) : QDialog(parent)
{
ui.setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);

projDial = new ProjectDialog(this);
strList = new QStringList;

strList = projDial->getImageList();

for (int i = 0; i < strList->size(); ++i)
{
new QListWidgetItem(strList->at(i), ui.imageList);

}
}

Der Zugriff auf die Liste scheint zu funktionieren, wobei jedoch eine leere strList-Variable entsteht. Wenn ich mit strList->count() die Anzahl der Einträge prüfe, ergibt sich als Ergebnis 0. Dem enstprechend bricht das Programm beim Durchlaufen der For-Schleife zusammen.

Kann mir jemand einen Tipp geben, wo mein Fehler liegt? Danke!

Thomas
FlorianBecker
Beiträge: 1213
Registriert: 2. Dezember 2004 10:54
Kontaktdaten:

Beitrag von FlorianBecker »

Benutze die StringListen als Referenzen und nicht als Pointer.
ArneStocker
Beiträge: 300
Registriert: 3. November 2004 16:15
Wohnort: Berlin

Beitrag von ArneStocker »

Hi

nutze doch bitte {code} {/code} (nur mit eckigen Klammern, das kann doch keiner lesen)

zur Frage:
wenn ich es richtig verstehe willst Du die Member - Stringlist einer Klasse in die Member - Stringlist einer anderen Klasse kopieren. Wenn ich Deinen Code richtig lese übergibst Du einen Zeiger auf die Memberklasse.

Code: Alles auswählen

    void setImageList(QStringList *list) {strImageList = list;}
    QStringList* getImageList() {return strImageList;} 
das sieht so aus, als würdest Du nur den Pointer auf die Stringlist kopieren, während die Stringlist offensichtlich nicht auf dem Stack sondern auf dem heap erzeugt wird. Wenn Du (wovon ich ausgehe) die Stringlist in einer Klasse im Destruktor wieder abgebaut hast, bekommst Du einen ungültige Pointer.

warum nimmst Due nicht eine Stringlist als Member statt eines Pointers auf eine Stringlist und kopierst sie dann

Code: Alles auswählen

class ...
{
   QStringList m_stringlist;
   void SetImageList(const QStringList &list) {m_stringlist = list;}
   QStringList GetImageList() {return m_stringList;}
}
Gruss Arne
Thomas
Beiträge: 45
Registriert: 9. September 2005 16:26

Beitrag von Thomas »

Hallo,

ich habe beide Wege probiert, erhalte jedoch das gleiche Ergebnis. Wenn ich die Größe der übergebenen Liste teste, erhalte ich als Ergebnis 0. Die Liste scheint leer zu sein, obwohl sie in der Ausgangsklasse 6 Einträge enthält.

Code: Alles auswählen

ModelDialog::ModelDialog(QWidget *parent) : QDialog(parent)          
{
    ui.setupUi(this);    
    setAttribute(Qt::WA_DeleteOnClose);
    
    projDial = new ProjectDialog(this);
 //   strList = new QStringList;
    
    setList(projDial->getImageList());  
    
    int t = strList.count();
    QString s = QString::number(t);
    QMessageBox::warning(this, tr("I-MET"), s);                         
    
    for (int i = 0; i < strList.size(); ++i)
    {
        new QListWidgetItem(strList.at(i), ui.imageList);
       
    }   
}
Thomas
ArneStocker
Beiträge: 300
Registriert: 3. November 2004 16:15
Wohnort: Berlin

Beitrag von ArneStocker »

das sieht i.O. aus. Allerdings sieht man ja immer nur Ausschnitte, ... poste doch mal die betreffenden Methoden und den Konstruktor komplett als *.cpp Files als attachment

Gruss Arne
Thomas
Beiträge: 45
Registriert: 9. September 2005 16:26

Beitrag von Thomas »

... habe die Dateien angehängt

Gruß

Thomas
Thomas
Beiträge: 45
Registriert: 9. September 2005 16:26

Beitrag von Thomas »

...neuer Versuch. Nun hat es mit anhängen hoffentlich geklappt.

Gruß

Thomas
Dateianhänge
code.zip
(2.94 KiB) 174-mal heruntergeladen
ArneStocker
Beiträge: 300
Registriert: 3. November 2004 16:15
Wohnort: Berlin

Beitrag von ArneStocker »

Code: Alles auswählen

QStringList& getImageList() {return strImageList;}
damit gibst Du eine Referenz auf die Member Stringlist einer Fremden Klasse zurück, von der Du nicht weisst, wie lange die gültig ist. Versuch doch mal folgendes :

Code: Alles auswählen

QStringList getImageList() {return strImageList;}
dann wird die StringLIst nämlich kopiert

Gruss Arne
Thomas
Beiträge: 45
Registriert: 9. September 2005 16:26

Beitrag von Thomas »

Hallo,

irgendwie blicke ich die Sache im Moment nicht mehr ganz. Wenn ich die Liste im Konstruktor mit einem normalen String (z.B. "Test") fülle, kann ich sie problemlos mit Inhalt kopieren und in der anderen Klasse darauf zugreifen.

Fülle ich sie aber in einer Methode bzw. in einem Slot lässt sich der Inhalt nicht kopieren, egal ob ich mit Referenzen, Zeiger oder einer normalen Membervariable arbeite. Beim Zugriff auf die Liste aus der anderen Klasse heraus, erhalte ich eine leere Kopie. Im folgenden ein Beispiel für einen Slot in dem die Liste strImageList gefüllt wird.

Code: Alles auswählen


void ProjectDialog::on_ImageBrowseButton_clicked()
{    
    QString suffix;         
    QDir directory = QFileDialog::getExistingDirectory(this,
                                    tr("QFileDialog::getExistingDirectory()"),
                                    ".", QFileDialog::DontResolveSymlinks
                                    | QFileDialog::ShowDirsOnly);

    if (directory.exists())
    {
        ui.ImageEdit->setText(directory.path());
                
        directory.setFilter(QDir::Files);
        QFileInfoList list = directory.entryInfoList();
        
        for (int i = 0; i < list.size(); ++i) {
            QFileInfo fileInfo = list.at(i);
            
            suffix = fileInfo.completeSuffix();
            int x = QString::localeAwareCompare(suffix, "jpg");    
            if (x == 0)
            {
                imageName = fileInfo.fileName(); 
                strImageList.append(imageName);

                new QListWidgetItem(imageName, ui.imageList);                
            }
        }
    } 
    else
        QMessageBox::warning(this, tr("I-MET"),
                                    tr("Cannot find image directory %1.")
                                    .arg(directory.dirName()));
                                    
    imageName = "";
}
Gibt es dafür irgendeine logische Erklärung oder habe ich in der Doku eine besondere Eigenschaft dieser Liste überlesen?

Gruß

Thomas
ArneStocker
Beiträge: 300
Registriert: 3. November 2004 16:15
Wohnort: Berlin

Beitrag von ArneStocker »

Das neue Beispiel hast Du gegenüber dem ursprünglichen Code abgeändert.

Normalerweise 'vergisst' ein QStringList objekts nichts und es ist auch egal, in welcher Methode oder welchem Ereignis es gefüllt wird (es sei denn es handelt sich um einen unbekannten Bug in Qt4.x, was ich so nicht glauben mag).

Bist Du Dir sicher, dass Du immer mit den gleichen Instanzen von ProjektDialog arbeitest ? Ich blick in Deinem Code nicht mehr richtig durch, wann Du für welche Klasse ein neues Objekt erzeugst.

In dem ursprünglichen Code hast Du ein ProjektDialog Objekt im Konstruktor von ModelDialog dynamisch erzeugt und unmittelbar danach ausgelesen. Da passierte (bezogen auf die stringImageList) nicht viel. Die musste also leer sein.

Mir fällt dazu nichts ein, außer dass Du mal einen Index (als Member) für jede Instanz von ProjektDialog hochzählst und im Debugger (oder durch einen output) prüfst, ob Du wirklich das gleiche Objekt ausliest, dessen Slot aufgerufen wurde.

Gruss Arne
Goos
Beiträge: 360
Registriert: 17. August 2004 10:10
Wohnort: Black Forest

Beitrag von Goos »

Thomas hat geschrieben:irgendwie blicke ich die Sache im Moment nicht mehr ganz. Wenn ich die Liste im Konstruktor mit einem normalen String (z.B. "Test") fülle, kann ich sie problemlos mit Inhalt kopieren und in der anderen Klasse darauf zugreifen.
Oehmmm ja, du bist dir schon sicher, dass du Deine Liste auch ERST per Button fuellst und dann zurueckgibst?
Irgendwie schaut mir das auf den ersten Blick nicht so aus.
Die Benamung in Deinem Code ist uebrigens schlecht lesbar :)

Goos
Thomas
Beiträge: 45
Registriert: 9. September 2005 16:26

Beitrag von Thomas »

Hallo,

das Problem hat sich erledigt. Der Tipp mit den verschiedenen Instanzen von ProjektDialog war richtig. Ich habe mit zwei Instanzen gearbeitet und deshalb immer eine leere Liste erhalten. Danke für die Hilfe!

Gruß

Thomas
Antworten