s
sol11Feb. 19, 2018, 3:48 p.m.

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

Qt

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


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


Снимок_экрана_4.png
We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

16
s
  • Feb. 19, 2018, 3:48 p.m.

2 Скрин

    s
    • Feb. 19, 2018, 3:50 p.m.
    • (edited)

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

      s
      • Feb. 19, 2018, 3:56 p.m.

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

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

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



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

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

              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
                • Feb. 20, 2018, 7:58 a.m.
                • (edited)
                До этого слот вот такой юзал

                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
                  • Feb. 20, 2018, 8:01 a.m.

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

                  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
                    • Feb. 20, 2018, 8:03 a.m.

                    .

                      Evgenii Legotckoi
                      • Feb. 20, 2018, 8:04 a.m.

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

                        s
                        • Feb. 20, 2018, 8:25 a.m.

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

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

                          Evgenii Legotckoi
                          • Feb. 20, 2018, 8:29 a.m.
                          • (edited)

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

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

                            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
                              • Feb. 21, 2018, 3:53 a.m.
                              • (edited)
                              • The answer was marked as a solution.

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

                              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
                                • Feb. 21, 2018, 8:26 a.m.

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


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

                                  Comments

                                  Only authorized users can post comments.
                                  Please, Log in or Sign up
                                  d
                                  • dsfs
                                  • April 26, 2024, 4:56 p.m.

                                  C ++ - Test 004. Pointers, Arrays and Loops

                                  • Result:80points,
                                  • Rating points4
                                  d
                                  • dsfs
                                  • April 26, 2024, 4:45 p.m.

                                  C++ - Test 002. Constants

                                  • Result:50points,
                                  • Rating points-4
                                  d
                                  • dsfs
                                  • April 26, 2024, 4:35 p.m.

                                  C++ - Test 001. The first program and data types

                                  • Result:73points,
                                  • Rating points1
                                  Last comments
                                  k
                                  kmssrFeb. 9, 2024, 7:43 a.m.
                                  Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                                  Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                                  EVA
                                  EVADec. 25, 2023, 11:30 p.m.
                                  Boost - static linking in CMake project under Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
                                  J
                                  JonnyJoDec. 25, 2023, 9:38 p.m.
                                  Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
                                  G
                                  GvozdikDec. 19, 2023, 10:01 a.m.
                                  Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
                                  Now discuss on the forum
                                  G
                                  GarApril 22, 2024, 5:46 p.m.
                                  Clipboard Как скопировать окно целиком в clipb?
                                  DA
                                  Dr Gangil AcademicsApril 20, 2024, 7:45 p.m.
                                  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_vlasovApril 14, 2024, 6:41 p.m.
                                  Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
                                  Павел Дорофеев
                                  Павел ДорофеевApril 14, 2024, 2:35 p.m.
                                  QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
                                  f
                                  fastrexApril 4, 2024, 4:47 p.m.
                                  Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

                                  Follow us in social networks