[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?
-
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.
-
@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
wherew 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.
-
@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
wherew 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ę.
-
@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ę.