qt5-入门-自定义委托-可编辑的TableModel与信号接收

本文介绍了如何在Qt5环境下,通过自定义QAbstractTableModel和QStyledItemDelegate实现表格项的编辑功能,并利用信号(dataChanged)处理编辑后的内容变化。
摘要由CSDN通过智能技术生成

参考:
C++ GUI Programming with Qt 4, Second Edition

本地环境:
win10专业版,64位,Qt5.12

上一篇:
qt5-入门-自定义委托-简单例子_qt 委托-CSDN博客
https://blog.csdn.net/pxy7896/article/details/137234839


本篇重点在于接收信号。Model做了一点点改动。

效果

每个item都是可以编辑的字符串。
在这里插入图片描述
编辑之后,输出编辑的位置以及改动后的值(前两个数字是row index和column index,第三个是更改后的值)。
在这里插入图片描述

实现

自定义model

class CustomTableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit CustomTableModel(QObject* parent = nullptr)
        : QAbstractTableModel(parent)
    {
        // 初始化数据
        //m_data << 1 << 2 << 3 << 4 << 5;
    }

    void setData(QStringList other) {
        this->m_data = other;
    }

    QStringList getData() {
        return  this->m_data;
    }

    QVariant headerData(int section, Qt::Orientation orientation, int role) const override
    {
        if (role == Qt::DisplayRole)
        {
        	// 这个相当于将行名和列名设置为“”,实际仍然占据空间
        	// 如果要完全隐藏需要用setVisible(false),参见最后1节
            return QVariant();
            /*
            if (orientation == Qt::Horizontal)
            {
                return QVariant(); // 返回空的QVariant,不显示列名
            }
            else
            {
                return QVariant(); // 返回空的QVariant,不显示行名
            }*/
        }
        return QAbstractTableModel::headerData(section, orientation, role);
    }

    int rowCount(const QModelIndex& parent = QModelIndex()) const override
    {
        return m_data.size();
    }

    int columnCount(const QModelIndex& parent = QModelIndex()) const override
    {
        return 1;
    }

    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override
    {
        if (!index.isValid())
            return QVariant();

        if (role == Qt::DisplayRole) {
            return m_data.at(index.row());
        }

        return QVariant();
    }

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

        return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
    }

    bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override
    {
        if (index.isValid() && role == Qt::EditRole) {
            m_data.replace(index.row(), value.toString());
            // 这里发出信号了
            emit dataChanged(index, index);
            return true;
        }

        return false;
    }

private:
    QStringList m_data;
};

自定义delegate

class EditableListItemDelegate : public QStyledItemDelegate
{
public:
    EditableListItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}

    QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override
    {
        return QStyledItemDelegate::sizeHint(option, index);
    }

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

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

    // 设置编辑器内容
    void setEditorData(QWidget *editor, const QModelIndex &index) const override
    {
        QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
        lineEdit->setText(index.model()->data(index).toString());
    }

    // 获取并设置更新后的文本到Model
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
    {
        QLineEdit *lineEdit = qobject_cast<QLineEdit*>(editor);
        model->setData(index, lineEdit->text(), Qt::EditRole);
    }

    void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override
    {
        editor->setGeometry(option.rect);
    }
};

使用

注意:这里的隐藏是指完全隐藏,并非只隐藏内容。

QTableView* tableView = new QTableView;
// 隐藏列名列
tableView->horizontalHeader()->setVisible(false);
// 隐藏行号列 
tableView->verticalHeader()->setVisible(false); 

// 设置代理
EditableListItemDelegate* delegate = new EditableListItemDelegate;
tableView->setItemDelegate(delegate);

// 设置数据
CustomTableModel* model = new CustomTableModel;
model->setData({"1", "2"});
tableView->setModel(model);

// 信号接收
QObject::connect(model, &CustomTableModel::dataChanged, [](const QModelIndex &topLeft, const QModelIndex &bottomRight) {
    qDebug() << "Data changed in model:" << topLeft.row() << topLeft.column() << "-" << bottomRight.data().toString() << endl;
});

tableView->show();

done.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值