Segfault przy wywoływaniu QTreeWidgetItem::setSelected()

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:

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:

 
 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.

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ć

0

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


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 :/

1

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

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()

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...

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

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?

0

O jakim reloadzie mowa?

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 :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1