如何在QTreeView列中禁用复选框,但保持整行可选。

huangapple go评论66阅读模式
英文:

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:

如何在QTreeView列中禁用复选框,但保持整行可选。

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

英文:

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:

如何在QTreeView列中禁用复选框,但保持整行可选。

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

答案1

得分: 0

以下是代码的翻译部分:

尝试使用代理?仅使复选框变灰,不使单元格变灰:

#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"

请注意,我已将代码部分翻译成中文。

英文:

try using a delegate? gray out only checkbox, doesnot gray out cell:如何在QTreeView列中禁用复选框,但保持整行可选。

#include &lt;QtWidgets/QApplication&gt;
#include&lt;qt_windows.h&gt;
#include &lt;QTableView&gt;
#include &lt;QAbstractTableModel&gt;
#include &lt;QStyledItemDelegate&gt;
#include &lt;QPainter&gt;
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&amp; option
, const QModelIndex&amp; 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-&gt;drawControl(QStyle::CE_CheckBox, &amp;butOpt, painter);
}
}
};
class tablemodel :public QAbstractTableModel
{
Q_OBJECT
public:
Q_INVOKABLE virtual int rowCount(const QModelIndex&amp; parent = QModelIndex()) const
{
return 4;
}
Q_INVOKABLE virtual int columnCount(const QModelIndex&amp; parent = QModelIndex()) const
{
return 2;
}
Q_INVOKABLE virtual QVariant data(const QModelIndex&amp; index, int role = Qt::DisplayRole) const
{
if (index.column() == 0&amp;&amp; role==Qt::DisplayRole)
{
return QString::number(index.row()) + &#39;-&#39; + QString::number(index.column());
}
return QVariant();
}
Qt::ItemFlags flags(const QModelIndex&amp; 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(&amp;d);
view.setModel(&amp;m);
view.show();
//QtWidgetsApplication1 w;
//w.show();
return a.exec();
}
#include&quot;main.moc&quot;

huangapple
  • 本文由 发表于 2023年5月22日 18:22:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76305195.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定