Refresh einer TreeView

Alles rund um die Programmierung mit Qt
D_ron
Beiträge: 38
Registriert: 24. Juli 2007 11:53
Wohnort: Karlsruhe
Kontaktdaten:

Refresh einer TreeView

Beitrag von D_ron »

Hallo allerseits,

ich habe eine TreeView die Daten aus einer Quelle ausliest. Nun habe ich eine Toolbar integriert die ein Refresh dieser Ansicht durchführen (sprich alle Daten neu einlesen) soll nur klappt das nicht richtig... :(

Hier zu habe ich folgenden Code innerhalb meiner Refresh-Funktion:

Code: Alles auswählen

setUpdatesEnabled(false);
QList<QVariant> rootData; 
rootData << "Content";
TreeItem *rootItem = new TreeItem(rootData);
model.setupModelData(rootItem); //liest Daten neu ein.
setUpdatesEndabled(true);
Folgenden Effekt habe ich beim Drücken auf den Refresh()-Button:
keinen

Kann mir jemand sagen was ich falsch mache?

Vielen Dank für deine Unterstützung!
code404
Beiträge: 7
Registriert: 9. August 2007 12:44

Beitrag von code404 »

hy,

aktualisierst du auch deine View? Das ändern des Models reicht leider nicht aus! Du musst der View mitteilen das neue Daten vorhanden sind! Also:

Code: Alles auswählen

ui.treeView->setModel(&model);
Korgen
Beiträge: 42
Registriert: 28. März 2006 16:37

Beitrag von Korgen »

Hi,
erzeugt denn deine setupModelData( QVariant ) auch ein dataChanged Signal? Was für ein Model verwendest du denn?
Mir fehlen irgendwie die QModelIndex und die damit verbundene model->setData( myIndex, myData );
Mantus
Beiträge: 19
Registriert: 6. November 2007 00:30

Beitrag von Mantus »

ich hab wie in einem anderen thread schon beschrieben, ein ähnliches Problem.
ich hab auch am ende meiner funktion die im model die daten verändert ein "emit datachanged..." nur mit welchem slot des Views muss ich das verbinden ? oder wird das automatisch verbunden wenn ich setmodel ausführe ? denn aus irgendeinem grund hab ich zwar alle daten im model, aber mein view zeigt mir immer nur die header info an :/
Korgen
Beiträge: 42
Registriert: 28. März 2006 16:37

Beitrag von Korgen »

Hi,
Das kommt ganz darauf an, wie du das in deiner View Klasse implementiert hast. Erbt deine View von QAbstractItemView(sollte sie ja eigentlich) und hast du die setModel( QAbstractItemModel* ) NICHT überschrieben, dann wird darin das dataChanged Signal des Models mit dem dataChanged() Slot der View verbunden.
Mantus
Beiträge: 19
Registriert: 6. November 2007 00:30

Beitrag von Mantus »

also mein view ist eine std. QTableView

also ca. so:
QTableView *table
MyModel *model
model = new MyModel(this) (von QAbstractTableModel)
table->setModel(model);

im model gibts dann irgendwie
void setMsg(data){
.......
......
emit dataChanged(createIndex(0,0), createIndex(entry.size()-1, 4));
}

aber in meinem Table seh ich immer nur den header und sonst nichts.

danke schonmal im vorhinein für jedem tip
Korgen
Beiträge: 42
Registriert: 28. März 2006 16:37

Beitrag von Korgen »

hast du vorher auch ein insertRow an deinem Model gemacht?
Mantus
Beiträge: 19
Registriert: 6. November 2007 00:30

Beitrag von Mantus »

ich dachte da mein model read only ist muss ich das nicht ? okay daran wirds wohl liegen :/

muss ich das nur "aufrufen" oder überschreiben ?
also bis jetzt schaut mein model so aus

Code: Alles auswählen

	int CANMsgTableModel::rowCount(const QModelIndex& idx = QModelIndex())const {      return CANMsgEntrys.size();}
	int CANMsgTableModel::columnCount(const QModelIndex& idx = QModelIndex())const {   return 6;}

CANMsgTableModel::CANMsgTableModel(QObject* parent) : QAbstractTableModel(parent) 
{
}

CANMsgTableModel::~CANMsgTableModel()
{
}

Qt::ItemFlags CANMsgTableModel::flags(const QModelIndex& index) const
{
   return Qt::ItemIsEnabled;
}

QVariant CANMsgTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
   if ( role != Qt::DisplayRole )
      return QVariant();
   switch (section) {
      case 0:   return QString("TimeStamp");
      case 1:	return QString("Can Dev");
      case 2:   return QString("Type");
      case 3:   return QString("ID");
      case 4:   return QString("length");
      case 5:   return QString("Can Msg");
      default: return  QVariant();
   }
} 

QVariant CANMsgTableModel::data(const QModelIndex& index, int role) const
{
	CANMsg cm;
	cm = CANMsgEntrys.at(index.row());
	
	if ( role != Qt::DisplayRole )
		return QVariant();
	switch (index.column()) {
      	case 0:   return QString("%1").arg(cm.timestamp);
      	case 1:	  return QString("CAN");
      	case 2:   return QString("Type");
      	case 3:   return QString("ID");
      	case 4:   return QString("length");
      	case 5:   return QString("Can Msg");
      	default: return  QVariant();
	}
}

