Problem z zastosowaniem własnego modelu

0

Witam, może zacznę od kodu :

class StringListModel : public QAbstractListModel
{
   Q_OBJECT
public:
    StringListModel(const QStringList strings,QObject *parent =0) : QAbstractListModel(
            parent) {stringList = strings;}
    int rowCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index,int role) const;
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;

private:
    QStringList stringList;

}; 

Klasę i implementację metod utworzyłem na wzór tej z dokumentacji Qt, problem w tym że nie umiem jej poprawnie zastosować. Oto kod programu:

QListView listView;
    QStringList * strList = new QStringList;
    StringListModel myModel(*strList);
    listView.setModel(myModel);
    listView.show(); 

Błąd kompilatora:
undefined reference to `vtable for StringListModel'

Probowałem już na różne sposoby, nie mogę jednak sobie z tym poradzić, dopiero uczę się Qt i C++. Będę bardzo wdzięczny za pomoc, z góry dziękuję za odpowiedzi, pozdrawiam!

1

Czy aby na pewno używasz moc?

Tzn. musisz przebudować projekt tak, aby qmake (czy czego tam używasz) odpalił moc.

1

Czy aby na pewno używasz moc?

use the moc, Luke ;-) problemem może być po prostu brak wywołania qmake przed make, by odświeżyć listę klas.

1

1.Ustawienie modelu nie będącego wskaźnikiem winno wyglądać tak:

view.setModel(&model);

jazda do dokumentacji funkcji QAbstractItemView::setModel i przeczytać
2.Tworzysz model lokalnie na stosie,po wyjściu z prawdopodobnie konstruktora szlag go trafia.Zatem albo zaalokuj na stercie operatorem new,albo niech ten model będzie składnikiem klasy w której jest funkcja z kodem co pokazałeś

Tak poza tym,budujesz widzę model na pustej QStringLiście...co zatem ma ci się pokazać w widoku?I wewnątrz modelu lepiej chyba wskaźnik na nią przechowywać a nie robić kopię w konstruktorze

0

Dzięki Panowie!
Problem rzecz jasna w moc.

MasterBLB, lista nie jest pusta , nie wklejałem całego kodu, wiedziałem że problem nie w dodawaniu do QStringList nowych elementów. Co do ustawienia modelu to racja, tak oczywiście robię, dopisywałem to do posta ręcznie nie wklejając kodu i o tym zapomniałem. To tylko eksperymenty, gdyż chcę sobie utworzyć w moim programie coś w rodzaju listy użytkowników.W QListView będą wyświetlane ich nazwy, natomiast ja muszę znać index zaznaczonego elementu. Z tego co sobie wyczytałem w internecie, muszę stworzyć własny model.Nie wiem nawet czy ide dobrym tropem?

1

Generalnie dobrym,jednak w razie problemów pokaż implementacje funkcji data i flags.
Co zaznaczonego indeksu-nie musisz znać,możesz zapytać się poprzez view->selectionModel()->selectedIndexes()

0

Witam.

Piszę już swój właściwy program, doszedłem do momentu w którym mam problem z własnym modelem.Nie wiem jak zabrać się do tego, aby móc edytować wpisy, dodawać nowe lub też je usuwać.

Mój model odnosi się do QList, w której przetrzymuję wszystkich użytkowników. User to klasa posiadająca pola: name, password, oraz podklasę przetrzymującą rózne dane liczbowe, dlatego też mój User nie może byc po prostu drugą QList składającą się z 2 QString, co ułatwiłoby mi znacznie implementację.

Mój model wygląda następująco:

 class UserModel : public QAbstractListModel
{
    Q_OBJECT
public:
    UserModel(const QList<User> &user,QObject *parent = 0);
    int rowCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
   
    Qt::ItemFlags flags(const QModelIndex &index) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);

    bool UserModel::insertRow(int row, const QModelIndex &parent);
    bool UserModel::removeRow(int row, const QModelIndex &parent);

private:
    QList<User> usersModel;
 };

Plik usermodel.cpp

UserModel::UserModel(const QList<User> &user, QObject *parent) : QAbstractListModel(parent)
{
    usersModel = user;
}
int UserModel::rowCount(const QModelIndex &parent) const
{
    return usersModel.size();
}
QVariant UserModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid()) return QVariant();
    if(index.row() >= usersModel.size()) return QVariant();
    if(role == Qt::DisplayRole )
        return QVariant(usersModel.at(index.row()).ShowUser());
    else
        return QVariant();
}
Qt::ItemFlags UserModel::flags(const QModelIndex &index) const
{

    if (!index.isValid())
        return Qt::ItemIsEnabled;

    return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}
bool UserModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (index.isValid() && role == Qt::EditRole)
        {
             QString tmpName = value.toString();
             usersModel.append(User());
             emit dataChanged(index, index);
             return true;
         }
         return false;
} 

Jeśli dodam sobie użytkowników "ręcznie" w kodzie przed uruchomieniem programu to wszystko działa ok, problem jeśli dodaję ich np wciskając button AddUser, tam podaję nazwę użytkownika oraz hasło. Wiem że poprawnie się dodają, bo wyświetlam sobie komunikaty w konsoli pochodzące z konstruktorów klasy User. Nawet jeśli "zaktualizuję" sobię mój ListView, to lista użytkowników pozostaje taka sama. Nie wiem czy poprawnie rozumiem działanie wszystkich metod, ponieważ z moim angielskim jest troche słabo, a po polsku jest niestety bardzo mało informacji.

Z góry dziękuję za pomoc i poświęcony czas! Pozdrawiam

0

Przeczytaj w assistancie sekcję "editable models" przy okazji opisu model/view programming.
W telegraficznym skrócie:
-funkcja flags winna zwracać ustawioną flagę ItemIsEditable
-trzeba przeimplementować funkcję setData modelu.
-po edycji na widoku powinineś użyć view->viewport()->update().Ewentualnie na modelu wywołać funkcję reset(),ale to już będzie strzał z działa najcięższego kalibru (czytaj to jest kosztowna operacja)

0

Dzieki MasterBLB,

Zrobiłem tak jak mówiłeś, doszedłem do momentu w którym mam QListView i mogę dodawać nowych userów poprzez "dwuklik" na QListView. Jest możliwość aby wywoływać tę metodę która umieszcza użytkowników, lecz przez powiedzmy kliknięcie przycisku ?

0

Tak.Poczytaj o editTriggers w QAbstractItemView,a także o funkcji QAbstractItemView::edit()

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