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();

                                  Пікірлер

                                  Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
                                  Кіріңіз немесе Тіркеліңіз
                                  OI
                                  • Ora Iro
                                  • Жел. 24, 2024, 3:38 Т.Ж.

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

                                  • Нәтиже:40ұпай,
                                  • Бағалау ұпайлары-8
                                  AD

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

                                  • Нәтиже:50ұпай,
                                  • Бағалау ұпайлары-4
                                  m
                                  • molni99
                                  • Қаз. 25, 2024, 10:37 Т.Қ.

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

                                  • Нәтиже:80ұпай,
                                  • Бағалау ұпайлары4
                                  Соңғы пікірлер
                                  ИМ
                                  Игорь МаксимовҚар. 22, 2024, 8:51 Т.Ж.
                                  Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                                  Evgenii Legotckoi
                                  Evgenii LegotckoiҚаз. 31, 2024, 11:37 Т.Ж.
                                  Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                                  A
                                  ALO1ZEҚаз. 19, 2024, 5:19 Т.Ж.
                                  Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                                  ИМ
                                  Игорь МаксимовҚаз. 5, 2024, 4:51 Т.Ж.
                                  Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                                  d
                                  dblas5Шілде 5, 2024, 8:02 Т.Ж.
                                  QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                                  Енді форумда талқылаңыз
                                  n
                                  nklyЖел. 27, 2024, 8:41 Т.Ж.
                                  Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. У меня есть Представление QTreeView и древовидная модель QStandardItemModel подключенная к представлению. Итемы в модели QStandardItem. В разных ветках дерева могут быть элементы с одинаковым им…
                                  Evgenii Legotckoi
                                  Evgenii LegotckoiМаусым 24, 2024, 12:11 Т.Қ.
                                  добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                                  t
                                  tonypeachey1Қар. 15, 2024, 3:04 Т.Ж.
                                  google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                                  NSProject
                                  NSProjectМаусым 4, 2022, 12:49 Т.Ж.
                                  Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…

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