Search code examples
c++qtmodel-view

Changing data in a QTableView depending on the selection of a QComboBox


I have a QComboBox in one of the columns of a QTableView. How can I change the other columns depending on what I selected in the ComboBox? I am using the QComboBox as a delegate.


Solution

  • There are at least 2 approaches.

    • Use natural for Qt's model itemChanged signal.
    • emit signal from your delegate and catch it inside your main window.

    If your delegate is standard which means that inside setModelData() method you have something like:

    QComboBox *line = static_cast<QComboBox*>(editor);
    QString data = line->currentText();
    //...
    model->setData(index, data);
    

    then I think you should use just natural way. For example:

    connect(model,&QStandardItemModel::itemChanged,[=](QStandardItem * item) {
        if(item->column() == NEEDED_COLUMN)
        {
            //you found, just get data and use it as you want
            qDebug() << item->text();
        }
    });
    

    I used here C++11 (CONFIG += c++11 to .pro file) and new syntax of signals and slots, but of course you can use old syntax if you want.

    I already reproduced your code(delegate with combobox) and my solution works if I select something in combobox and confirm that by enter clicking for example. But if you want to get solution where data will be changed automatically, when you select another item in combobox(without pressing enter) then see next case:

    Create special signal onside delegate:

    signals:
        void boxDataChanged(const QString & str);
    

    Create connection inside createEditor() method:

    QWidget *ItemDelegate::createEditor(QWidget *parent,
                                        const QStyleOptionViewItem &option,
                                        const QModelIndex &index) const
    {
        QComboBox *editor = new QComboBox(parent);
        connect(editor,SIGNAL(currentIndexChanged(QString)),this,SIGNAL(boxDataChanged(QString)));
        return editor;
    }
    

    And use it!

    ItemDelegate *del = new ItemDelegate;
    ui->tableView->setItemDelegate( del);
    ui->tableView->setModel(model);
        connect(del,&ItemDelegate::boxDataChanged,[=](const QString & str) {
                //you found, just get data and use it as you want
                qDebug() << str;
        });