Qt 通过Delegate方式将QTableView 中指定项扩展为自定义类型,QComboBox转变为可checked选项

在 Qt 中,可以通过自定义代理(QAbstractItemDelegate、QStyledItemDelegate 或其派生类)的方式,将 QTableView 中的指定项扩展为自定义类型控件。下面以将指定列的单元格扩展为 QComboBox 为例,详细介绍实现步骤和示例代码。

实现思路

  1. 自定义代理类:继承自 QStyledItemDelegate,重写其关键虚函数,如 createEditorsetEditorDatasetModelData
  2. 设置代理:将自定义代理应用到 QTableView 的指定列或行;
#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
#include <QComboBox>
#include <QWidget>
#include <QVBoxLayout>

class ComboBoxModel;

// 自定义代理类
class ComboBoxDelegate : public QStyledItemDelegate {
    Q_OBJECT
public:
    ComboBoxDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}

    // 创建编辑器
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
        QComboBox *editor = new QComboBox(parent);

        //接下来可以向editor中添加项,可以通过index传入的数据进行添加,这样更灵活;
        //此处先以较简单的方式进行添加(通过组态模型的方式进行添加)
        ComboBoxModel *config = new ComboBoxModel();
        config->addItem(QString("Option 1"));
        config->addItem(QString("Option 2"));
        config->addItem(QString("Option 3"));
        config->setCheckable();

        QComboBox *editor = new QComboBox(parent);
        editor->setModel(config);
        return editor;
    }

    // 将模型中的数据设置到编辑器中
    void setEditorData(QWidget *editor, const QModelIndex &index) const override {
        QComboBox *comboBox = static_cast<QComboBox*>(editor);
        QString value = index.model()->data(index, Qt::EditRole).toString();
        int comboIndex = comboBox->findText(value);
        if (comboIndex != -1) {
            comboBox->setCurrentIndex(comboIndex);
        }
    }

    // 将编辑器中的数据保存到模型中,通过设置模型数据的方式可以修改QTableView对应(row,col)中的值
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override {
        ComboBoxModel *modelMy = qobject_cast<ComboBoxModel*>(editor->model());
        QStringList list = modelMy->getCheckedItems();
        QString value = list.join(',');
        model->setData(index, value, Qt::EditRole);
    }

};

class ComboBoxModel : public QStandardItemModel
{
    Q_OBJECT
public:
    ComboBoxModel(QObject *parent = nullptr){};

    void addItem(QString &name)
    {
        QStandardItem *item = new QStandardItem(name);
        appendRow(item);
    }
    void addItems(QStringList &list)
    {
        for(const auto &text : list)
        {
            QStandardItem *item = new QStandardItem(text);
            appendRow(item);
        }
    }

    void setCheckable()
    {
        int rows = rowCount();
        for (int i = 0; i < rows; ++i)
        {
            QStandardItem *item = takeItem(i);
            item ->setData(Qt::Unchecked, Qt::CheckStateRole);
            item ->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
        }
    }

    QStringList getCheckedItems()
    {
        QStringList options;
        int rows = rowCount();
        for (int i = 0; i < rows; ++i)
        {
            QStandardItem *item = takeItem(i);
            if(item->data(Qt::CheckStateRole) == Qt::Checked)
                {
            options.append(item->text());
            }
        }

        return options;
    }  
};


int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建模型
    QStandardItemModel model(4, 2);
    model.setHorizontalHeaderLabels({"Column 1", "Column 2"});

    // 创建表格视图
    QTableView tableView;
    tableView.setModel(&model);

    // 创建并设置代理
    ComboBoxDelegate delegate;
    // 将代理应用到第二列
    tableView.setItemDelegateForColumn(1, &delegate);

    // 显示表格视图
    tableView.show();

    return app.exec();
}

#include "main.moc"

代码解释

  • createEditor 函数:当用户开始编辑指定列的单元格时,该函数会被调用,用于创建并返回一个 QComboBox 作为编辑器。在函数中,为 QComboBox  添加了几个选项。
  • setEditorData 函数:此函数将模型中的数据设置到编辑器中。通过 index.model()->data(index, Qt::EditRole) 获取模型中的数据,然后使用 comboBox->findText 查找该数据在 QComboBox 中的索引,并设置当前索引。
  • setModelData 函数:当用户完成编辑后,该函数会被调用,用于将编辑器中的数据保存到模型中。通过 comboBox->currentText 获取当前选择的文本,然后使用 model->setData 将其保存到模型中。
  • 创建模型和表格视图:使用 QStandardItemModel 创建一个模型,并设置水平表头标签。然后创建一个 QTableView 并将模型设置给它。
  • 创建并设置代理:创建 ComboBoxDelegate 实例,并使用tableView.setItemDelegateForColumn 将其设置为表格视图第二列的代理。
  • ComboBoxModel类: 是实现QComboBox的组态模型类,可以通过此类为QComboBox进行初始化赋值,及相关属性参数设置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值