带有QCheckbox的QAbstractModel,带有开/关状态图标

时间:2016-12-01 12:01:43

标签: c++ qt

我有一个QTableView,我填充了QAbstractTableModel。一列,比如第三列,应该包含一个QCheckBox,我想为其显示两个图标,而不是QCheckBox的标准外观,on状态的一个图标和另一个off州。

为此,我从QAbstractTableModel派生了一个模型,并从QStyledItemDelegate派生了一个委托。问题是我的模型setData从未被调用过,唯一出现的图标就是off。以下是我的测试实现的一些代码片段

MyModel.h

#ifndef MYMODEL_H
#define MYMODEL_H

#include <vector>
#include <QAbstractTableModel>

class MyModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit MyModel(QObject *parent = 0);

    int rowCount(const QModelIndex &parent) const override;

    int columnCount(const QModelIndex &parent) const override;

    QVariant headerData(int section, Qt::Orientation orientation, int role) const override;

    QVariant data(const QModelIndex &index, int role) const override;

    bool indexIsValid(const QModelIndex& index) const;

    Qt::ItemFlags flags(const QModelIndex &index) const override;

    bool setData(const QModelIndex& index, const QVariant& value, int role) override;

private:
    std::vector<bool> _states;

};

#endif // MYMODEL_H

MyModel.cpp

#include "MyModel.h"

MyModel::MyModel(QObject *parent) : QAbstractTableModel(parent)
{
    _states.resize(5,false);
}

int MyModel::rowCount(const QModelIndex &parent) const
{
    return 4;
}

int MyModel::columnCount(const QModelIndex &parent) const
{
    return 3;
}

QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role != Qt::DisplayRole)
        return QVariant();

    if (orientation == Qt::Horizontal)
        return QString("Col");

    return QVariant();
}

QVariant MyModel::data(const QModelIndex &index, int role) const
{

    if (!indexIsValid(index))
        return QVariant();

    if (role==Qt::DisplayRole)
    {
        if (index.column() != 2)
            return QString("blabla");
    }
    else if (role==Qt::CheckStateRole)
    {
        if (index.column() == 2)
        {
            Qt::CheckState state = _states[index.row()] ? Qt::Checked : Qt::Unchecked;
            return state;
        }
    }
    return QVariant();
}

bool MyModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
    if (!indexIsValid(index))
        return false;

    if (role==Qt::CheckStateRole)
    {
        {
            if (index.column()==2)
                _states[index.row()] = value.toBool();
        }
    }

    emit dataChanged(index,index);

    return true;
}

bool MyModel::indexIsValid(const QModelIndex& index) const
{
    return index.isValid() && index.row() < 5;
}

Qt::ItemFlags MyModel::flags(const QModelIndex &index) const
{
    if (!indexIsValid(index))
        return Qt::ItemIsEnabled;

    if (index.column() == 2)
        return QAbstractTableModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;

    return QAbstractTableModel::flags(index);

}

MyDelegate.h

#ifndef MYDELEGATE_H
#define MYDELEGATE_H

#include <QStyledItemDelegate>
#include <QModelIndex>
#include <QObject>
#include <QSize>
#include <QSpinBox>
#include <QIcon>

class MyDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit MyDelegate(QObject *parent = 0);

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;

private:

    QIcon _icon;
};
#endif // MYDELEGATE_H

MyDelegate.cpp

#include "MyDelegate.h"
#include <QCheckBox>
#include <QPainter>

#include <QApplication>
#include <QStyleOptionViewItem>

MyDelegate::MyDelegate(QObject *parent) :
    QStyledItemDelegate(parent)
{
    _icon.addPixmap(QPixmap(":/selected.png"), QIcon::Normal, QIcon::On);
    _icon.addPixmap(QPixmap(":/deselected.png"), QIcon::Normal, QIcon::Off);
}

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{

    if (index.column() != 2)
        QStyledItemDelegate::paint(painter,option,index);
    else
    {
        bool value = index.model()->data(index).toBool();
        QStyleOptionButton buttonVis;
        buttonVis.rect = option.rect;
        buttonVis.iconSize = QSize(10,10);
        buttonVis.icon = _icon;
        buttonVis.state |= QStyle::State_Enabled;
        buttonVis.state |= value? QStyle::State_On : QStyle::State_Off;
        buttonVis.features = QStyleOptionButton::None;
        QApplication::style()->drawControl(QStyle::CE_PushButton,&buttonVis, painter);
    }
}

你对我错过了什么让它有用吗?

0 个答案:

没有答案