maro213_
maro213_

Reputation: 45

How to disable checkboxes in QTreeView columns but keep the entire row selectable

I'm using a QTreeView and a custom model derived from QAbstractItemModel to display rows with 3 checkboxes per row.

The selection behaviour is set to select entire rows. The checkboxes are added via returning a Qt::CheckState in the model's data()-function.

The model's flags()-function returns Qt::ItemIsUserCheckable for all model indices that have a checkbox. Depending on the state of the third checkbox, checkbox 1 and 2 shall be enabled or disabled.

Qt::ItemFlags MyModel::flags(QModelIndex const& index) const {
    Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;

    if(index.column() > 0) {
        flags = flags | Qt::ItemIsUserCheckable;
    }

    if(thirdCheckboxChecked(index) && (index.column() == 1 || index.column() == 2) ) {
        flags = flags & ~Qt::ItemIsEnabled;
    }

    return flags;
}

I have tried to disable the checkboxes via the model's flags()-function (by not returning Qt::ItemIsEnabled if the third checkbox is checked) but this will disable the entire item, disabling the selection for the entire item / cell resulting in this behaviour:

enter image description here

How can I access the checkboxes and disable them without disabling the entire items?

Upvotes: 0

Views: 337

Answers (1)

kenash0625
kenash0625

Reputation: 697

try using a delegate? gray out only checkbox, doesnot gray out cell:enter image description here

#include <QtWidgets/QApplication>
#include<qt_windows.h>
#include <QTableView>
#include <QAbstractTableModel>
#include <QStyledItemDelegate>
#include <QPainter>

int checkstat[4] = { Qt::Checked,Qt::Checked,Qt::Unchecked,Qt::Unchecked };
int checkenable[4] = { 1,1,0,0 };

class delegate :public QStyledItemDelegate
{
    Q_OBJECT
public:
    virtual void paint(QPainter* painter, const QStyleOptionViewItem& option
        , const QModelIndex& index) const override
    {
        QStyledItemDelegate::paint(painter, option, index);
        if (index.column() == 1)
        {
            QStyle* style = QApplication::style();
            QStyleOptionButton butOpt;
            butOpt.rect.setX(option.rect.x()+ option.rect.width()/2);
            butOpt.rect.setY(option.rect.y());
            butOpt.rect.setWidth(option.rect.width()/4);
            butOpt.rect.setHeight(option.rect.height());
            if(checkenable[index.row()])butOpt.state = QStyle::State_Enabled;
            butOpt.state |= checkstat[index.row()] ? QStyle::State_On : QStyle::State_Off;
            style->drawControl(QStyle::CE_CheckBox, &butOpt, painter);
        }
      
    }
};

class tablemodel :public QAbstractTableModel
{
    Q_OBJECT
public:
    Q_INVOKABLE virtual int rowCount(const QModelIndex& parent = QModelIndex()) const
    {
        return 4;
    }
    Q_INVOKABLE virtual int columnCount(const QModelIndex& parent = QModelIndex()) const
    {
        return 2;
    }

    Q_INVOKABLE virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const
    {
        if (index.column() == 0&& role==Qt::DisplayRole)
        {
            return QString::number(index.row()) + '-' + QString::number(index.column());
        }
        return QVariant();
    }
    Qt::ItemFlags flags(const QModelIndex& index) const override
    {
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
};
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTableView view;
    tablemodel m;
    delegate d;
    view.setItemDelegate(&d);
    view.setModel(&m);
    view.show();
    //QtWidgetsApplication1 w;
    //w.show();
    return a.exec();
}
#include"main.moc"

Upvotes: 0

Related Questions