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

参考:
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.

相关推荐

  1. Qt5定义信号实现方式

    2024-04-25 14:24:02       16 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-25 14:24:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-25 14:24:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-25 14:24:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-25 14:24:02       18 阅读

热门阅读

  1. 深入解读Dubbo:微服务RPC框架的佼佼者

    2024-04-25 14:24:02       18 阅读
  2. 基于Splinter演示如何使用Chrome WebDriver

    2024-04-25 14:24:02       16 阅读
  3. Debian常用命令

    2024-04-25 14:24:02       16 阅读
  4. 实时交互新篇章:WebSocket在Flutter中的应用与实践

    2024-04-25 14:24:02       15 阅读
  5. Android retrofit使用模板

    2024-04-25 14:24:02       40 阅读
  6. Qt相关开源项目总结

    2024-04-25 14:24:02       13 阅读
  7. QT5.12.12配置MSVC2017编译器环境

    2024-04-25 14:24:02       21 阅读
  8. Qt: windows下关闭系统窗体

    2024-04-25 14:24:02       16 阅读
  9. springBoot Event实现异步消费机制

    2024-04-25 14:24:02       42 阅读