[gelöst] Optimierung Item-Suche im QTreeWidget
Verfasst: 13. August 2010 09:59
Guten Morgen,
möchte meinen Einstieg schon gleich mit 2 Problemen feiern
ich benutze QT open source SDK in Version 4.6.3 (Package 2010.04) zusammen mit Eclipse Helios Release und QT Eclipse Integration v1.6.1
dies ist mein Einstieg in ein großes Projekt in c++ und QT, deswegen gibts auch noch ein paar grundlegende Probleme
hab mich schon bißchen in das signal / slot Verhalten eingelesen und jetzt nach knappen 3 Wochen auch schon bißchen was zusammen bekommen, aber manchmal zwickt es noch
also, genug geschwafelt, kommen wir zu den Punkten
ich bilde in einer QGraphicsView Polygone ab, die von der Datenhaltung her gruppiert sein können in Segmente und mehrere Segmente wiederum in Layern.
Nun zeichne ich beim Auslesen meiner Polygone alle in das QGraphicsView, was auch soweit schon funktioniert. Gleichzeitig werden alle Polygone nach oben genannter Hierarchie in das TreeWidget eingefügt, Layer ist TopItem, Segment ist Child von Layer und Polygon Child von Segment. In Spalte 1 steht der Name des Objekts und in Spalte 2 eine Checkbox, mit der ich die Sichtbarkeit der einzelnen toggeln kann (also entweder kompletter Layer, kompl. Segment oder einzelnes Polygon weg)
dazu hab ich die stateChanged Methode überschrieben und such mir hierin wieder mein Objekt, das ausgewählt wurde.
Meine Lösung funktioniert zwar, allerdings scheint es mir immer noch zu kompliziert gedacht. Was meint ihr ?
Layer, Segments und Polygone sind QVector von eigenen Datenklassen, die ich angelegt hab.
so, nächste Baustelle hierbei ist, dass ich die QGraphicsView bzw. die darin enthaltene QGraphicsScene passend zu dem Inhalt, den ich reinzeichne der Größe anpassen will, das ganze sollte weich geschehen, momentan funktioniert es bei mir anhand des überschriebenen MouseReleaseEvent mit einem festen Schwellenwert für das SceneRect, was in ziemlichem Gezappel endet, weil die Scene auf einen Schlag riesig wird.
Hier mal noch mein momentaner Ansatz, auch wenn es ziemlich billig ist
außerdem fehlt mir noch bißchen Umgang mit der QGraphicsView, ich brauch für meine Zwecke noch eine Zoomfunktion (das geht wohl über den MouseWheelHändler, je nach Up / Down dann halt rein- / rauszoomen), außerdem noch zoomen in einen Bereich (Rectangle), den ich vorher mit gehaltener Maus-Taste o.ä. auswähle und vielleicht noch zoomen auf ein Objekt durch Doppelklick darauf, aber die anderen Punkte wären wichtiger 
danke
möchte meinen Einstieg schon gleich mit 2 Problemen feiern
ich benutze QT open source SDK in Version 4.6.3 (Package 2010.04) zusammen mit Eclipse Helios Release und QT Eclipse Integration v1.6.1
dies ist mein Einstieg in ein großes Projekt in c++ und QT, deswegen gibts auch noch ein paar grundlegende Probleme
hab mich schon bißchen in das signal / slot Verhalten eingelesen und jetzt nach knappen 3 Wochen auch schon bißchen was zusammen bekommen, aber manchmal zwickt es noch
also, genug geschwafelt, kommen wir zu den Punkten
ich bilde in einer QGraphicsView Polygone ab, die von der Datenhaltung her gruppiert sein können in Segmente und mehrere Segmente wiederum in Layern.
Nun zeichne ich beim Auslesen meiner Polygone alle in das QGraphicsView, was auch soweit schon funktioniert. Gleichzeitig werden alle Polygone nach oben genannter Hierarchie in das TreeWidget eingefügt, Layer ist TopItem, Segment ist Child von Layer und Polygon Child von Segment. In Spalte 1 steht der Name des Objekts und in Spalte 2 eine Checkbox, mit der ich die Sichtbarkeit der einzelnen toggeln kann (also entweder kompletter Layer, kompl. Segment oder einzelnes Polygon weg)
dazu hab ich die stateChanged Methode überschrieben und such mir hierin wieder mein Objekt, das ausgewählt wurde.
Meine Lösung funktioniert zwar, allerdings scheint es mir immer noch zu kompliziert gedacht. Was meint ihr ?
Layer, Segments und Polygone sind QVector von eigenen Datenklassen, die ich angelegt hab.
Code: Alles auswählen
// react on toggling the visibility checkbox within the treeWidget
void PolyCreater::stateChanged(int signal)
{
// detect the selected checkbox
QCheckBox *cb = qobject_cast<QCheckBox *>( sender() );
// index of the selected layer (either as directly chosen or as parent node
// of the chosen polygon or segment)
int selectedLayerIndex = -1;
// index of the selected segment (either as directly chosen or as parent node
// of the chosen polygon)
int selectedSegmentIndex = -1;
// index of the selected polygon
int selectedPolygonIndex = -1;
// item for the selected item of the treewidget
QTreeWidgetItem *selectedItem;
// if the checkbox could be detected
if (cb)
{
// choose the selected item
selectedItem = ui.treeWidget->itemAt(cb->pos());
// check if the selected item is on top level (which means it is a layer)
selectedLayerIndex = ui.treeWidget->indexOfTopLevelItem(selectedItem);
// if it is a layer
if (-1 != selectedLayerIndex)
{
// change the layers visibility
polyHelper->layers[selectedLayerIndex].isVisible = (signal == Qt::Checked);
// and repaint the polygons
paintAllPolygons();
}
// otherwise
else
{
// if it is not a layer
if (-1 == selectedLayerIndex)
{
// check if the parent node of the selected item is a layer
selectedLayerIndex = ui.treeWidget->indexOfTopLevelItem(selectedItem->parent());
// if the parent node is a layer
if (-1 != selectedLayerIndex)
{
// then search within for the selected child (which means it is a segment)
selectedSegmentIndex = ui.treeWidget->topLevelItem(selectedLayerIndex)->indexOfChild(selectedItem);
// if the selected item is a segment
if (-1 != selectedSegmentIndex)
{
// change the segments visibility
polyHelper->layers[selectedLayerIndex].segments[selectedSegmentIndex].isVisible = (signal == Qt::Checked);
// and repaint the polygons
paintAllPolygons();
}
}
// otherwise
else
{
// if the parent node is not a layer (which means the parent node has to be a segment in a 3 subsequent node structure)
if (-1 == selectedLayerIndex)
{
// detect the layer index through the parent of the parent (which means the parent of the selected item is a segment
// and the parent of the segment is the layer)
selectedLayerIndex = ui.treeWidget->indexOfTopLevelItem(selectedItem->parent()->parent());
// detect the segment index within the above selected layer through the parent of selected item (which means the
// parent is a segment)
selectedSegmentIndex = ui.treeWidget->topLevelItem(selectedLayerIndex)->indexOfChild(selectedItem->parent());
// search within the selected layer and segment for the selected polygon
selectedPolygonIndex = ui.treeWidget->topLevelItem(selectedLayerIndex)->child(selectedSegmentIndex)->indexOfChild(selectedItem);
// if the polygon could be found (which is the last chance, because the who emitted the stateChanged event was not found
// within the upper layer and segment childs)
if (-1 != selectedPolygonIndex)
{
// change the polygons visibility
polyHelper->layers[selectedLayerIndex].segments[selectedSegmentIndex].polygons[selectedPolygonIndex].isVisible = (signal == Qt::Checked);
// and repaint the polygons
paintAllPolygons();
}
}
}
}
}
}
}Hier mal noch mein momentaner Ansatz, auch wenn es ziemlich billig ist
Code: Alles auswählen
void myQGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
QRect maxRect = QRect(-20, -20, 2000, 1500);
QRect sceneRect = (scene()->sceneRect()).toRect();
if (maxRect.contains(sceneRect, TRUE))
{
fitInView(scene()->sceneRect(), Qt::KeepAspectRatio);
}
else
{
scene()->setSceneRect(maxRect);
fitInView(scene()->sceneRect(), Qt::KeepAspectRatio);
}
QGraphicsView::mouseReleaseEvent(event);
}danke