Seite 1 von 1
QTreeWidget - neues Item einfügen?
Verfasst: 25. Februar 2010 14:29
von Angerfist
hi,
ich versuche grade mit QTreeWidget und XML-Files etwas zu experimentieren. Dabei wird ein XML-File eingelesen und entsprechend angezeigt. Löschen, Öffnen und Speichern klappt einwandfrei (ok,ist mit qt doku und examples auch nicht allzu schwer

)
jetzt versuche ich jedoch, neue Einträge hinzuzufügen und da scheitert es dann. ich weiß jetzt nicht direkt, wie ich das erklären soll, ohne den ganzen code zu posten, aber ich versuchs mal:
ich habe eine mainwindow.cpp+.h, eine ioall.cpp+.h und eine addnew.cpp+.h. In der Klasse mainwindow wird u.a. das TreeWidget erzeugt. Auch wird von dort aus die Klasse addnew aufgerufen, da diese das Eingabefenster "modelliert" und die Eingaben in das TreeWidget einfügen soll.
Doch an der Stelle:
Code: Alles auswählen
QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
item->setText(0, name2);
treeWidget->addTopLevelItem(item);
QTreeWidgetItem *addItem = new QTreeWidgetItem(item);
addItem->setText(0, tr("Vorname"));
addItem->setText(1, vorname2);
item->addChild(addItem);
(1.Zeile)
stürzt das Prog dann ab, debuggen ergibt einen Segmentation Fault und beim weiteren Durchschauen der Debugger-Ausgaben einen PointerError, sprich, der weiß nicht, wo er den kram reinschreiben soll. Und ich ehrlich gesagt nicht, wie ich ihm beibiegen soll, dass er das treeWidget aus dem mainwindow nehmen soll. In allen Headerfiles ist das TreeWidget public deklariert.
Beispiele im Netz und in Büchern behandeln zwar das Thema, allerdings fügen die ihre Sachen immer in der gleichen Klasse zu :/
Wäre echt nett, wenn jemand nen tipp geben könnte..
Verfasst: 25. Februar 2010 14:42
von archer
Kann es sein, das du das addItem zweimal hinzufügst?
Nummer 1: QTreeWidgetItem *addItem = new QTreeWidgetItem(item);
Nummer 2: item->addChild(addItem);
Ist das so gewollt von dir?
Verfasst: 25. Februar 2010 15:48
von Angerfist
Code: Alles auswählen
QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
item->setText(0, name2);
treeWidget->addTopLevelItem(item);
Hier wird ein Item erzeugt im treeWidget (also soll, wird ja nicht)
dieses Item "item" erhält dann in Spalte 0 den String aus name2, danach wird das als toplevelitem in den treewidget gepflanzt.
Code: Alles auswählen
QTreeWidgetItem *addItem = new QTreeWidgetItem(item);
addItem->setText(0, tr("Vorname"));
addItem->setText(1, vorname2);
item->addChild(addItem);
hier wird ein neues item additem erzeugt im treewidget unter item. rest s.o. also eig. sind das schon zwei verschiedene items?
p.s. also weiter unten gibts nur noch additem3-6, das sind jeweils unterschiedliche. und er stürzt ja auch schon ab bei dem new QTreeWidgetItem(treeWidget), weil ich da wohl irgendwas falsch deklariert hab, aber ich weiß halt nicht was und wo

