Die Klasse QDataMapperWidget wird verwendet, um Daten in einem Freiform-Widget anzuzeigen. Um mit diesem Widget zu arbeiten, benötigen Sie noch ein Modell, um die Daten darzustellen.
Zum Beispiel QSqlTableModel oder QSqlRelationalTableModel , aber die Daten werden nicht mehr ersetzt in QTableView , sondern in verschiedene beliebige Objekte. Zum Beispiel QLineEdit oder QComboBox Oder in einem Dialogfeld zum Hinzufügen von Einträgen, mit dem wir in diesem Artikel arbeiten werden.
Die Aufgabe lautet also wie folgt. Schreiben Sie ein Programm, das eine Liste von Computern in einer Tabelle anzeigt, und jeder Computer hat drei Datenfelder: Hostname, IP-Adresse und MAC-Adresse Es sollte auch eine Schaltfläche zum Öffnen eines Dialogfelds durch . geben die Wir können der Tabelle ein neues Gerät hinzufügen. Wir sollten auch in der Lage sein, Datensätze über dasselbe Dialogfeld zu bearbeiten.
Nachdem die Aufgabe beschrieben ist, gehen wir zu ihrer Implementierung in den Programmcode über, der in QtCreator 3.3.1 basierend auf Qt 5.4.1 geschrieben wurde.
Projektstruktur für QDataWidgetMapper
Das Projekt wird als Qt-Widgets-Anwendung erstellt, in der die folgenden Dateien erstellt werden:
- QDataMapperWidget.pro - Profil;
- mainwindow.h - Header-Datei des Hauptanwendungsfensters;
- mainwindow.cpp - Fensterquellcode;
- main.cpp - die Hauptquelldatei, von der aus die Anwendung startet;
- mainwindow.ui - Form des Hauptanwendungsfensters;
- database.h - Header-Datei der Hilfsklasse, die verwendet wird, um mit Informationen zu arbeiten, die in die Datenbank gestellt werden;
- database.cpp - die Quelldatei der Hilfsklasse, die verwendet wird, um mit Informationen zu arbeiten, die in der Datenbank platziert sind;
- dialogadddevice.h - Header-Datei des Dialogfelds zum Hinzufügen und Bearbeiten von Datensätzen;
- dialogadddevice.cpp - die Quelldatei des Dialogfelds zum Hinzufügen und Bearbeiten von Datensätzen;
- dialogadddevice.ui
Notiz. Ich erstelle den größten Teil der Benutzeroberfläche im Designer, um die Logik des Hauptcodes nicht mit unnötigen Informationen zu überladen. Tatsächlich ist dies nur eine Frage des Geschmacks und der Gewohnheit.
mainwindow.ui
Die Form des Hauptfensters des Projekts QDataWidgetMapper Die Form des Hauptfensters ist einfach. Und Sie verwenden zwei Objekte aus diesem Formular:
- Geräteschaltfläche hinzufügen
- Gerätetabellenansicht
dialogadddevice.ui
Das Dialogfeldformular verwendet drei QLineEdit Felder, zwei Schaltflächen und eine ButtonBox , die das Standardelement für die Klasse ist, die von QDialog erbt.
Das Dialogfeld QDataWidgetMapper Wir haben die folgenden Objekte bei der Arbeit:
- HostnameLineEdit
- IPAddressLineEdit
- MACLineBearbeiten
- buttonBox
- nächster Knopf
- ZurückSchaltfläche
QDataMapperWidget.pro
Dem Projektprofil muss eine Direktive hinzugefügt werden, die die Verwendung von SQL-Bibliotheken deklariert.
#------------------------------------------------- # # Project created by QtCreator 2015-08-16T23:58:29 # #------------------------------------------------- QT += core QT += gui QT += sql greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = QDataMapperWidget TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp \ database.cpp \ dialogadddevice.cpp HEADERS += mainwindow.h \ database.h \ dialogadddevice.h FORMS += mainwindow.ui \ dialogadddevice.ui
main.cpp
Die Datei wird im Projekt verwendet und wird standardmäßig erstellt.
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
mainwindow.h
In der Header-Datei des Hauptfensters definieren wir Slots zum Starten des Dialogs zum Hinzufügen von Datensätzen, zum Aktualisieren des Modells und zum Starten des Dialogs zum Bearbeiten von Datensätzen. Neben den im Qt Interface Designer vorgenommenen Grundeinstellungen gibt es auch Methoden zur Initialisierung des Erscheinungsbildes des Fensters sowie eine Methode zur Initialisierung des Datenansichtsmodells.
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSqlTableModel> #include <database.h> #include <dialogadddevice.h> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_addDeviceButton_clicked(); void slotUpdateModels(); void slotEditRecord(QModelIndex index); private: Ui::MainWindow *ui; DataBase *db; QSqlTableModel *modelDevice; private: void setupModel(const QString &tableName, const QStringList &headers); void createUI(); }; #endif // MAINWINDOW_H
mainwindow.cpp
In der Quellcodedatei des Hauptfensters initialisieren wir die Datentabelle, wie es in einem der vorherigen Artikel beispielsweise zum Arbeiten mit QSqlTableModel . Und wir schreiben auch die Logik des Verhaltens der Anwendung, wenn die Schaltfläche Hinzufügen gedrückt wird, die den Dialog zum Hinzufügen eines Datensatzes zur Tabelle aufruft. Dieser Dialog wird auch aufgerufen, wenn Sie auf einen Datensatz in der Datentabelle doppelklicken. In diesem Fall werden Informationen darüber, welcher Datensatz angeklickt wurde, an den Dialog übermittelt und seine Daten werden in die Felder zur Bearbeitung eingefügt.
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->setWindowTitle("QDataWidgetMapper Example"); /* Первым делом необходимо создать объект для работы с базой данных * и инициализировать подключение к базе данных * */ db = new DataBase(); db->connectToDataBase(); /* Инициализируем модели для представления данных * с заданием названий колонок * */ this->setupModel(DEVICE, QStringList() << trUtf8("id") << trUtf8("Имя хоста") << trUtf8("IP адрес") << trUtf8("MAC-адрес") ); /* Инициализируем внешний вид таблицы с данными * */ this->createUI(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::setupModel(const QString &tableName, const QStringList &headers) { /* Производим инициализацию модели представления данных * */ modelDevice = new QSqlTableModel(this); modelDevice->setTable(tableName); modelDevice->select(); /* Устанавливаем названия колонок в таблице с сортировкой данных * */ for(int i = 0, j = 0; i < modelDevice->columnCount(); i++, j++){ modelDevice->setHeaderData(i,Qt::Horizontal,headers[j]); } } void MainWindow::createUI() { ui->deviceTableView->setModel(modelDevice); // Устанавливаем модель на TableView ui->deviceTableView->setColumnHidden(0, true); // Скрываем колонку с id записей // Разрешаем выделение строк ui->deviceTableView->setSelectionBehavior(QAbstractItemView::SelectRows); // Устанавливаем режим выделения лишь одно строки в таблице ui->deviceTableView->setSelectionMode(QAbstractItemView::SingleSelection); // Устанавливаем размер колонок по содержимому ui->deviceTableView->resizeColumnsToContents(); ui->deviceTableView->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->deviceTableView->horizontalHeader()->setStretchLastSection(true); connect(ui->deviceTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotEditRecord(QModelIndex))); } /* Метод для активации диалога добавления записей * */ void MainWindow::on_addDeviceButton_clicked() { /* Создаем диалог и подключаем его сигнал завершения работы * к слоту обновления вида модели представления данных * */ DialogAddDevice *addDeviceDialog = new DialogAddDevice(); connect(addDeviceDialog, SIGNAL(signalReady()), this, SLOT(slotUpdateModels())); /* Выполняем запуск диалогового окна * */ addDeviceDialog->setWindowTitle(trUtf8("Добавить Устройство")); addDeviceDialog->exec(); } /* Слот обновления модели представления данных * */ void MainWindow::slotUpdateModels() { modelDevice->select(); } /* Метод для активации диалога добавления записей в режиме редактирования * с передачей индекса выбранной строки * */ void MainWindow::slotEditRecord(QModelIndex index) { /* Также создаем диалог и подключаем его сигнал завершения работы * к слоту обновления вида модели представления данных, но передаём * в качестве параметров строку записи * */ DialogAddDevice *addDeviceDialog = new DialogAddDevice(index.row()); connect(addDeviceDialog, SIGNAL(signalReady()), this, SLOT(slotUpdateModel())); /* Выполняем запуск диалогового окна * */ addDeviceDialog->setWindowTitle(trUtf8("Редактировать Устройство")); addDeviceDialog->exec(); }
dialogadddevice.h
Header-Datei des Dialogs zum Hinzufügen und Bearbeiten von Datensätzen. Wie Sie der Header-Datei entnehmen können, wird auch hier ein Modell zur Darstellung von Daten verwendet, dessen Daten jedoch nicht in QTableView übersetzt werden, wie beispielsweise im Tutorial zu QSqlRelationalModel oder in der MainWindow-Klasse dieses Artikels und in einem Objekt der QDataWidgetMapper-Klasse. Außerdem wird die accept()-Methode hier überschrieben, weil vor dem Schließen im Fenster müssen Sie sicherstellen, dass die Daten korrekt ausgefüllt sind. Kriterium für die Richtigkeit des Ausfüllens der Daten ist in diesem Projekt das Fehlen von doppelten Datensätzen.
#ifndef DIALOGADDDEVICE_H #define DIALOGADDDEVICE_H #include <QDialog> #include <QSqlTableModel> #include <QDataWidgetMapper> #include <QMessageBox> #include <database.h> namespace Ui { class DialogAddDevice; } class DialogAddDevice : public QDialog { Q_OBJECT public: explicit DialogAddDevice(int row = -1, QWidget *parent = 0); ~DialogAddDevice(); signals: void signalReady(); private slots: void on_buttonBox_accepted(); void updateButtons(int row); private: Ui::DialogAddDevice *ui; QSqlTableModel *model; QDataWidgetMapper *mapper; private: void setupModel(); void createUI(); void accept(); }; #endif // DIALOGADDDEVICE_H
dialogadddevice.cpp
Diese Datei implementiert die Logik der Klasse. Die Überprüfung der Richtigkeit der eingegebenen Daten erfolgt im Moment des Drückens der OK-Taste Bei korrekt ausgefüllten Feldern wird ein Datensatz in die Tabelle eingefügt oder bearbeitet. Die Validierung der Daten in den Feldern IP-Adresse und MAC-Adresse erfolgt mit dem Validator , dessen Schreiben in einem der vorherigen Artikel . Ebenfalls implementiert ist eine Prüfung auf Existenz eines Datensatzes mit ähnlichen Daten.
#include "dialogadddevice.h" #include "ui_dialogadddevice.h" DialogAddDevice::DialogAddDevice(int row, QWidget *parent) : QDialog(parent), ui(new Ui::DialogAddDevice) { ui->setupUi(this); /* Метода для инициализации модели, * из которой будут транслироваться данные * */ setupModel(); /* Если строка не задана, то есть равна -1, * тогда диалог работает по принципу создания новой записи. * А именно, в модель вставляется новая строка и работа ведётся с ней. * */ if(row == -1){ model->insertRow(model->rowCount(QModelIndex())); mapper->toLast(); /* В противном случае диалог настраивается на заданную запись * */ } else { mapper->setCurrentModelIndex(model->index(row,0)); } createUI(); } DialogAddDevice::~DialogAddDevice() { delete ui; } /* Метод настройки модели данных и mapper * */ void DialogAddDevice::setupModel() { /* Инициализируем модель и делаем выборку из неё * */ model = new QSqlTableModel(this); model->setTable(DEVICE); model->setEditStrategy(QSqlTableModel::OnManualSubmit); model->select(); /* Инициализируем mapper и привязываем * поля данных к объектам LineEdit * */ mapper = new QDataWidgetMapper(); mapper->setModel(model); mapper->addMapping(ui->HostnameLineEdit, 1); mapper->addMapping(ui->IPAddressLineEdit, 2); mapper->addMapping(ui->MACLineEdit, 3); /* Ручное подтверждение изменения данных * через mapper * */ mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); /* Подключаем коннекты от кнопок пролистывания * к прилистыванию модели данных в mapper * */ connect(ui->previousButton, SIGNAL(clicked()), mapper, SLOT(toPrevious())); connect(ui->nextButton, SIGNAL(clicked()), mapper, SLOT(toNext())); /* При изменении индекса в mapper изменяем состояние кнопок * */ connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(updateButtons(int))); } /* Метод для установки валидатора на поле ввода IP и MAC адресов * */ void DialogAddDevice::createUI() { QString ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"; QRegExp ipRegex ("^" + ipRange + "\\." + ipRange + "\\." + ipRange + "\\." + ipRange + "$"); QRegExpValidator *ipValidator = new QRegExpValidator(ipRegex, this); ui->IPAddressLineEdit->setValidator(ipValidator); QString macRange = "(?:[0-9A-Fa-f][0-9A-Fa-f])"; QRegExp macRegex ("^" + macRange + "\\:" + macRange + "\\:" + macRange + "\\:" + macRange + "\\:" + macRange + "\\:" + macRange + "$"); QRegExpValidator *macValidator = new QRegExpValidator(macRegex, this); ui->MACLineEdit->setValidator(macValidator); } void DialogAddDevice::on_buttonBox_accepted() { /* SQL-запрос для проверки существования записи * с такими же учетными данными. * Если запись не существует или находится лишь индекс * редактируемой в данный момент записи, * то диалог позволяет вставку записи в таблицу данных * */ QSqlQuery query; QString str = QString("SELECT EXISTS (SELECT " DEVICE_HOSTNAME " FROM " DEVICE " WHERE ( " DEVICE_HOSTNAME " = '%1' " " OR " DEVICE_IP " = '%2' )" " AND id NOT LIKE '%3' )") .arg(ui->HostnameLineEdit->text(), ui->IPAddressLineEdit->text(), model->data(model->index(mapper->currentIndex(),0), Qt::DisplayRole).toString()); query.prepare(str); query.exec(); query.next(); /* Если запись существует, то диалог вызывает * предупредительное сообщение * */ if(query.value(0) != 0){ QMessageBox::information(this, trUtf8("Ошибка хоста"), trUtf8("Хост с таким именем или IP-адресом уже существует")); /* В противном случае производится вставка новых данных в таблицу * и диалог завершается с передачей сигнала для обновления * таблицы в главном окне * */ } else { mapper->submit(); model->submitAll(); emit signalReady(); this->close(); } } void DialogAddDevice::accept() { } /* Метод изменения состояния активности кнопок пролистывания * */ void DialogAddDevice::updateButtons(int row) { /* В том случае, если мы достигаем одного из крайних (самый первый или * самый последний) из индексов в таблице данных, * то мы изменяем состояние соответствующей кнопки на * состояние неактивна * */ ui->previousButton->setEnabled(row > 0); ui->nextButton->setEnabled(row < model->rowCount() - 1); }
database.h
Die Hilfsklasse für die Arbeit mit der Datenbank ist eine modifizierte Version derselben Klasse aus früheren Lektionen.
#ifndef DATABASE_H #define DATABASE_H #include <QObject> #include <QSql> #include <QSqlQuery> #include <QSqlError> #include <QSqlDatabase> #include <QFile> #include <QDate> #include <QDebug> /* Директивы имен таблицы, полей таблицы и базы данных */ #define DATABASE_HOSTNAME "ExampleDataBase" #define DATABASE_NAME "DataBase.db" #define DEVICE "DeviceTable" #define DEVICE_HOSTNAME "Hostname" #define DEVICE_IP "IP" #define DEVICE_MAC "MAC" class DataBase : public QObject { Q_OBJECT public: explicit DataBase(QObject *parent = 0); ~DataBase(); /* Методы для непосредственной работы с классом * Подключение к базе данных и вставка записей в таблицу * */ void connectToDataBase(); bool inserIntoDeviceTable(const QVariantList &data); private: // Сам объект базы данных, с которым будет производиться работа QSqlDatabase db; private: /* Внутренние методы для работы с базой данных * */ bool openDataBase(); bool restoreDataBase(); void closeDataBase(); bool createDeviceTable(); }; #endif // DATABASE_H
datenbank.cpp
#include "database.h" DataBase::DataBase(QObject *parent) : QObject(parent) { } DataBase::~DataBase() { } /* Методы для подключения к базе данных * */ void DataBase::connectToDataBase() { /* Перед подключением к базе данных производим проверку на её существование. * В зависимости от результата производим открытие базы данных или её восстановление * */ if(!QFile("C:/example/" DATABASE_NAME).exists()){ this->restoreDataBase(); } else { this->openDataBase(); } } /* Методы восстановления базы данных * */ bool DataBase::restoreDataBase() { if(this->openDataBase()){ if(!this->createDeviceTable()){ return false; } else { return true; } } else { qDebug() << "Не удалось восстановить базу данных"; return false; } return false; } /* Метод для открытия базы данных * */ bool DataBase::openDataBase() { /* База данных открывается по заданному пути * и имени базы данных, если она существует * */ db = QSqlDatabase::addDatabase("QSQLITE"); db.setHostName(DATABASE_HOSTNAME); db.setDatabaseName("C:/example/" DATABASE_NAME); if(db.open()){ return true; } else { return false; } } /* Методы закрытия базы данных * */ void DataBase::closeDataBase() { db.close(); } /* Метод для создания таблицы устройств в базе данных * */ bool DataBase::createDeviceTable() { /* В данном случае используется формирование сырого SQL-запроса * с последующим его выполнением. * */ QSqlQuery query; if(!query.exec( "CREATE TABLE " DEVICE " (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " DEVICE_HOSTNAME " VARCHAR(255) NOT NULL," DEVICE_IP " VARCHAR(16) NOT NULL," DEVICE_MAC " VARCHAR(18) NOT NULL" " )" )){ qDebug() << "DataBase: error of create " << DEVICE; qDebug() << query.lastError().text(); return false; } else { return true; } return false; } /* Метод для вставки записи в таблицу устройств * */ bool DataBase::inserIntoDeviceTable(const QVariantList &data) { /* Запрос SQL формируется из QVariantList, * в который передаются данные для вставки в таблицу. * */ QSqlQuery query; /* В начале SQL запрос формируется с ключами, * которые потом связываются методом bindValue * для подстановки данных из QVariantList * */ query.prepare("INSERT INTO " DEVICE " ( " DEVICE_HOSTNAME ", " DEVICE_IP ", " DEVICE_MAC " ) " "VALUES (:Hostname, :IP, :MAC )"); query.bindValue(":Hostname", data[0].toString()); query.bindValue(":IP", data[1].toString()); query.bindValue(":MAC", data[2].toString()); // После чего выполняется запросом методом exec() if(!query.exec()){ qDebug() << "error insert into " << DEVICE; qDebug() << query.lastError().text(); return false; } else { return true; } return false; }
Ergebnis
Archiv mit Quellen: QDataWidgetMapper
Als Ergebnis sollte die laufende Anwendung so aussehen:
Вопрос: Как записать данные в столбец который не привязан к элементу ввода в форме? Например в таблице
привязаны к lineedit все поля кроме object_id и brend_id. object id это автоинкремент с ним все понятно подставляется значение по умолчанию. Как с используя QDataWidgetMapper записывать определенное значение в brend_id? При редактировании записей никаких вопросов нет а вот при попытке добавления выдает ошибку.Либо добавить в форум соответствующий виджет и сделать его скрытым через setVisible(false) , либо написать собственный маппер, в котором некоторые поля будут обрабатываться внутри маппера по заданному алгоритму. Я изучал вопрос маппера в QML, вот статья на эту тему , но там не для QSqlTableModel , а просто для модели данных.
Если делать со скрытым виджетом, то следует отслеживать сигнал currentIndexChanged и уже по нему обрабатывать требуемые скрытые виджеты так, как требуется. В документации нет и намёка на работу со скрытыми полями каким-либо документированным способом, поэтому вариант со скрытыми виджетами видится мне наиболее адекватным.
Про скрытый виджет идея пришла сразу, но думал что есть другие варианты.
Увы, но других вариантов я не вижу. QDataWidgetMapper явно подходит только для этого, иначе был бы какой-нибудь класс держатель значений. Но тот же самый QVariant, что наиболее близкое по смыслу, здесь явно не подходит. Так что... только скрытый виджет.
Успешно заработало :-)
Ну и отлично :-)
Как сделать так, что бы когда я открываю диалог, я не могу ничего делать в программе, пока я не закрою сам диалог? (Я не заметил(плохо прочел код))
Очень долго искал подобное описание.Спасибо. Только подскажи пожалуйста, как можно реализовать удаление строки с помощью кнопки
Нужно навешать слот на клик кнопки
И еще, как можно из диалогового окна, из QTextEdit , передать данные в таблицу?
Спасибо большое, но немного не пойму, что именно нужно прописать в слоте, что бы получать id и удалять через кнопку
Вставка данных в таблицу базы данных производится через INSERT SQL запрос. Пример такого запроса есть в этой статье
Можете в Mapper`e прикрутить ещё одно поле ввода, которое будет выводить id записи. Поле ввода можете настроить в режим readOnly, чтобы его нельзя было редактировать. Тогда сможете забирать через метод text() или value() данный id записи.
Хорошо, спасибо большое за помощь
Evileg, Здравствуйте. Можете пожалуйста пояснить, вот есть метод:
Добрый день!
Так получилось, что конкретно этот метод не используется в данном примере.
А где находится связь между нажатием на кнопку "ok" и выполнением слота
Спасибо!
Здравствуйте! В этой статье и нескольких Ваших других заметил метод closeDataBase(), но не нашел чтобы он использовался. И вообще во многих источниках видел исходники без закрытия БД. В php обычно (всегда) после запроса(ов) БД закрывается, и выходит здесь (в qt c++) также такое предусмотрено, но не совсем ясно понял когда и где его нужно (целесообразно) использовать? Как быть, если программа обращается к БД редко единичным образом или же когда все время требуется соединение и частые обращения?
В Qt После создания соединения с БД оно хранится на протяжения работы с приложением, но не постоянно. Необходимости закрывать соединение особо нет.
Добрый день!
@EVILEG can you kindly provide a response? Please
If you want to show two columns from your model in combobox, then, I think, you can try to set Model in QComboBox and use custom ItemDelegate for QComboBox. Try to research information about delegates in official documentation.
А как можно добавить картинку в БД через QDataWidgetMapper? Это делается методом addMapping? Статью про изображение в базе данных я читал.
Добрый день. Я не проверял mapping изображений. Тем более, что вопрос в том, на что именно их маппить. В той статье делается на QLabel. А это нередактируемый виджет, как например QLineEdit. Тем более, что такой специфичный функционал как изображения вряд ли подготовливался для маппинга.
Так что здесь скорее при выборе записи нужно или делать дополнительный запрос к базе данных или смотреть, содержит ли текущая запись информацию об изображении и помещать его на QLabel. То есть прямой маппинг не заработает, по моему мнению.
Мне просто надо изображение из QLabel'a, расположеннго на диалоговом окне, вставить в БД. Значит, всё-таки это лучше сделать через запрос?
Лучше через запрос. Видите ли, если вы будете вставлять изображение в базу данных, там Вам придётся преобразовать данные изображения в BLOB. Как в той статье. А в QDataWidgetMapper такая логика просто отсутсвует. Так что здесь или наследоваться от QDataWidgetMapper и писать свой, или просто через запрос.
Через запрос проще и быстрее. Через наследование уже больше мороки, но в крупных проектах это окупается (В ОЧЕНЬ КРУПНЫХ)
Реализовал поиск через QSortFilterProxyModel, но при выборе результата в Mapper передаются значения из tableView по порядку, а не полученные в результате поиска значения. Такая же проблема при сортировке данных в tableView.
Как правильно реализовать поиск?
Для фильтрации QSqlTableModel нужно использовать метод setFilter у этой самой модели QSqlTableModel. Туда передаётся SQL запрос для where
Начал делать что-то похожее, но без sql.
Не очень понимаю, что делает
Вернее не понимаю вот что: откуда он берёт данные, которые затем подставляет в диалог?
Моё собственное решение (делаю через QStandartItemModel) — передать в конструктор диалога все соответствующие поля из моей таблицы, которые затем через setText() прописать в QLineEdit.
Работать — работает (значения, разумеется, подставляются), но правильно ли так делать?
Понял сам так - происходит через setTable() "Sets the database table on which the model operates to tableName. Does not select data from the table, but fetches its field information", а затем через select() "Populates the model with data from the table that was set via setTable(), using the specified filter and sort condition, and returns true if successful; otherwise returns false".
Hi EVILEG,
Thnaks for example.
With this example code i am not getting header data. Any idea? I am new to QT and C++.
Can someone please help.