显示已启用QCheckBox已禁用

时间:2012-11-22 10:42:40

标签: c++ qt qtreeview qcheckbox

我使用带有TreeModel的QTreeView(继承了QAbstractItemModel)。 TreeModel :: flags()函数返回Qt :: ItemIsUserCheckable,因此除了视图中的每个项目外都会显示一个复选框。 我需要做的是在未选中父项但是用户必须能够正常与其进行交互时显示禁用的复选框(必须启用该复选框)。

我尝试实现自定义QStyledItemDelegate并自己绘制复选框。但是,在委托的draw()函数中绘制复选框时,我不知道如何使用自定义图像。我甚至不知道这是否是正确的方法。

我还想过以某种方式使用样式表,但是复选框的显示取决于模型数据(如果选中了父项)。

任何想法?

这是我的ItemDelegate :: paint()函数。

void ItemDelegate::paint(QPainter *painter,
                         const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    int value = index.model()->data(index, Qt::DisplayRole).toInt();

    QStyleOptionButton check_box_style_option;

    check_box_style_option.state |= QStyle::State_Enabled;

    if (value == 1)
        check_box_style_option.state |= QStyle::State_On;
    else
        check_box_style_option.state |= QStyle::State_Off;

    check_box_style_option.rect = option.rect;


    QApplication::style()->drawControl(QStyle::CE_CheckBox,
                                       &check_box_style_option, painter);
}

[编辑] TreeModel代码。树模型基于“simpletreemodel”示例。我更改了flags()以返回Qt :: ItemIsUserCheckable和data(),setData()以启用复选框以进行检查和取消选中。

#include <QtGui>
#include <QDebug>
#include "treeitem.h"
#include "treemodel.h"

TreeModel::TreeModel(Container *data, QObject *parent)
    : QAbstractItemModel(parent)
{
    root_item_ = new TreeItem("");
    SetupModelData(data, root_item_);
}

TreeModel::~TreeModel()
{
    delete root_item_;
}

int TreeModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
    else
        return root_item_->columnCount();
}

QVariant TreeModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    TreeItem *item = static_cast<TreeItem*>(index.internalPointer());

    if(role == Qt::CheckStateRole && index.column() == 0)
        return static_cast<int>(item->checked()) ? Qt::Checked : Qt::Unchecked;

    if(role != Qt::DisplayRole)
        return QVariant();

    return item->data(index.column());
}

bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    TreeItem *item = static_cast<TreeItem*>(index.internalPointer());

    if(role == Qt::CheckStateRole)
        item->set_checked(!item->checked());

    if(role == Qt::EditRole)
    {
        qDebug() << "value:" << value.toString();
        item->set_data(value.toString());
    }

    emit dataChanged(index, index);

    return true;
}

Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return 0;

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
}

QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
                               int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
        return root_item_->data(section);

    return QVariant();
}

QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
            const
{
    if (!hasIndex(row, column, parent))
        return QModelIndex();

    TreeItem *parentItem;

    if (!parent.isValid())
        parentItem = root_item_;
    else
        parentItem = static_cast<TreeItem*>(parent.internalPointer());

    TreeItem *childItem = parentItem->child(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}

QModelIndex TreeModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

    TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
    TreeItem *parentItem = childItem->parent();

    if (parentItem == root_item_)
        return QModelIndex();

    return createIndex(parentItem->row(), 0, parentItem);
}

int TreeModel::rowCount(const QModelIndex &parent) const
{
    TreeItem *parentItem;
    if (parent.column() > 0)
        return 0;

    if (!parent.isValid())
        parentItem = root_item_;
    else
        parentItem = static_cast<TreeItem*>(parent.internalPointer());

    return parentItem->childCount();
}

void TreeModel::SetupModelData(Container *data, TreeItem *parent)
{
    TreeItem *new_item = new TreeItem(data->id(), parent);
    data->set_tree_item(new_item);
    parent->appendChild(new_item);

    foreach(Container *child, data->children())
        SetupModelData(child, new_item);
}

0 个答案:

没有答案