Segfault przy wywoływaniu QTreeWidgetItem::setSelected()

Segfault przy wywoływaniu QTreeWidgetItem::setSelected()
several
  • Rejestracja:prawie 16 lat
  • Ostatnio:około 13 godzin
0

Zrobiłem widget bazując na przykładzie DOM Bookmarsk http://doc.qt.nokia.com/latest/xml-dombookmarks.html. Dodałem funkcjonalność dzięki której mogę przesuwać elementy drzewa w górę i w dół bez ponownego zaznaczania elementu:

Kopiuj
void MyTree::MoveItemDown()
{
    QDomElement elem;
    if(!currentElMarked.isNull()){
         elem=CurrentItemMarked();
    }
    else{
        return;
    }

    QDomNode parent=elem.parentNode();

    parent.insertAfter(elem,elem.nextSibling());
    Refresh();
    
    currentElMarked.clear();
    treeModified=1;

    emit itemClicked(domElementForItem.key(elem),0);

} 

Przesuwanie w górę wygląda bardzo analogicznie. Ale chciałbym żeby przesuwany element był zaznaczony, jednak jeśli dodam na końcu tej metody:

Kopiuj
 
 domElementForItem.key(elem)->setSelected(true);

dostaję segfaulta. To samo jak próbuję użyć QTreeWidget::scrollToItem() razem z QTreeWidget::setCurrentItem(). Nie wiem zupełnie czemu tak się dzieje.


MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:2 dni
  • Lokalizacja:Warszawa
  • Postów:1454
0

Spróbuj uzyć QItemSelectionModelu Bracie.Wprawdzie on bardziej do używania z widokami opartymi na modelach jest przeznaczony,ale i z takimi opartymi na widgetach powinien działać


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
several
  • Rejestracja:prawie 16 lat
  • Ostatnio:około 13 godzin
0

Hmm, dodałem taki kod do slotu przyjmujący sygnał itemClicked() (ten który jest emitowany gdy przesuniemy element) :

Kopiuj

QItemSelectionModel *selection = new QItemSelectionModel(this->model());
QModelIndex index;
index=this->model()->index(this->indexOfTopLevelItem(item),column,QModelIndex());
selection->select(index,QItemSelectionModel::Select);
this->setSelectionModel(selection); 

Segfaulta nie ma ale gałąź w drzewie po przesunięciu raz pozostaje zaznaczona a razie nie :/


MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:2 dni
  • Lokalizacja:Warszawa
  • Postów:1454
1

E,nie tak.Te selection modele wyłuskuje się z widoku:

Kopiuj
QItemSelectionModel *sm=twój_widok->selectionModel();

Następnie używasz funkcji QItemSelectionModel::selectedIndexes() dostaniesz listę zaznaczonych itemów-z tego co mówisz powinien być tylko jeden.Następnie nieco więcej zabawy cię czeka,bo musisz sprawdzać czy są QModelIndexy mające tego samego parenta(czyli leżące w tej samej gałęzi) w zależności od tego,czy chcesz iść w dół czy w górę-a jak nie ma to znaleźć gałąź do której chcesz przejść,ewentualnie rozwinąć ją,i zaznaczyć 1 albo ostatni indeks znajdujący się w niej.
A to zaznaczanie itemów robisz poprzez sm->select()


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 3x, ostatnio: MasterBLB
several
  • Rejestracja:prawie 16 lat
  • Ostatnio:około 13 godzin
0

Hmm, tylko że ja nie używam żadnego widoku, w sensie żadnej klasy Q...View. Dziedziczę sobie QTreeWidget i to wszystko. Damn it nie sądziłem że zaznaczenie elementu w drzewie z poziomu kodu jest takie pokrętne...


MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:2 dni
  • Lokalizacja:Warszawa
  • Postów:1454
1

Ehhhh Bracie...a weź obacz sobie w assistancie,po czym dziedziczy QTreeWidget ;) a jeszcze lepiej,zapodaj w link 'List of all members, including inherited members' i tam pokukaj :P


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
several
  • Rejestracja:prawie 16 lat
  • Ostatnio:około 13 godzin
0

Hmm racja racja, mój błąd. Tylko hmm...jak sobie pobiorę zaznaczony index to po reloadzie ten index jest już dla mnie bezużyteczny (tak wnioskuję po działaniu qDebuga). Także zapewne będę musiał zmodyfikować funkcję Refresh() i w niej jakoś uwzględnić informację który element w drzewie zaznaczyć na starcie?


MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:2 dni
  • Lokalizacja:Warszawa
  • Postów:1454
0

O jakim reloadzie mowa?


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
several
  • Rejestracja:prawie 16 lat
  • Ostatnio:około 13 godzin
0

TreeWidget jest tworzony na podstawie obiektu QDomDocument (jedna z klas do obsługi XML). Jak zmieniam coś w domDocument (przesuwam w góre/w dół, dodaję elementy) muszę potem zaktualizować TreeWidget odpowiednio parsując domDocument. Odbywa się to tak, że czyszczę wszystko w TreeWidget i tworzę wszystko na nowo. W kodzie z tytułowego postu odpowiedzialna jest za to funkcja Refresh(), także wygląda na to że to w niej muszę pogrzebać jeśli chce zaznaczyć jakiś element w drzewie.

edit
Zszedłem niżej, do wcześniej napisanych funkcji parsujących domElement. Wystarczyło wcześniej zapamiętać nazwę elementu dla którego odpowiadający mu TreeWidgetItem ma zostać zaznaczony i oznaczyć go setSelected(true) zaraz po stworzeniu. Najprostsze rozwiązanie najlepsze.
@MasterBLB dziękuję za uświadomienie mi pewnych zależności i mechanizmów w Qt, Twoje podpowiedzi rozwiązały mój problem w innym module :)


edytowany 1x, ostatnio: several

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.