Seite 1 von 1

QListView in QMainWindow: Daten werden nicht angezeigt

Verfasst: 28. April 2009 22:49
von elDietmar
ich hab mit dem QTDesigner ein QMainWindow mit einer *listView:QListView erzeugt.

Weiters hab ich eine Klasse class MyListModel : public QAbstractListModel
als Model für QListView erzeugt.

In der Klasse class MainWindowDemo : public QMainWindow,Ui::MainWindowDemo
habe ich die Attribute:
QStringList numbers;
MyListModel *model;
Im Konstruktor verbinde ich listView mit model, fülle model mit Daten, rufe noch update() für die listView auf:

MainWindowDemo::MainWindowDemo() {
setupUi(this);
model = new MyListModel(numbers);
numbers << "One" << "Two" << "Three" << "Four" << "Five";
listView->setModel(model);
listView->update();
}

Zur Info:
in einer main.cpp erstelle ich app:Application, win:MainWindowDemo, win.show(), app.exec().

Problem:
MainWindow wird mit QListView angezeigt, aber es werden keine Daten in der QListView angezeigt.

------------------------------------------------------------
Alternative: Verwenden Nur QListView im main.cpp, dann werden Daten in QlIStView angezeigt:
main.cpp:
app:Application erzeuge,
MyListModel *model = new MyListModel(numbers);
QStringList numbers << "One" << "Two" << "Three" << "Four" << "Five";
QListView * listView= new QListView();
listView->setModel(model);
listView->show();
---------------------------------------
Weiß wer meine Problemlösung?

lg
Dietmar

Re: QListView in QMainWindow: Daten werden nicht angezeigt

Verfasst: 28. April 2009 23:03
von neuschi
elDietmar hat geschrieben: model = new MyListModel(numbers);
numbers << "One" << "Two" << "Three" << "Four" << "Five";
Vertausche mal die beiden Zeilen, dann müsste es gehen, vorausgesetzt dein MyListModel kopiert die Strings.
Das Problem ist, dass deine QStringList "numbers" zum Zeitpunkt der Anzeige nicht mehr "lebt", wenn du das im Konstruktor machst.
Wenn du das in main() machst ist dieses Objekt noch gültig und daher siehst du die Daten.
(alles als Trockenübung, habe gerade kein Qt verfügbar.)

\Ralf

Verfasst: 28. April 2009 23:19
von elDietmar
hast vollkommen recht !
Es funktioniert.

Danke für prompte Antwort!

Kannst du mir auch beim nächsten Problem helfen:

Ich habe eine Button mit slot-Methode onClicked().
Wenn ich den Button drücke, füge ich Daten zum Model hinzu, die natürlich in der QListView angezeigt werden sollen:
void MainWindowDemo::onclicked()
{
model->add("Six");
listView->update();
}

Refreshed nicht die QListView?!
lg
Dietmar

Verfasst: 28. April 2009 23:30
von neuschi
elDietmar hat geschrieben: Ich habe eine Button mit slot-Methode onClicked().
Wenn ich den Button drücke, füge ich Daten zum Model hinzu, die natürlich in der QListView angezeigt werden sollen:
void MainWindowDemo::onclicked()
{
model->add("Six");
listView->update();
}

Refreshed nicht die QListView?!
Dazu müsste man die Implementierung von "MyListModel::add()" kennen.
Ich empfehle die Lektüre der Qt Doku zum Thema. (insertRow() und Konsorten ) http://doc.trolltech.com/4.5/model-view ... oving-rows

\Ralf

Verfasst: 28. April 2009 23:35
von elDietmar
okay - Danke! Werd dort nachlesen!

Gute Nacht sag ich einmal!

Dietmar

Verfasst: 29. April 2009 00:42
von elDietmar
Hmm, klar ist mir nicht was ich programmiert hab, aber es geht !

Wenn ich den Button druecke, übergebe ich zuerst den neuen Wert, und rufe dann die insertRows Methode auf.

void MainWindowDemo::onclicked()
{
model->add(lineEdit->text().toStdString());
model->insertRow(model->rowCount(), QModelIndex());
}

Im MyListModel hab ich ein neues Attribut für den neuenWert:string, denn ich mit de add(string neuerWert) setze.

Die insertRows Methode hab ich direkt vom Trolltec Link http://doc.trolltech.com/4.5/model-view ... oving-rows, wo ich das Attribut neuerWert erst jetzt zur liste hinzufüge.
-------------
Scheint mir aber ein wenig ums Kreuz ?!
Warum muss ich zuerst die Daten zwischenspeichern mit add(..) und dann erst zur liste hinzufügen mit insertRows(..)?