void CANMsgTableModel::insertCANMsg(CANMsg& canMsg){
	CANMsgEntrys.append(canMsg);
	
	std::cerr<<"Node:"<<CANMsgEntrys.at(CANMsgEntrys.size()-1).node<<
			" TimeStamp:" << CANMsgEntrys.at(CANMsgEntrys.size()-1).timestamp <<
			" Msg:" << CANMsgEntrys.at(CANMsgEntrys.size()-1).msg<<
			" CAN ID:" << CANMsgEntrys.at(CANMsgEntrys.size()-1).id << "\n";
	
	emit dataChanged(createIndex(0,0), createIndex(CANMsgEntrys.size()-1, 4));
}
wenn ich hier instert Row benutzten muss, was muss ich da als "index" eintragen ?
wär echt dankbar wenn ihr mir sagen könnt wo ich den fehler mach :/
Korgen
Beiträge: 42
Registriert: 28. März 2006 16:37

Beitrag von Korgen »

Ich bin mir nicht sicher, ob QAbstractTableModel die richtige Baseclass für deine Verwendung ist (schau dir doch auch mal QAbstractListModel an). In einem TableModel werden 2dimensionale Daten (Zeile/Spalte) gespeichert, aber deine Speicherstruktur CANMsgEntrys sieht mir wie eine Liste oder ähnliches eindimensionales aus, oder?

Zum Thema "readOnly". Bei einem Model, das readOnly ist, heißt das nur, dass der User, die Daten, die im Model stehen nicht ändern kann. Wenn das komplette Model von anfang an readonly wäre, wie willst du denn dann Daten reinbekommen.
Die InsertRow Methode rufst du mit der Zeilennummer auf, vor die du deine neue Zeile einfügen willst. Prinzipiell ist ein insertRow( 0 ) bestimmt nicht verkehrt.
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

bitte keine doppelposts.. sonst wird's mühsam...
Mantus
Beiträge: 19
Registriert: 6. November 2007 00:30

Beitrag von Mantus »

ich dacht table is das richtige, da die msg objekte zwar eine sind, aber jedes objekt 6 eigenschaften hat die angezeigt werden sollen.

btw mit dem "read only" hab ich mich einfach an die vorgaben des trolltech model/view beispiels gehalten, dort staht das für modele die nicht editiert werden, das überschreiben dieser funktionen ausreicht.
die daten kommen ja über meine selbstgeschriebene funktion ins model, sonst soll da niemand was einfügen können.

btw braucht insertRow nicht 2 parameter ? row und Index ?
Korgen
Beiträge: 42
Registriert: 28. März 2006 16:37

Beitrag von Korgen »

Hej,
1. ok, dann passt ein TableModel. :-)

2. nee, der zweite Parameter ist optional, siehe Doku:

http://doc.trolltech.com/4.3/qabstracti ... #insertRow
Mantus
Beiträge: 19
Registriert: 6. November 2007 00:30

Beitrag von Mantus »

Danke erstmal für die hilfe soweit :)

aber es will noch immer nicht :/
mein code für die selbstgebastelte insert funktion schaut jetzt wie folgt aus:

Code: Alles auswählen

void CANMsgTableModel::insertCANMsg(CANMsg& canMsg){
   CANMsgEntrys.append(canMsg);
  this->insertRow(0);
   emit dataChanged(createIndex(0,0), createIndex(CANMsgEntrys.size()-1, 4));
} 
aber an der optik meines tables ändert sich noch immer nichts :/

ehrlich gesagt versteh ich nicht ganz wozu insertRow aufgerufen wird, die anzahl der rows im model werden ja direkt aus meiner Liste an MsgObjects ausgelesen ? irgendwie blick ich durch dieses model view konzept von QT nicht wirklich durch.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

1. Habe ich dir deine fehlenden Funktionen schon mal aufgelistet
2. Gibt es in der Doku den Abschnitt Createing New Models, in dem das ganze Thema anhand eines Beispiels ausführlich erklärt wird.
Mantus
Beiträge: 19
Registriert: 6. November 2007 00:30

Beitrag von Mantus »

eben das finde ich bei deinem link sehr verwirrden

1. gehts um ein list model
2. steht insert und remove Row unter dem topic "creating editable models" .... ich will nicht das der user das model editieren kann.
3. steht in dieser anleitung ebenfalls nichts von den funktionen die du im anderen thread angeführt hast.

das read only example aus deinem link z.b. verfügt nur über folgende funktionen

Code: Alles auswählen

     int rowCount(const QModelIndex &parent = QModelIndex()) const;
     QVariant data(const QModelIndex &index, int role) const;
     QVariant headerData(int section, Qt::Orientation orientation,
                         int role = Qt::DisplayRole) const;
die habe ich alle implementiert, aber wir wird genau 0 angezeigt ausser dem header .... mag sein das es für dich alles logisch und einfach ist, aber mir hilft dieses tutorial genau 0 weiter, wenn ich nämlich das mache was in dem tutorial gesagt wird stehe ich genau dort wo ich jetzt bin, ich sehen einen header und nicht mehr.
ebenfalls im weiterführenden tutorial stehen unter "readonly model" wieder nur 5 funktionen, die ich alle implementiert habe, aber keine veränderung im verhalten.

hab jetzt noch versucht in meine handgestrickte insert methode begininsertrows und endinsertrows einzubauen, weil ja diese angeblich dafür verantwortlich sind das die view benachrichtigt wird, bringt aber auch nix :/
auch das implementieren von "insertRows" bringt 0
Antworten