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
                                  AD

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

                                  • Result:50points,
                                  • Rating points-4
                                  m

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

                                  • Result:80points,
                                  • Rating points4
                                  m

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

                                  • Result:20points,
                                  • Rating points-10
                                  Last comments
                                  i
                                  innorwallNov. 12, 2024, 6:12 a.m.
                                  Django - Tutorial 055. How to write auto populate field functionality Freckles because of several brand names retin a, atralin buy generic priligy
                                  i
                                  innorwallNov. 12, 2024, 2:23 a.m.
                                  QML - Tutorial 035. Using enumerations in QML without C ++ priligy cvs 24 Together with antibiotics such as amphotericin B 10, griseofulvin 11 and streptomycin 12, chloramphenicol 9 is in the World Health Organisation s List of Essential Medici…
                                  i
                                  innorwallNov. 11, 2024, 11:50 p.m.
                                  Qt/C++ - Lesson 052. Customization Qt Audio player in the style of AIMP It decreases stress, supports hormone balance, and regulates and increases blood flow to the reproductive organs buy priligy online safe Promising data were reported in a PDX model re…
                                  i
                                  innorwallNov. 11, 2024, 10:19 p.m.
                                  Heap sorting algorithm The role of raloxifene in preventing breast cancer priligy precio
                                  i
                                  innorwallNov. 11, 2024, 9:55 p.m.
                                  PyQt5 - Lesson 006. Work with QTableWidget buy priligy 60 mg 53 have been reported by Javanovic Santa et al
                                  Now discuss on the forum
                                  i
                                  innorwallNov. 12, 2024, 4:56 a.m.
                                  добавить qlineseries в функции buy priligy senior brother Chu He, whom he had known for many years
                                  i
                                  innorwallNov. 11, 2024, 6:55 p.m.
                                  Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
                                  9
                                  9AnonimOct. 25, 2024, 4:10 p.m.
                                  Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                                  Follow us in social networks