Welche Rolle das QModelIndex &parent = QModelIndex() hat, versteh ich auch nicht. Sehe ich auch nicht in der Doku!

So jetzt aber Gute Nacht ;)
Dietmar

Verfasst: 29. April 2009 10:47
von neuschi
elDietmar hat geschrieben:

Code: Alles auswählen

   model->add(lineEdit->text().toStdString());
Scheint mir aber ein wenig ums Kreuz ?!
Warum muss ich zuerst die Daten zwischenspeichern mit add(..) und dann erst zur liste hinzufügen mit insertRows(..)?
Wo kommt die Methode add() her? Sie ist kein Bestandteil von QAbstractListModel, muss also aus deinem MyListModel kommen. Diese Methode scheint sich ja um das Hinzufügen von Elementen zum Model zu kümmern, muss das dann also auch per insertRow() etc. machen.


\Ralf

Verfasst: 29. April 2009 21:56
von elDietmar
Hi Ralf,

nur mit dem insertRows(..) kann ich keine Daten übergeben!
Zumindest wüßte ich nicht wie. Weißt Du ob's geht?

Daher hast recht, mit

model->add(lineEdit->text().toStdString());

übergebe ich die Daten an das model:MyListModel.

Allerdings kann ich das insertRows(..) direkt in der add() Methode aufrufen, was wieder Sinn macht, weil das Model der View mitteilen muss, dass sich was hinzugefügt hat.

Daher hab ich jetzt den Aufruf der insertRows() verschoben von...:
void MainWindowDemo::onclicked()
{
model->add(lineEdit->text().toStdString());
}

nach....:
void MyListModel::add(string wert)
{
this->wert =wert;
insertRow(rowCount(), QModelIndex());
}

Besser, nicht war ??? oder hast noch eine bessere Idee?

Weiss aber noch immer nicht was das QModelIndex() bewirkt ??

lg
Dietmar

Verfasst: 29. April 2009 22:58
von upsala
In der Doku gibt es den Punkt: Model/View Programming
Bitte beschäftige dich mal damit.
Hier im Forum gibt es Code-Tags um Codes hervorzuheben.
Und dann gibt es noch Einrückungen, damit man Codeteile besser lesen und verstehen kann.

Verfasst: 29. April 2009 23:26
von elDietmar
Danke für Hinweise:
  1. 1. Doku: hab ich schon durch, doch leider keine Antworten gefunden => daher Forum zur Diskussion ?!
  1. 2.Code tags und Einrückungen: hast recht - ist wirklich besser !!
Frage zurück: hast Du schon mit ListModel gearbeitet?

lg
Dietmar

Verfasst: 30. April 2009 03:16
von CLRS530
Diese "Zurückfrage" ist lächerlich. Willst du ihm jetzt unterstellen er wüsste nicht wie das geht nur weil er dir keine Antwort gibt die du hören möchtest?
Du kannst auch nicht von einer Doku erwarten dir immer genau das zu sagen was du gerade brauchst. Bei dem Model/View Konzept, genauso wie bei dem Signal/Slot Konzept ist es wichtig das Ganze bzw die Funktionsweise zu verstehen.
Was du da fabrizierst und schreibst, zeigt, dass du es schlichtweg gar nicht verstanden hast.
Das model ist da, damit du die ganzen Daten darin managed. insertRows ist hauptsächlich dafür gedacht, um z.B. Drag&Drop implementieren zu können.

Im Grunde hast du es jetzt doch für dich geregelt, also wo ist das Problem. :)
Willst du es "einfacher" haben nimm ListWidget.

Verfasst: 6. Mai 2009 20:18
von elDietmar
So jetzt hab ich die Lösung:

Code: Alles auswählen

   void StringListModel::addData(QString data)
    {
        beginInsertRows(QModelIndex(), stringList.size()-1,
                    stringList.size()-1);

             stringList.insert(stringList.size(),
                     data);

         endInsertRows();
    }
d.h. ich schreibe eine eigene StringListModel::addData(...) Methode in meinem Model, wo ich die übergebenen Daten in meine liste anhänge. Damit die mit diesem Model verknüpfte View upgedatet wird brauche ich nur die beginInsertRows(..) und endInsertRows() Methode aufrufen.

Für die Anzeige (Qt::DisplayRole) muss ich nur die beiden Methoden int StringListModel::rowCount(const QModelIndex &parent) const
und QVariant StringListModel::data(const QModelIndex &index, int role) const überschreiben.

lg
Dietmar