s
sol11Ақп. 19, 2018, 3:48 Т.Қ.

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

Qt

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


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


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

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

16
s
  • Ақп. 19, 2018, 3:48 Т.Қ.

2 Скрин

    s
    • Ақп. 19, 2018, 3:50 Т.Қ.
    • (өңделген)

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

      s
      • Ақп. 19, 2018, 3:56 Т.Қ.

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

        s
        • Ақп. 19, 2018, 4: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();

                                  Пікірлер

                                  Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
                                  Кіріңіз немесе Тіркеліңіз
                                  Г

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

                                  • Нәтиже:66ұпай,
                                  • Бағалау ұпайлары-1
                                  t

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

                                  • Нәтиже:33ұпай,
                                  • Бағалау ұпайлары-10
                                  t

                                  Qt - Тест 001. Сигналы и слоты

                                  • Нәтиже:52ұпай,
                                  • Бағалау ұпайлары-4
                                  Соңғы пікірлер
                                  G
                                  GoattRockҚыр. 3, 2024, 1:50 Т.Қ.
                                  Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
                                  d
                                  dblas5Шілде 5, 2024, 11:02 Т.Ж.
                                  QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                                  k
                                  kmssrАқп. 8, 2024, 6:43 Т.Қ.
                                  Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                                  АК
                                  Анатолий КононенкоАқп. 5, 2024, 1:50 Т.Ж.
                                  Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                                  Енді форумда талқылаңыз
                                  Evgenii Legotckoi
                                  Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
                                  добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                                  F
                                  FynjyШілде 22, 2024, 4:15 Т.Ж.
                                  при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
                                  BlinCT
                                  BlinCTМаусым 25, 2024, 1 Т.Ж.
                                  Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
                                  BlinCT
                                  BlinCTМамыр 5, 2024, 5:46 Т.Ж.
                                  Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
                                  Evgenii Legotckoi
                                  Evgenii LegotckoiМамыр 2, 2024, 2:07 Т.Қ.
                                  Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

                                  Бізді әлеуметтік желілерде бақылаңыз