IscanderChe
IscanderCheМаусым 21, 2019, 6:09 Т.Ж.

QSqlTableModel + QTableView + кастомный делегат QComboBox

Пытаюсь реализовать кастомного делегата на основе QComboBox. Получилось отчасти.
1) При щелчке на ячейке в колонке с делегатом (у меня это колонка 4, status) комбобокс появляется, а хотелось бы, чтобы он был виден всегда.
2) При загрузке виджета, если строк в таблице несколько, только в последней строке заполнена колонка status. Надо, чтоб показывались все.
3) Если щелкнуть на ячейке колонки status, где установлено значение "green", а потом перейти на другую ячейку, то значение предыдущей ячейки сбрасывается на значение "white". Должны сохраняться предыдущие установленные значения.

#include "comboboxdelegate.h"
#include <QComboBox>

ComboBoxDelegate::ComboBoxDelegate(QObject* parent)
{

}

QWidget* ComboBoxDelegate::createEditor(QWidget* parent,
    const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    if(index.column() == 4)
    {
        QComboBox* editor = new QComboBox(parent);
        editor->insertItem(0, "white");
        editor->insertItem(1, "green");
        return editor;
    }

    return QStyledItemDelegate::createEditor(parent, option, index);
}

void ComboBoxDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
    if(index.column() == 4)
    {
        QString value = index.model()->data(index, Qt::EditRole).toString();
        QComboBox* comboBox = static_cast<QComboBox*>(editor);
        if(value == "white")
            comboBox->setCurrentIndex(0);
        else if(value == "green")
            comboBox->setCurrentIndex(1);
    }
}

void ComboBoxDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
                                    const QModelIndex& index) const
{
    if(index.column() == 4)
    {
        QComboBox* comboBox = static_cast<QComboBox*>(editor);
        QString value = comboBox->currentData().toString();
        model->setData(index, value, Qt::EditRole);
    }
}

void ComboBoxDelegate::updateEditorGeometry(QWidget* editor,
    const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    editor->setGeometry(option.rect);
}
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

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

31
Evgenii Legotckoi
  • Маусым 24, 2019, 5:41 Т.Ж.

Добрый день!

