Search code examples
c++qtqwidgetqtreeviewqcombobox

Add QCombobox inside QTreeview specific cell


I was trying to insert a QCombobox only in some specific cells of my QTreeview. As I read, I think that I need to create my delegate (that I've created). But I don't understand how to insert this in my treeview.

I want to realize this:

enter image description here

This is my code:

#include <QTreeView>
#include <QStandardItemModel>
#include <QStandardItem>
#include "mainwindow.h"
#include "comboboxdelegate.h"


const int ROWS = 2;
const int COLUMNS = 3;

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    treeView = new QTreeView(this);
    setCentralWidget(treeView);

    standardModel = new QStandardItemModel ;
    standardModel->setColumnCount(2);

    QStandardItem *root = new QStandardItem("ROOT");
    root->setCheckable(true);
    root->setCheckState(Qt::Checked);
    root->setEditable(false);

    standardModel->setItem(0, 0, root);

    QList< QStandardItem * > listOne ;
    QStandardItem  *f1 = new QStandardItem( "Field_1" );
    f1->setCheckable(true);
    f1->setCheckState(Qt::Checked);
    f1->setEditable(false);

    listOne.append(f1) ;
    listOne.append( new QStandardItem( "<Free text>" ) ) ;
    root->appendRow(listOne);


    QList< QStandardItem * > listTwo ;
    QStandardItem  *f2 = new QStandardItem( "Field_2" );
    listTwo.append(f2) ;
    listTwo.append( new QStandardItem( "<HERE COMBOBOX!>" ) ) ;
    root->appendRow(listTwo);

    treeView->setModel(standardModel);
    treeView->expandAll();
}

I managed to create an entire column with QCombobox (using custom delegate). But I don't know how to set only specific cell. Anyone can help me?


Solution

  • QTreeWidget makes widget items convenient.

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
    {
        treeWidget = new QTreeWidget(this);
        setCentralWidget(treeWidget);
    
        treeWidget->setColumnCount(2);
    
        auto root = new QTreeWidgetItem({"Root"});
        root->setCheckState(0, Qt::Checked);
        treeWidget->addTopLevelItem(root);
    
        auto child1 = new QTreeWidgetItem({"Field 1", "<Free Text>"});
        child1->setCheckState(0, Qt::Checked);
        child1->setFlags(child1->flags() | Qt::ItemIsEditable);
        root->addChild(child1);
    
        auto child2 = new QTreeWidgetItem({"Field 2"});
        child2->setFlags(child2->flags() | Qt::ItemIsEditable);
        root->addChild(child2);
    
        auto comboBox = new QComboBox();
        comboBox->addItems({"Red", "Blue", "Yellow"});
        treeWidget->setItemWidget(child2, 1, comboBox);
    
        connect(treeWidget, &QTreeWidget::itemDoubleClicked, treeWidget, &QTreeWidget::editItem);
    
        treeWidget->expandAll();
    }
    

    There are a few differences to note.

    • You'll need QTreeWidget* treeWidget; in your class declaration. And include the QTreeWidget header.

    • By default, TreeWidgetItems aren't checkable (no checkbox), but calling QTreeWidgetItem::setCheckState with Qt::Checked or Qt::Unchecked will make it checkable.

    • Items are not editable by default. Whole rows can be made editable by calling treeWidgetItem->setFlags(treeWidgetItem->flags() | Qt::ItemIsEditable). To filter what rows/columns can be edited, you can define your own itemDoubleClicked slot and use an if-statement (example).