[QTableView + QSqlite] Jak przy wybraniu wiersza zawsze otrzymywać dane z pierwszej komórki
-
Dzień Dobry
Proszę o poradę.
Poniższy kod wypisuje mi w konsoli dane z komórki (klikniętej) w wybranym wierszu, jednak mi zależy aby dane wyświetlane były z pierwszej komórki wybranego wiersza.QString text; const QModelIndex index = ui->tableView->selectionModel()->currentIndex(); text = index.data(Qt::DisplayRole).toString(); qDebug() << text;
-
Dokładniej przybliżę o co mi chodzi.
Program pobiera z bazy dane i wyświetla w QTableView cztery kolumny ("Id", "Imię", Nazwisko", "telefon"). Po kliknięciu, na obojętnie którą komórkę wiersza, aktywuję cały wiersz. Przy aktywnym wierszu otwieram okno dialogowe np. do edycji danych - i tu jest mi potrzebny "id" z pierwszej komórki aktywnego wiersza(w otwartym oknie dialogowym mogę edytować rekord bazy o znanym "id").Problem rozwiązałem, stworzyłem listę indeksów aktywnego wiersza i przypisałem pierwszy element listy do stringu "tekst". Trochę mi to zajęło czasu, dlatego postanowiłem się tym podzielić. Może komuś się przyda.
Mam pytanie, czy może jest bardziej elegancki sposób? :)QString text; const QModelIndexList indexes = ui->tableView->selectionModel()->selectedIndexes(); text = indexes[0].data(Qt::DisplayRole).toString(); qDebug() << text; dialogEdit = new DialogEdit(text,this); dialogEdit->setModal(true); dialogEdit->show();
-
@karlowic Jeśli dobrze rozumiem to chodzi Ci o sytuację, w której np ktoś klika n-tą kolumnę ale potrzebujesz dane z tego samego wiersza z innej kolumny niż kliknięta? Możesz użyć indeksu który masz, odwołać się do modelu. Zakładając że model jest z rodzaju table model (nie podałeś, jakiego używasz?) oferuje on metody sibling() które służą właśnie do uzyskania danych z innych kolumn tego samego rzędu.
-
Jestem początkujący i za bardzo nie łapię wszystkiego jak trzeba.
Nie wiem czy SqlQueryModel to table model.
Tworzę model i wyświetlam go w tableView:QSqlQueryModel *model = new QSqlQueryModel; model->setQuery(pytanie); model->setHeaderData(0, Qt::Horizontal, tr("id")); model->setHeaderData(1, Qt::Horizontal, tr("Imię")); model->setHeaderData(2, Qt::Horizontal, tr("Nazwisko")); model->setHeaderData(3, Qt::Horizontal, tr("nr telefonu")); ui->tableView->setModel(model); ui->tableView->setColumnWidth(0,40); ui->tableView->show();
Teraz jak kliknę na komórkę określonego wiersza to mam operować na obiekcie - model czy na obiekcie ui->tableView?
-
@karlowic Wygodniej do table view podać table model o ile masz naprawdę coś, co wymaga dedykowanej kwerendy do bazy. Jeśli jednak chodzi tylko o pominięcie kilku kolumn wydaje mi się że wygodniej zrobić hide() na kolumnach niż cudować z kwerendą.
-
@artwaw Wydaję mi się, że kwerendę do bazy raczej potrzebuję. Ułatwia mi znalezienie konkretnego nazwiska w bazie. Cała metoda tak wygląda:
void MainWindow::refresh() { QString relation = ui->lineEdit->text() + '%'; QString column = ui->comboBox->currentText(); QString pytanie = QString ("SELECT * FROM pacjenci WHERE %1 LIKE \"%2\" ORDER BY %1").arg(column, relation); QSqlQueryModel *model = new QSqlQueryModel; model->setQuery(pytanie); model->setHeaderData(0, Qt::Horizontal, tr("id")); model->setHeaderData(1, Qt::Horizontal, tr("Imię")); model->setHeaderData(2, Qt::Horizontal, tr("Nazwisko")); model->setHeaderData(3, Qt::Horizontal, tr("nr telefonu")); ui->tableView->setModel(model); ui->tableView->setColumnWidth(0,40); ui->tableView->show(); }
Po wpisaniu pierwszych dwóch-trzech liter zawęża liczba wyświetlanych rekordów.
-
@karlowic Rozumiem Twoje podejście ale się z nim nie zgadzam :)
QueryModel jest dość prymitywny i nie widzę łatwego sposobu dojścia do danych, których potrzebujesz. Wykonałbym nieco więcej pracy i przeszedł na TableModel dla prostej tabeli lub nawet RelationalTableModel jeśli w tabeli są obecne foreign keys. W ten sposób iteracja po kolumnach staje się dość prosta.
Dodatkowo:
select *
zwraca nieposortowany wynik (który jak widzę porządkujesz przezorder by
. Załatwiłbym to przez wsadzenie QSortFilterProxyModel pomiędzy model właściwy a widok - umożliwia filtrowanie a co najważniejsze sortowanie w samym widoku.QSqlTableModel posiada też metodę setFilter() która służy aplikowaniu warunków po
where
w Sql.Jeśli dobrze rozumiem jak chcesz to mieć skonstruowane da się rzecz opędzić bez robienia subclassingu. Wiem, że to trochę więcej pracy ale w efekcie, nawet stosując sam TableModel, dostajesz elastyczność w dostępie do danych i dobry punkt wyjścia, gdybyś chciał swoje narzędzie rozwijać dalej w przyszłości.
I tak:- QSqlTableModel zamiast QSqlQueryModel;
setTable("pacjenci");
zamiastsetQuery()
;- headers I dalej bez zmian.
Opcjonalnie:
- QSortFilterProxyModel przypisany do widoku zamiast TableModel, ten ostatni jako source.
- parę drobnych zmian w ustawieniach widoku, żeby sortowanie działało od strzału (w opisie klasy jest jasno wytłumaczone).
Lub: QSqlTableModel::setFilter();
Tak bym to zrobił w każdym razie.
-
@artwaw Trochę poszperałem, poczytałem i w pełni się z Tobą zgadzam. Nie wiedziałem, że istnieje taka alternatywa. Jak wspomniałem moja wiedza w zakresie środowiska Qt jest mizerna. Bawię się "programowaniem" w wolnym czasie dla przyjemności. Dziękuję za poświęcony mi czas i przekazaną mi wiedzę.