А можете ещё прикрепить какой-нибудь пробный проект с этим делегатом? Я бы вечером глянул после работы, что там, да как.

    IscanderChe
    • Маусым 24, 2019, 9:19 Т.Ж.
    // widget.cpp
    
    #include "widget.h"
    #include <QTableView>
    #include <QVBoxLayout>
    #include "checkboxdelegate.h"
    #include "comboboxdelegate.h"
    #include "mytableview.h"
    #include <QSqlDatabase>
    #include <QDebug>
    #include <QSqlQuery>
    #include <QSqlError>
    #include <QDate>
    #include <QTime>
    #include <QSqlRecord>
    #include <QApplication>
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        // Setup UI
        MyTableView* tableView = new MyTableView();
        QVBoxLayout* layout = new QVBoxLayout;
        layout->addWidget(tableView);
        setLayout(layout);
    
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setHostName("localhost");
        QString dbName = qApp->applicationDirPath() + "/db.db";
        db.setDatabaseName(dbName);
    
        if(db.open())
            qDebug() << "DB opened";
        else
            qDebug() << "DB don't opened";
    
        QSqlQuery query_tbl;
        if(!query_tbl.exec( "CREATE TABLE IF NOT EXISTS tbl ("
                                    "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                                    "flag INTEGER, "
                                    "timeone TIME NOT NULL, "
                                    "timetwo TIME NOT NULL, "
                                    "status TEXT"
                                    ")"
                          )
          )
        {
            qDebug() << "Error of create table";
            qDebug() << query_tbl.lastError().text();
        }
        else
            qDebug() << "Created table";
    
        QVariantList data;
        int flag = 1;
        data.append(flag);
        data.append(QTime::currentTime());
        data.append(QTime::currentTime());
        QString status = "green";
        data.append(status);
        qDebug() << data;
    
        QSqlQuery query_ins;
        query_ins.prepare("INSERT INTO tbl (flag, timeone, timetwo, status) "
                          "VALUES (:Flag, :TimeOne, :TimeTwo, :Status)"
                          );
        query_ins.bindValue(":Flag", data.at(0).toInt());
        query_ins.bindValue(":TimeOne", data.at(1).toTime());
        query_ins.bindValue(":TimeTwo", data.at(2).toTime());
        query_ins.bindValue(":Status", data.at(3).toString());
    
        if(!query_ins.exec())
        {
            qDebug() << "error insert into table";
            qDebug() << query_ins.lastError().text();
        }
        else
            qDebug() << "inserted row";
    
        model = new MySqlTableModel;
        model->setTable("tbl");
    
        tableView->setModel(model);
    
        CheckBoxDelegate* checkBoxDelegate = new CheckBoxDelegate;
        tableView->setItemDelegateForColumn(1, checkBoxDelegate);
    
        ComboBoxDelegate* comboBoxDelegate = new ComboBoxDelegate;
        tableView->setItemDelegateForColumn(4, comboBoxDelegate);
    
        tableView->resizeColumnToContents(1);
    
        model->select();
    
        connect(tableView, SIGNAL(clickToCheck(QModelIndex)), this, SLOT(changeStateCheckBox(QModelIndex)));
    }
    
    Widget::~Widget()
    {
    
    }
    
    void Widget::changeStateCheckBox(QModelIndex index)
    {
        int state = index.model()->data(index).toBool();
        QVariant value = !state;
        model->setData(index, value);
    }
    
    
      Evgenii Legotckoi
      • Маусым 25, 2019, 3:33 Т.Ж.

      1) Насчёт того, чтобы делегат был виден всегда. Можете попробовать переопределить метод paint у делегата

      void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
      {
          if (index.column() == 1) // show combobox only in the second column
          {
              QStyleOptionComboBox box;
              box.state = option.state;
      
              box.rect = option.rect;
              box.currentText = index.data(Qt::EditRole).toString();
      
              QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &box, painter, 0);
              QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &box, painter, 0);
              return;
          }
          QStyledItemDelegate::paint(painter, option, index);
      }
      

      Что-то наподобие такого, только перепишите в рамках вашего делегата.

      2) Немного не понял

      3) Не уверен, но возможно, что нужно поработать ещё немного с самой моделью данных.

        IscanderChe
        • Маусым 25, 2019, 5:26 Т.Ж.

        По пункту 1 - да, всё получилось, спасибо. Я почти дошёл до этого, но переопределял paint не совсем правильно.

        По пункту 2 - картинка в прицепе. Для первых двух комбобоксов значения менялись с их же помощью, для следующих двух значения предустановлены программно.
        По пункту 3 - возможно, что надо задействовать модель, я только пока не понимаю, как. Сейчас у меня там кроме формата отображения дат больше ничего нет.

          IscanderChe
          • Маусым 25, 2019, 6:55 Т.Ж.

          По пункту 3 попытался переписать метод setData. В итоге комбобокс перестал работать.

          bool MySqlTableModel::setData(const QModelIndex& index, const QVariant& value, int /* role */)
          {
              bool ok = true;
              if(index.column() == 4)
              {
                  QModelIndex primaryKeyIndex = QSqlTableModel::index(index.row(), 0);
                  int id = QSqlTableModel::data(primaryKeyIndex).toInt();
                  QSqlQuery query;
                  query.prepare("UPDATE tbl SET status = ? WHERE id = ?");
                  query.addBindValue(value.toString());
                  query.addBindValue(id);
                  ok = query.exec();
                  select();
              }
          
              return ok;
          }
          
            IscanderChe
            • Маусым 26, 2019, 9:35 Т.Ж.
            • Жауап шешім ретінде белгіленді.

            В общем, полностью переписал код, получилось вот что:

            // widget.h
            
            #ifndef WIDGET_H
            #define WIDGET_H
            
            #include <QWidget>
            #include <QSqlTableModel>
            
            class Widget : public QWidget
            {
                Q_OBJECT
            
            public:
                Widget(QWidget *parent = 0);
                ~Widget();
            
            private:
                QSqlTableModel* model;
            };
            
            #endif // WIDGET_H
            
            // widget.cpp
            
            #include "widget.h"
            #include "comboboxdelegate.h"
            #include <QTableView>
            #include <QVBoxLayout>
            #include <QSqlDatabase>
            #include <QDebug>
            #include <QSqlQuery>
            #include <QSqlError>
            #include <QTime>
            #include <QSqlRecord>
            #include <QApplication>
            
            Widget::Widget(QWidget *parent)
                : QWidget(parent)
            {
                QTableView* tableView = new QTableView;
                QVBoxLayout* layout = new QVBoxLayout;
                layout->addWidget(tableView);
                setLayout(layout);
            
                QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
                db.setHostName("localhost");
                QString dbName = qApp->applicationDirPath() + "/db.db";
                db.setDatabaseName(dbName);
            
                if(db.open())
                    qDebug() << "DB opened";
                else
                    qDebug() << "DB don't opened";
            
                QSqlQuery query_tbl;
                if(!query_tbl.exec( "CREATE TABLE IF NOT EXISTS tbl ("
                                            "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                                            "timeone TIME NOT NULL, "
                                            "timetwo TIME NOT NULL, "
                                            "status TEXT"
                                            ")"
                                  )
                  )
                {
                    qDebug() << "Error of create table";
                    qDebug() << query_tbl.lastError().text();
                }
                else
                    qDebug() << "Created table";
            
                QVariantList data;
                data.append(QTime::currentTime());
                data.append(QTime::currentTime());
                QString color = "white";
                data.append(color);
                qDebug() << data;
            
                QSqlQuery query_ins;
                query_ins.prepare("INSERT INTO tbl (timeone, timetwo, status) "
                                  "VALUES (:TimeOne, :TimeTwo, :Status)"
                                  );
                query_ins.bindValue(":TimeOne", data.at(0).toTime());
                query_ins.bindValue(":TimeTwo", data.at(1).toTime());
                query_ins.bindValue(":Status", data.at(2).toString());
            
                if(!query_ins.exec())
                {
                    qDebug() << "error insert into table";
                    qDebug() << query_ins.lastError().text();
                }
                else
                    qDebug() << "inserted row";
            
                model = new QSqlTableModel;
                model->setTable("tbl");
            
                tableView->setModel(model);
            
                ComboBoxDelegate* delegate = new ComboBoxDelegate;
                tableView->setItemDelegateForColumn(3, delegate);
            
                model->select();
            }
            
            Widget::~Widget()
            {
            
            }
            
            // comboboxdelegate.h
            
            #ifndef COMBOBOXDELEGATE_H
            #define COMBOBOXDELEGATE_H
            
            #include <QStyledItemDelegate>
            
            class ComboBoxDelegate : public QStyledItemDelegate
            {
                Q_OBJECT
            
            public:
                ComboBoxDelegate();
            
                QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                                      const QModelIndex &index) const override;
            
                void setEditorData(QWidget* editor, const QModelIndex& index) const override;
            
                void setModelData(QWidget *editor, QAbstractItemModel *model,
                                  const QModelIndex &index) const override;
            
                void updateEditorGeometry(QWidget *editor,
                        const QStyleOptionViewItem &option, const QModelIndex &index) const override;
            
                void paint(QPainter* painter,
                    const QStyleOptionViewItem& option, const QModelIndex& index) const override;
            };
            
            #endif // COMBOBOXDELEGATE_H
            
            // comboboxdelegate.cpp
            
            #include "comboboxdelegate.h"
            #include <QComboBox>
            #include <QApplication>
            #include <QSqlQuery>
            #include <QSqlTableModel>
            
            ComboBoxDelegate::ComboBoxDelegate()
            {
            
            }
            
            QWidget* ComboBoxDelegate::createEditor(QWidget *parent,
                                                    const QStyleOptionViewItem &option,
                                                    const QModelIndex &index) const
            {
                QComboBox* comboBox = new QComboBox(parent);
                QPair<QString, int> pair;
                QList<QPair<QString, int> > dataList;
                pair.first = "white";
                pair.second = 0;
                dataList << pair;
                pair.first = "yellow";
                pair.second = 1;
                dataList << pair;
                pair.first = "green";
                pair.second = 2;
                dataList << pair;
            
                for(int i = 0; i < dataList.size(); ++i)
                {
                    QPair<QString, int> item = dataList.at(i);
                    comboBox->addItem(item.first, item.second);
                }
            
                comboBox->setCurrentIndex(0);
            
                return comboBox;
            }
            
            void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
            {
                if(index.column() == 3)
                {
                    QString value = index.model()->data(index, Qt::EditRole).toString();
                    QComboBox* comboBox = static_cast<QComboBox*>(editor);
                    if(value == "white")
                        comboBox->setCurrentIndex(0);
                    else if(value == "yellow")
                        comboBox->setCurrentIndex(1);
                    else if(value == "green")
                        comboBox->setCurrentIndex(2);
                }
            }
            
            void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                                const QModelIndex &index) const
            {
                QComboBox *edit = static_cast<QComboBox *>(editor);
                QSqlTableModel* sqlModel = static_cast<QSqlTableModel*>(model);
                QModelIndex primaryKeyIndex = sqlModel->index(index.row(), 0);
                int id = sqlModel->data(primaryKeyIndex).toInt();
                QString value = edit->currentText();
                QSqlQuery query;
                query.prepare("UPDATE tbl SET status = ? WHERE id = ?");
                query.addBindValue(value);
                query.addBindValue(id);
                query.exec();
                sqlModel->select();
            }
            
            void ComboBoxDelegate::updateEditorGeometry(QWidget *editor,
                const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const
            {
                editor->setGeometry(option.rect);
            }
            
            void ComboBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                                         const QModelIndex &index) const
            {
                if(index.column() == 3)
                {
                    QStyleOptionComboBox comboBoxStyleOption;
                    comboBoxStyleOption.state = option.state;
                    comboBoxStyleOption.rect = option.rect;
                    comboBoxStyleOption.currentText = index.data(Qt::EditRole).toString();
            
                    QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &comboBoxStyleOption, painter, 0);
                    QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &comboBoxStyleOption, painter, 0);
            
                    return;
                }
            
                QStyledItemDelegate::paint(painter,option, index);
            }
            

            Всё работает как надо: выставляется значение по умолчанию white, сохраняются значения, выставленные ранее. Осталось только одно затруднение: доступ к комбобоксу осуществляется после двойного щелчка мыши. Хотелось бы с первого щелчка.

              Evgenii Legotckoi
              • Маусым 26, 2019, 2:10 Т.Қ.

              Попробуйте включить все триггеры редактирования у TableView, а потом уже немного поиграться с ними, если заработает.

              tableView->setEditTriggers(QAbstractItemView::AllEditTriggers);
              
                IscanderChe
                • Маусым 27, 2019, 1:42 Т.Ж.
                • (өңделген)

                Теперь со второго щелчка работает: вначале выделить ячейку, потом уже работать с выпадающим списком.
                И выделяется первая ячейка для редактирования текста, что совсем не надо. Похоже, надо опять думать в сторону собственной реализации QTableView...

                  IscanderChe
                  • Маусым 27, 2019, 9:55 Т.Ж.

                  "Теперь со второго щелчка работает: вначале выделить ячейку, потом уже работать с выпадающим списком." Это осталось, а вот с редактированием удалось успешно закрыть вопрос. Добавилась собственная реализация QTableView и несколько строк в widget.cpp.

                  // mytableview.h
                  
                  #ifndef MYTABLEVIEW_H
                  #define MYTABLEVIEW_H
                  
                  #include <QTableView>
                  
                  class MyTableView : public QTableView
                  {
                      Q_OBJECT
                  
                  public:
                      MyTableView(QObject* parent = 0);
                  
                      void mouseMoveEvent(QMouseEvent* event) override;
                  
                  signals:
                      void mouseHover(QModelIndex index);
                  };
                  
                  #endif // MYTABLEVIEW_H
                  
                  // mytableview.cpp
                  
                  #include "mytableview.h"
                  #include <QMouseEvent>
                  
                  MyTableView::MyTableView(QObject* /*parent*/)
                  {
                  
                  }
                  
                  void MyTableView::mouseMoveEvent(QMouseEvent* event)
                  {
                      QPoint position = event->pos();
                      QModelIndex index = indexAt(position);
                      emit mouseHover(index);
                  }
                  
                  // widget.h
                  
                  #ifndef WIDGET_H
                  #define WIDGET_H
                  
                  #include "mytableview.h"
                  #include <QWidget>
                  #include <QSqlTableModel>
                  #include <QTableView>
                  
                  class Widget : public QWidget
                  {
                      Q_OBJECT
                  
                  public:
                      Widget(QWidget *parent = 0);
                      ~Widget();
                  
                  private:
                      QSqlTableModel* model;
                      MyTableView* tableView;
                  
                  private slots:
                      void mouseHover(QModelIndex index);
                  };
                  
                  #endif // WIDGET_H
                  
                  // widget.cpp
                  ...
                      tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
                      tableView->setSelectionMode(QAbstractItemView::SingleSelection);
                      tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
                      tableView->setSortingEnabled(true);
                      tableView->setMouseTracking(true);
                  
                      connect(tableView, SIGNAL(mouseHover(QModelIndex)), this, SLOT(mouseHover(QModelIndex)));
                  }
                  
                  Widget::~Widget()
                  {
                  
                  }
                  
                  void Widget::mouseHover(QModelIndex index)
                  {
                      if(index.column() != 3)
                          tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
                      if(index.column() == 3)
                          tableView->setEditTriggers(QAbstractItemView::AllEditTriggers);
                  }
                  

                  Огромное спасибо за помощь по работе с моделями! Трудновато, но очень интересно.)

                    IscanderChe
                    • Маусым 28, 2019, 7:21 Т.Ж.
                    • (өңделген)

                    С проблемой редактирования текста разобрался с помощью другого дружественного ресурса путём наследования модели и переписывания метода flags. Получилось более элегантно и без костылей в виде кастомного QTableView:

                    Qt::ItemFlags MySqlTableModel::flags(const QModelIndex& index) const
                    {
                        if(index.column() == 0 || index.column() == 1)
                        {
                            Qt::ItemFlags flags = QSqlTableModel::flags(index);
                            flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
                            return flags;
                        }
                    
                        return QSqlTableModel::flags(index);
                    }
                    

                    Но вылезла другая интересная проблема. Как удалось выяснить, при выборе другого значения в комбобоксе данные вносятся в базу данных только после щелчка на другой ячейке или свободном пространстве. Можно это как-то побороть, чтобы данные записывались сразу после выбора значения?

                      Evgenii Legotckoi
                      • Шілде 1, 2019, 2:43 Т.Ж.

                      Я думаю, что нужно попробовать делегат переписать, чтобы он сразу отсылал сигнал об изменении данных, как только выбрано какое-то значение в комбобоксе. По сути, значение не подтверждается, пока нет перехода в другую ячейку.

                        IscanderChe
                        • Шілде 1, 2019, 8:48 Т.Ж.

                        Если напрямую из setEditorData делать так:

                        emit commitData(editor);
                        

                        то компилятор выдаёт ошибку: "passing 'const ComboBoxDelegate' as 'this' argument discards qualifiers [-fpermissive]"

                          Evgenii Legotckoi
                          • Шілде 2, 2019, 3:07 Т.Ж.

                          commitData ожидает неконстантный указатель на виджет, а у вас туда передаётся константный указатель.

                            IscanderChe
                            • Шілде 2, 2019, 8:08 Т.Ж.

                            В общем, мозг сломал, но так ничего и не придумал... Слишком тонкие намёки для меня.))
                            Вот если бы чуть более развёрнутое объяснение... И примеров кода не надо! Только объяснение.

                              Evgenii Legotckoi
                              • Шілде 3, 2019, 2:30 Т.Ж.

                              А мне бы наоборот код глянуть )) Можете показать, где у вас emit commitData(editor) используется? А то я всё уже в голове не успеваю держать, детали из памяти истераются.

                                IscanderChe
                                • Шілде 3, 2019, 5:20 Т.Ж.
                                void ComboBoxDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
                                {
                                    qDebug() << "Work setEditorData";
                                    if(index.column() == 2)
                                    {
                                        QString value = index.model()->data(index, Qt::EditRole).toString();
                                        QComboBox* comboBox = static_cast<QComboBox*>(editor);
                                
                                        QSqlQuery querySelect("SELECT status FROM statuses");
                                        QStringList statusList;
                                        if(!querySelect.exec())
                                        {
                                            qDebug() << "Error select from statuses";
                                            qDebug() << querySelect.lastError().text();
                                        }
                                        else
                                        {
                                            while(querySelect.next())
                                                statusList << querySelect.value(0).toString();
                                        }
                                
                                        for(int i = 0; i < statusList.size(); ++i)
                                        {
                                            if(value == statusList.at(i))
                                            {
                                                comboBox->setCurrentIndex(i);
                                                emit commitData(editor);
                                            }
                                        }
                                    }
                                }
                                
                                  Evgenii Legotckoi
                                  • Шілде 3, 2019, 2:08 Т.Қ.

                                  Придумал. Вот что попробуйте, сделайте в методе createEditor коннект лямбды на изменение текущего индекса. В котором и будете делать commitData.

                                  QWidget* ComboBoxDelegate::createEditor(QWidget* parent,
                                      const QStyleOptionViewItem& option, const QModelIndex& index) const
                                  {
                                      if(index.column() == 4)
                                      {
                                          QComboBox* editor = new QComboBox(parent);
                                          editor->insertItem(0, "white");
                                          editor->insertItem(1, "green");
                                  
                                          connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index)
                                          {
                                              emit commitData(editor);
                                          });
                                          return editor;
                                      }
                                  
                                      return QStyledItemDelegate::createEditor(parent, option, index);
                                  }
                                  

                                  По идее, когда вы измените значение, тогда сразу и вызовется применение изменений.

                                    IscanderChe
                                    • Шілде 3, 2019, 4:14 Т.Қ.

                                    Спасибо, попробую завтра. На работе у меня стоит 5.11, там QOverload поддерживается. А вот дома стоит 5.5.1, и этого там ещё нет...
                                    Не знаете, как правильно под 32-битный линукс скомпилить одновременно и QtCreator, и свежий Qt? Несколько надоело быть ограниченно годным в домашних условиях.

                                      Evgenii Legotckoi
                                      • Шілде 3, 2019, 4:21 Т.Қ.

                                      Ну я никогда не компилировал сам Qt, просто устанавливал нужные версии через Qt Maintanence Tool и всё. Этого достаточно было.

                                        IscanderChe
                                        • Шілде 3, 2019, 4:51 Т.Қ.

                                        Вот ещё, кстати, вопрос не по теме. В сообщениях указывается время, отличное от моего местного. Это правильно? Особо не мешает, но вопрос есть. :) Хорошо бы настроить возможность определять/задавать часовой пояс в профиле пользователя.

                                          IscanderChe
                                          • Шілде 4, 2019, 2:17 Т.Ж.

                                          Всё равно ругается: "passing 'const ComboBoxDelegate' as 'this' argument discards qualifiers [-fpermissive] emit commitData(comboBox);".

                                          QWidget* ComboBoxDelegate::createEditor(QWidget* parent,
                                                                                  const QStyleOptionViewItem& /*option*/,
                                                                                  const QModelIndex& /*index*/) const
                                          {
                                              QComboBox* comboBox = new QComboBox(parent);
                                              QSqlQuery querySelect("SELECT status FROM statuses");
                                              QStringList statusList;
                                              if(!querySelect.exec())
                                              {
                                                  qDebug() << "Error select from statuses";
                                                  qDebug() << querySelect.lastError().text();
                                              }
                                              else
                                              {
                                                  while(querySelect.next())
                                                      statusList << querySelect.value(0).toString();
                                              }
                                          
                                              foreach(QString status, statusList)
                                                  comboBox->addItem(status);
                                          
                                              comboBox->setCurrentIndex(0);
                                          
                                              connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index)
                                              {
                                                  emit commitData(comboBox);
                                              });
                                          
                                              return comboBox;
                                          }
                                          
                                            Evgenii Legotckoi
                                            • Шілде 4, 2019, 4:38 Т.Ж.

                                            Да надо бы это сделать. Я столкнулся в Django с тем, что довольно трудоёмко реализовать автоматическую детекцию часового пояса. А в официальной документации сказано, что добавляйте у пользователя поле для настройки часового пояся и выбирайте из него данные. Ну наверное да, нужно сделать ))))

                                              Evgenii Legotckoi
                                              • Шілде 4, 2019, 4:42 Т.Ж.

                                              етить колотить. Не обратил внимание на то, что это тоже const метод. Попробуйте тогда написать обычный слот без лямбды и подключиться к нему.

                                                IscanderChe
                                                • Шілде 4, 2019, 5 Т.Ж.

                                                Сигнал работает, сообщение "ComboBox index changed" появляется в момент смены значения, всё как надо. Только как теперь в модель всё это передать? Доступа-то к ней из слота нет.

                                                QWidget* ComboBoxDelegate::createEditor(QWidget* parent,
                                                                                        const QStyleOptionViewItem& /*option*/,
                                                                                        const QModelIndex& /*index*/) const
                                                {
                                                    QComboBox* comboBox = new QComboBox(parent);
                                                    QSqlQuery querySelect("SELECT status FROM statuses");
                                                    QStringList statusList;
                                                    if(!querySelect.exec())
                                                    {
                                                        qDebug() << "Error select from statuses";
                                                        qDebug() << querySelect.lastError().text();
                                                    }
                                                    else
                                                    {
                                                        while(querySelect.next())
                                                            statusList << querySelect.value(0).toString();
                                                    }
                                                
                                                    foreach(QString status, statusList)
                                                        comboBox->addItem(status);
                                                
                                                    comboBox->setCurrentIndex(0);
                                                
                                                    connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changedComboBox(int)));
                                                
                                                    return comboBox;
                                                }
                                                
                                                void ComboBoxDelegate::changedComboBox(int /*index*/)
                                                {
                                                    qDebug() << "ComboBox index changed";
                                                }
                                                
                                                  Evgenii Legotckoi
                                                  • Шілде 4, 2019, 5:07 Т.Ж.

                                                  Попробуйте так

                                                  void ComboBoxDelegate::changedComboBox(int /*index*/)
                                                  {
                                                      emit commitData(qobject_cast<QComboBox*>(sender()));
                                                  }
                                                  
                                                    IscanderChe
                                                    • Шілде 4, 2019, 5:15 Т.Ж.

                                                    Сработало! Спасибо!!!

                                                      Evgenii Legotckoi
                                                      • Шілде 4, 2019, 5:19 Т.Ж.

                                                      Кстати, скорее всего на новом синтаксисе сигналов и слотов через указатели на методы не получится так сделать. Дело в том, что Макросы кладут болт на некоторые моменты в плане приватности и константности объектов... Но я бы проверил...

                                                      Можете проверить коннект так? Любопытства ради. Если я правильно понимаю, то тогда не сможет скомпилироваться...

                                                      connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ComboBoxDelegate::changedComboBox);
                                                      
                                                        IscanderChe
                                                        • Шілде 4, 2019, 5:36 Т.Ж.

                                                        Скомилировалось и нормально работает.

                                                          Evgenii Legotckoi
                                                          • Шілде 4, 2019, 5:40 Т.Ж.

                                                          Хорошо, значит ошибочная мысль была. Спасибо.

                                                          Оставьте тогда на новом синтаксисе. Уже не комильфо использовать старый синтаксис )))

                                                            IscanderChe
                                                            • Сәуір 20, 2023, 2:21 Т.Ж.

                                                            Добрый день.

                                                            Я тут жаловался в посте выше ( тут ), что: "Теперь со второго щелчка работает: вначале выделить ячейку, потом уже работать с выпадающим списком." Т.е. комбобокс в делегате начинал работать только после того, как щёлкнешь на нём: клик, и потом на второй клик уже список значений выпадает.

                                                            Удалось победить с помощью дружественного форума так:

                                                            tableView->openPersistentEditor(model->index(row,col));
                                                            

                                                            где индекс указывает на те ячейки, где размещается делегат.

                                                              Evgenii Legotckoi
                                                              • Сәуір 20, 2023, 4:17 Т.Ж.

                                                              Круто, хорошо, что удалось разобраться :-)

                                                                Пікірлер

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

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

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

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

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

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

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

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