s
sol1119 февраля 2018 г. 15:48

Qtableviev после сортировки

Qt

Сделал проект по уроку + добавил фильтр по "Типу устройств". Проблема заключается в редактировании записей после фильтрации.


На 1 скрине до фильтрации, а на 2 после.


Снимок_экрана_4.png
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

16
s
  • 19 февраля 2018 г. 15:48

2 Скрин

    s
    • 19 февраля 2018 г. 15:50
    • (ред.)

    А вот что происходит, когда я пытаюсь отредактировать третью запись в отфильтрованной таблице :/

      s
      • 19 февраля 2018 г. 15:56

      EVILEG наведи на путь истинный, что делаю не так подскажи :(

        s
        • 19 февраля 2018 г. 16:02
        void MainWindow::on_SearchButton_clicked()
        {
            modelDevice->setFilter(QString( DEVICE_TYPE "= '%1'").arg(ui->SearchLine->text()));
            modelDevice->select();
            
        }
        
        Фильтрую вот так, если что
          Evgenii Legotckoi
          • 20 февраля 2018 г. 2:57
          Добрый день!
          Как я понимаю, вы в качестве id используете номер строки. В вашем случае не получится так сделать.
          QTableView поддерживает скрытие колонок. Так вот, вам нужно использовать колонку с ID записи. Эту колонку можно скрыть, чтобы он не мешалась в таблице.
          Когда кликаете по QTableView с помощью метода data через индекс (QModelIndex) вам следует забрать ID записи и уже с помощью Id записи открывать диалог на редактирование.
            s
            • 20 февраля 2018 г. 5:23

            "QTableView с помощью метода data через индекс (QModelIndex) "



            Немного не понял, это как?
              Evgenii Legotckoi
              • 20 февраля 2018 г. 5:59

              Ну вы используете слот для открытия диалога редактирования. Выглядеть он будет так.

              void MainWindow::slotEditRecord(QModelIndex index)
              {
                  DialogAddDevice addDeviceDialog(index.row());
                  connect(&addDeviceDialog, SIGNAL(signalReady()), this, SLOT(slotUpdateModel()));
               
                  addDeviceDialog.setWindowTitle(trUtf8("Редактировать Устройство"));
                  addDeviceDialog.exec();
              }
              Используете там index.row().
              то есть открываете через номер строки. А нужно через информацию об ID записи, который обычно должен идти первой колонкой.
              Поэтому можно сделать примерно так.
              void MainWindow::slotEditRecord(QModelIndex index)
              {
                  // В качестве номера колонки будет 0, поскольку именно такую колонку чаще всего имеет ID
                  DialogAddDevice addDeviceDialog(index.model()->data(index.model()->index(index.row(), 0)));
                  connect(&addDeviceDialog, SIGNAL(signalReady()), this, SLOT(slotUpdateModel()));
               
                  addDeviceDialog.setWindowTitle(trUtf8("Редактировать Устройство"));
                  addDeviceDialog.exec();
              }
                s
                • 20 февраля 2018 г. 7:58
                • (ред.)
                До этого слот вот такой юзал

                void MainWindow::slotEditRecord()
                {
                    
                    DialogAddDevice *addDeviceDialog = new DialogAddDevice(ui->deviceTableView->selectionModel()->currentIndex().row(););
                    connect(addDeviceDialog, SIGNAL(signalReady()),this, SLOT(slotUpdateModels()));
                    addDeviceDialog->setWindowTitle(trUtf8("Редактировать Устройство"));
                    addDeviceDialog->exec();
                }

                С вашим слотом выдаёт ошибку :(

                  Evgenii Legotckoi
                  • 20 февраля 2018 г. 8:01

                  Две последних строки с ошибками в коде вы не переписали. А в первой я забыл учесть один момент.

                  void MainWindow::slotEditRecord(QModelIndex index)
                  {
                      // В качестве номера колонки будет 0, поскольку именно такую колонку чаще всего имеет ID
                      DialogAddDevice addDeviceDialog(index.model()->data(index.model()->index(index.row(), 0)).toInt());
                      connect(&addDeviceDialog, SIGNAL(signalReady()), this, SLOT(slotUpdateModel()));
                   
                      addDeviceDialog.setWindowTitle(trUtf8("Редактировать Устройство"));
                      addDeviceDialog.exec();
                  }
                    s
                    • 20 февраля 2018 г. 8:03

                    .

                      Evgenii Legotckoi
                      • 20 февраля 2018 г. 8:04

                      А теперь ещё раз и внимательно смотрим моё последнее сообщение

                        s
                        • 20 февраля 2018 г. 8:25

                        Всё, поменял таки заработало. Но почему то оно выбирает строку с индексом больше на 1. В итоге вот что юзаю и оно корректно работает :)

                         DialogAddDevice addDeviceDialog((index.model()->data(index.model()->index(index.row(), 0)).toInt())-1);
                        EVILEG Спасибо вам больше что помогли разобраться :)

                          Evgenii Legotckoi
                          • 20 февраля 2018 г. 8:29
                          • (ред.)

                          Потому, что в mainwindow вы работаете уже с индексами, когда создаёте диалог для редактирования, а диалоге в всё ещё работаете со строками.

                          Вам нужно переписать диалог, чтобы также данные забирались через индекс, а не через строку. Поскольку когда будете удалять некоторые строки, то правка на -1 уже Вам не поможет. Там будет расхождение id со строкой гораздо больше.
                            s
                            • 20 февраля 2018 г. 10:58

                            Evileg, не совсем понимаю что тут нужно переписать, чтобы данные забирались через индекс, а не строку. :(


                            #include "dialogadddevice.h"
                            #include "ui_dialogadddevice.h"
                            #include <QDebug>
                            
                            DialogAddDevice::DialogAddDevice(int row, QWidget *parent) :
                                QDialog(parent),
                                ui(new Ui::DialogAddDevice)
                            {
                                ui->setupUi(this);
                            
                               
                                setupModel();
                            
                                
                                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->Device_Name, 1);
                                mapper->addMapping(ui->Device_Type, 2);
                                mapper->addMapping(ui->Dev_invent_number, 3);
                                mapper->addMapping(ui->Dev_location, 4);
                                mapper->addMapping(ui->Dev_status, 5);
                            
                              
                                mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
                            
                                qDebug() << ui->Device_Name->text();
                                
                                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)));
                            }
                            
                            void DialogAddDevice::createUI()
                            {
                            
                                QRegExp Name_Range("[a-zA-Z0-9]{20}");
                                ui->Device_Name->setValidator(new QRegExpValidator (Name_Range,this));
                            
                            
                                /*
                                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->Device_Type->setValidator(macValidator);
                                */
                            }
                            
                            void DialogAddDevice::on_buttonBox_accepted()
                            {
                                
                                QSqlQuery query;
                                QString str = QString("SELECT EXISTS (SELECT " DEVICE_NAME " FROM " DEVICE
                                                      /*" WHERE ( " DEVICE_NAME " = '%1' "*/" WHERE " DEVICE_INVENTORY_NUMBER " = '%1' "
                                                      " AND id NOT LIKE '%2' )")
                                        .arg(/*ui->Device_Name->text(),*/
                                             ui->Dev_invent_number->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("В базе уже присутствует устройство с таким серийным номером"));
                                
                                } else {
                                    mapper->submit();
                                    model->submitAll();
                                    emit signalReady();
                                    this->close();
                                }
                            }
                            
                            void DialogAddDevice::accept()
                            {
                            qDebug() << ui->Device_Name->text();
                            }
                            
                            
                            void DialogAddDevice::updateButtons(int row)
                            {
                               
                                ui->previousButton->setEnabled(row > 0);
                                ui->nextButton->setEnabled(row < model->rowCount() - 1);
                            }
                            
                            Кстати на удивление, удаление записей работает абсолютно нормально, без каких либо проблем вот с таким кодом:
                            void MainWindow::slotRemoveRecord()
                            {
                            
                                // Получение id_ строки
                                int row = ui->deviceTableView->selectionModel()->currentIndex().row();
                                
                                if(row >= 0)
                                {
                                    if (QMessageBox::warning(this, trUtf8("Удаление записи"),
                                                                   trUtf8("Вы уверены, что хотите удалить эту запись?"),
                                                                   QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
                                    {
                                        //Откат базы :)
                                        QSqlDatabase::database().rollback();
                                        return;
                            
                                    }
                                    else 
                                    {
                                        if(!modelDevice->removeRow(row))
                                        {
                                            QMessageBox::warning(this, trUtf8("Проблема"),trUtf8("Не удалось удалить запись\nВозможно мешает какая то зависимость"));
                                        }
                                        modelDevice->select();
                                        ui->deviceTableView->setCurrentIndex(modelDevice->index(-1, -1));
                                    }
                                }
                            }
                            

                            Можешь навести пожалуйста, что мне нужно переписать в диалоге добавления :x
                              Evgenii Legotckoi
                              • 21 февраля 2018 г. 3:53
                              • (ред.)
                              • Ответ был помечен как решение.

                              Вот так можно написать

                              DialogAddDevice::DialogAddDevice(int id, QWidget *parent) :
                                  QDialog(parent),
                                  ui(new Ui::DialogAddDevice)
                              {
                                  ui->setupUi(this);
                                 
                                  setupModel();
                                  
                                  if(row == -1){
                                      model->insertRow(model->rowCount(QModelIndex()));
                                      mapper->toLast();
                                  /* В противном случае диалог настраивается на заданную запись
                                   * */
                                  } else {
                                      for (int row = 0; row < model->rowCount(); ++row)
                                      {
                                          if (model->data(model->index(row, 0)).toInt() == id)
                                          {
                                              mapper->setCurrentModelIndex(model->index(row, 0));
                                          }
                                      }
                                  }
                              
                                  createUI();
                              }
                              Внимательно только посмотрите изменение кода, там я немного поменял аргументы конструктора.
                              Вообще, как вариант можно передавать ещё и QModelIndex вместо Id, тогда будет ещё более гарантированный результат без ошибок, но в этом случае нужно будет иметь указатель на ту модель, которая находится в главном диалоге, а это уже более сложный для понимания вариант реализации.

                              Но в данном случа оба варианта будут рабочими.
                                s
                                • 21 февраля 2018 г. 8:26

                                Спасибо, всё заработало :)


                                Единственное вот тут row на id поменял и всё круто :))
                                if(id == -1){
                                        model->insertRow(model->rowCount(QModelIndex()));
                                        mapper->toLast();

                                  Комментарии

                                  Только авторизованные пользователи могут публиковать комментарии.
                                  Пожалуйста, авторизуйтесь или зарегистрируйтесь
                                  d
                                  • dsfs
                                  • 26 апреля 2024 г. 11:56

                                  C++ - Тест 004. Указатели, Массивы и Циклы

                                  • Результат:80баллов,
                                  • Очки рейтинга4
                                  d
                                  • dsfs
                                  • 26 апреля 2024 г. 11:45

                                  C++ - Тест 002. Константы

                                  • Результат:50баллов,
                                  • Очки рейтинга-4
                                  d
                                  • dsfs
                                  • 26 апреля 2024 г. 11:35

                                  C++ - Тест 001. Первая программа и типы данных

                                  • Результат:73баллов,
                                  • Очки рейтинга1
                                  Последние комментарии
                                  k
                                  kmssr9 февраля 2024 г. 2:43
                                  Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                                  АК
                                  Анатолий Кононенко5 февраля 2024 г. 9:50
                                  Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                                  EVA
                                  EVA25 декабря 2023 г. 18:30
                                  Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
                                  J
                                  JonnyJo25 декабря 2023 г. 16:38
                                  Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
                                  G
                                  Gvozdik19 декабря 2023 г. 5:01
                                  Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
                                  Сейчас обсуждают на форуме
                                  IscanderChe
                                  IscanderChe30 апреля 2024 г. 11:22
                                  Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…
                                  G
                                  Gar22 апреля 2024 г. 12:46
                                  Clipboard Как скопировать окно целиком в clipb?
                                  DA
                                  Dr Gangil Academics20 апреля 2024 г. 14:45
                                  Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
                                  a
                                  a_vlasov14 апреля 2024 г. 13:41
                                  Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
                                  Павел Дорофеев
                                  Павел Дорофеев14 апреля 2024 г. 9:35
                                  QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь

                                  Следите за нами в социальных сетях