Custom model - własny model w Qt a baza danych

0

Ok, od pewnego czasu, raz więcej raz mniej, mam doczynienia z przedstawieniem danych pochodzących z bazy danych w formie tabelarycznej (QTableView). Zazwyczaj dane te były "read-olny" więc nie było problemu ich aktualizacji .. (pamiętam tylko jeden przypadek gdzie musiałem umożliwić edycje danycn to zrobiłem to poprzez QLineEdit'y, do których były ładowane dane poprzez zaznaczenie wiersza w tabeli).

Ale do rzeczy..

Wiem, że możliwa jest bezpośrednia edycja danych z poziomu tabeli (o ile dobrzę kojarzę jest to możliwe dla modelu QSqlTableModel po reimplementacji niektórych metod (flags,setData); link: http://qt-project.org/doc/qt-4.8/sql-presenting.html ).

Ogólnie tych predefiniowanych modeli jest kilka:
user image
gdzie każdy z nich ma swoje zalety/wady : np.
-QSqlTableModel : możliwe pobranie tylko jednej tabeli
-QSqlQueryModel : z tego co doczytałem jest to model tylko do odczytu - nie można w nim zmieniać poszczególnych 'krotek', aby potem móc odświeżyć wyniki w wyświetlanej tabeli
-QStandardItemModel : z tego co doczytałem to raczej nie powinno go się używać do tworzenia modelu dla danych pochodzących z bazy danych ponieważ jest to zbyt powolny process.. No i jest potem problem z utworzeniem 'edytowalnej' tabeli..

Tylko moje pytanie brzmi..

Z czego skorzystać (oraz jak powinny wyglądać ogólne kroki) do wykonania takiego modelu danych, które będą wyświetlane w QTableView, i z poziomu tabeli dane będą edytowane (czyli 'odświeżany będzie model oraz widok w tabeli') i będzie sama edycja danych w bazie danych będzie wykonywana w momencie akceptacji poprzez przycisk (tak jak jest to pokazane w przykładzie: http://qt-project.org/doc/qt-4.8/sql-cachedtable.html z tym, że tutaj jest ograniczenie do jednej tabeli (niestety..))

//--
Moje przemyślenia: jedyny pomysł, który przychodzi mi do głowy jak po części to zrealizować to skorzystać z nie wspomnianego jeszcze tutaj QAbstractTableModel (tak jak to zostało zrobione na przykładzie od @MarekR22 http://4programmers.net/Forum/C_i_C++/213377-filtr_splotowy_obrazu_-_qt?p=933606#id933606 ) (tego typu przykładów w sieci jest w sumie kilka), tylko powstaje pytanie - z czego utworzyć ten model ? w przytoczonym przykładzie model stanowi tabela: int mData[MaxMaskSize][MaxMaskSize]; , a jaki powinien być model dla danych pochodzących z bazy danych ? No i jak wygląda kwestia akutalizacji z powrotem w bazie danych.. bo co z tego, że sam model został już zakutalizowany..

Ogólnie z zauważyłem, że moje potrzeby spełniałby przykład CachedTable ale "integorwane" z QSqlQueryModel gdzie można ustawić model->setModel("dowolne zapytanie SQL") .. niestety to tylko marzenie ? ;>

Proszę o zainteresowanie (i z góry za nie już dziękuje :) )

2

QSqlQueryModel jest tylko read only ponieważ trudno jest wykryć, które kolumny są edytowalne, a które nie. Przykładowo jeśli w kolumnie będziesz miał średnią/sumę czegoś to nie ma jednoznacznej recepty by zmienić tą wartość.
Ponieważ QSqlQueryModel ma obsługiwać wszystkie możliwe query musiano zrezygnować z funkcjonalności edycji.
Nie oznacza to jednak, że nie dało by się tego zrobić samemu.
Jeśli chcesz to zrobić dla konkretnego query to można dodać możliwość edycji wybranych kolumn dziedzicząc po QSqlQueryModel.
Problemem może być brak informacji w tabeli do wykonania odpowiedniej modyfikacji na bazie danych. W takim wypadku warto zastanowić się czy nie dodać do query dodatkowych kolumn zawierających potrzebne informacje, które zostaną ukryte przez odpowiednią modyfikację modelu danych, coś w stylu:

int TwojModel::columnCount( const QModelIndex & index) const {
     return QSqlQueryModel::columnCountindex)-2; // dwie nadmiarowe kolumny do ukrycia
}

QVariant TwojModel::data(const QModelIndex & item, int role = Qt::DisplayRole ) const {
     if (item.column()>columnCount()-2)
           return QVariant();
    return QSqlQueryModel::data(item, role); 
}

...

W metodzie setData po prostu modyfikujesz bazę danych korzystając z tego co możesz pobrać za pomocą metody record, możliwe że konieczne będzie odświeżenie całego modelu tabeli, musisz troszkę poeksperymentować.
Bazy danych to nie moja działka więc więcej nie jestem w stanie pomóc.

Może warto tez popatrzeć na źródła Qt (dla QSqlQueryModel i QSqlTableModel), może znajdziesz tam coś co ci ułatwi zadanie.

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