Verfasst: 25. Februar 2010 15:55
von franzf
QTreeWidgetItem::QTreeWidgetItem ( QTreeWidget * parent, int type = Type )
Constructs a tree widget item of the specified type and appends it to the items in the given parent.
Das war gemeint!
addChild//addTopLevelItem zusätzlich ausführen ist doppelt gemoppelt, sollte aber mMn. nicht zu dem Crash führen. Ich nehme an es liegt am Code davor. Kannst du da mal mehr Posten?
Verfasst: 25. Februar 2010 16:00
von archer
Ich nehme mal an, dass der code nicht in der selben Klasse ist wie dein eigentliches QTreeWidget.
Was ist denn eigentlich treeWidget?
Ich hoffe treeWidget ist ein Zeiger auf dein QTreeWidget!!
Verfasst: 25. Februar 2010 16:08
von Angerfist
also davor deklarier ich nur die strings a la:
und in der mainwindow klasse wird das so aufgerufen:
Code: Alles auswählen
void MainWindow::newContact()
{
addnew aDialog;
aDialog.exec();
}
im konstruktor wird das so aufgerufen:
Code: Alles auswählen
treeWidget = new QTreeWidget;
setCentralWidget(treeWidget);
treeWidget ist in allen Klassen public deklariert.
hier wird in der io klasse ein xml eingelesen und ins treewidget eingefügt:
Code: Alles auswählen
QTreeWidgetItem *childItem;
if(item)
{
childItem = new QTreeWidgetItem(item);
}
else
{
childItem = new QTreeWidgetItem(treeWidget);
}
childItem->setData(0, Qt::UserRole, xml.name().toString());
return childItem;
hier weiß er ja auch welches treewidget er nehmen soll??
@franz: leider hab ich jetzt nicht ganz verstanden was du mir damit sagen möchtest. das erste element soll ein nachname sein und danach "klappen" dann weitere angaben auf, also die weiteren angaben sollen sozusagen die childs von dem topitem da werden.
@archer: jap, treewidget ist ein QTreeWidget, deklariert als Zeiger (*treeWidget). in der mainwindow wird der tree erzeugt, nur meine add klasse kann darauf nicht zugreifen und genau das ist mein problem.. weil ich ja son eingabefenster erzeuge und das wollte ich in eine andere klasse auslagern.
Verfasst: 25. Februar 2010 16:19
von franzf
Angerfist hat geschrieben:@franz: leider hab ich jetzt nicht ganz verstanden was du mir damit sagen möchtest. das erste element soll ein nachname sein und danach "klappen" dann weitere angaben auf, also die weiteren angaben sollen sozusagen die childs von dem topitem da werden.
Code: Alles auswählen
QTreeWidget* tree = new QTreeWidget;
QTreeWidgetItem* item = new QTreeWidgetItem(tree);
tree->addTopLevelItem(item); // überflüssig, wenn nicht sogar die Urasache deines Problems
ist doppelt gemoppelt! Der von dir gewählte Konstruktor fügt das item bereits als topLevelItem ein!
Verfasst: 25. Februar 2010 16:32
von Angerfist
ah ok, thx.. hab das mal auskommentiert, ändert aber leider nichts.. bleibt wieder an der stelle:
Code: Alles auswählen
QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
hängen.
Verfasst: 25. Februar 2010 16:53
von franzf
Kannst du mal bitte ein kompilierbares Minimalbeispiel posten, das dein Problem zeigt (also keinen Code, der funktioniert), samt der Klassen die involviert sind. So wie ich das verstehe ist das treeWidget ein Member deiner MainWindow-Klasse, welches du von einem Dialog aus verändern willst, richtig? Bitte diese Klassenstruktur in dem Beispiel 1:1 wiedergeben!
Verfasst: 25. Februar 2010 17:15
von Angerfist
ja genau das möchte ich erreichen..

...
hab jetzt mal die sachen rausgenommen die keine rolle spielen dürften. die ioall klasse dürfte auch nicht betroffen sein, da gehts nur um das einlesen und exportieren der xml files. (beispiel xml file liegt bei)
addnew ist die klasse mit dem hinzufügen dialog, in der mainwindow wird der tree erzeugt und in der funktion newContact wird das eben aufgerufen.
Verfasst: 25. Februar 2010 17:49
von franzf
Dir ist schon bewusst, dass addnew::treeWidget nicht initialisiert ist? Das verursacht den SegFault!
Code: Alles auswählen
void MainWindow::newContact()
{
addnew aDialog;
aDialog.treeWidget = treeWidget;
aDialog.exec();
treeWidget->sortItems(0, Qt::AscendingOrder);
}
behebt das
Überleg dir, ob das wirklich so klug ist, den treeWidget über den Dialog gleich zu verändern.
Besser ist es dem Dialog für jeden String nen getter zu verpassen. Wenn der Dialog zugeht (hier bitte die Doku lesen wie das mit QDialog::Accepted ist!) erstellst du QMainWindow::addContact das neue TreeWIdgetItem mit den gettern des dialogs. Das ist der übliche Weg.
Verfasst: 25. Februar 2010 17:59
von Angerfist
boar, VIELEN VIELEN DANK!!!!!
sowas banales.. aber das kommt davon, wenn man einfach son thema vor den latz geknallt bekommt und dann "mach mal"..dann kommt man auf die einfachsten Dinge nicht...
aber es klappt. selbst wenn das nicht die "feine" art zu programmieren ist, es läuft.. und jetzt hat mir auch mal einer gesagt, wie ich sowas klassenübergreifend machen kann =)
Verfasst: 26. Februar 2010 14:37
von Angerfist
mhm.. liegt das jetzt an der art und weise wie die sachen eingefügt werden oder wieso erscheinen die beim exportieren in ein xml file nicht? ich krieg hier gleich nen koller >.<
exportiert wird mit der funktion:
Code: Alles auswählen
xml.setDevice(device);
xml.writeStartDocument();
xml.writeStartElement("xml");
xml.writeAttribute("version", "1.0");
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i)
writeItem(treeWidget->topLevelItem(i));
xml.writeEndDocument();
return true;
exportiert werden nur die, die er eingelesen hat.. oO [/code]
edit:
nein,natürlich nicht^^ das klappt deshalb nicht, weil die neuen Einträge keine "Data"-Komponenten haben, an hand derer exportier ich aber die Items, da muss man also mit
herumexperimentieren, damit das wieder passt.[/quote]