Qt之视图QTableView

  Qt引入了模型/视图结构用于完成数据与界面的分离,即InterView框架。InterView框架把视图和控制器部件结合在一起,使得框架更为简洁。
 Qt的模型/视图结构分为三部分:模型(Model)、视图(View)和代理(Delegate)。模型与数据源通信,并为其他部件提供接口;视图从模型中获得用来引用数据条目的模型索引。在视图中,代理负责绘制数据条目,当编辑条目时,代理和模型直接进行通信。模型/视图/代理之间通过信号和槽进行通信。
 本文主要展示模型数据加载、视图显示和代理操作三部分功能。示例显示:
 ![请添加图片描述](https://img-blog.csdnimg.cn/direct/4d68b5328011426fa15ad97773e435fa.gif)

1.模型数据加载

QStandardItemModel m_model;
    m_model.setRowCount(4);
    m_model.setColumnCount(4);
    m_model.setHeaderData(0,Qt::Horizontal,QString::fromLocal8Bit("姓名"));
    m_model.setHeaderData(1,Qt::Horizontal,QString::fromLocal8Bit("生日"));
    m_model.setHeaderData(2,Qt::Horizontal,QString::fromLocal8Bit("职业"));
    m_model.setHeaderData(3,Qt::Horizontal,QString::fromLocal8Bit("收入"));
     QFile file("../SRC/doc/test.txt");
    if(file.open(QFile::ReadOnly|QFile::Text))
    {
        QTextStream stream(&file);
        QString line;
        m_model.removeRows(0,m_model.rowCount(QModelIndex()),QModelIndex());
        int row = 0;
        do
        {
            line = stream.readLine();
            if(!line.isEmpty())
            {
                m_model.insertRows(row,1,QModelIndex());
                QStringList pieces = line.split(",",QString::SkipEmptyParts);
                m_model.setData(m_model.index(row,0,QModelIndex()),pieces.value(0));
                m_model.setData(m_model.index(row,1,QModelIndex()),pieces.value(1));
                m_model.setData(m_model.index(row,2,QModelIndex()),pieces.value(2));
                m_model.setData(m_model.index(row,3,QModelIndex()),pieces.value(3));
                row++;
            }
        }while(!line.isEmpty());
        file.close();
    }

2.视图显示

ui->tableView->setModel(&m_model);
QHeaderView* headerView = ui->tableView->horizontalHeader();
headerView->setSectionResizeMode(QHeaderView::Interactive);

3.代理操作

    DateDelegate m_dateDelegate;
    ComboDelegate m_comboDelegate;
    SpinDelegate m_spinDelegate;
    ui->tableView->setItemDelegateForColumn(1,&m_dateDelegate);
    ui->tableView->setItemDelegateForColumn(2,&m_comboDelegate);
    ui->tableView->setItemDelegateForColumn(3,&m_spinDelegate);

3.1时间日历代理

构建项目DataDelegate,使用手动的方式实现对生日的录入编辑。

class DateDelegate:public QItemDelegate
{
    Q_OBJECT
public:
    DateDelegate(QObject *parent = nullptr);
    //完成创建控件的工作
    QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index)const;
    //设置控件显示的数据,将Model中的数据更新至Delegate中
    void setEditorData(QWidget *editor,const QModelIndex &index)const;
    void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index)const;
    void updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index)const;
};
DateDelegate::DateDelegate(QObject *parent):QItemDelegate(parent)
{

}
QWidget *DateDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    //新建QDateTimeEdit对象
    QDateTimeEdit *editor = new QDateTimeEdit(parent);
    editor->setDisplayFormat("yyyy-MM-dd");
    editor->setCalendarPopup(true);//以Popup的方式显示日历
    editor->installEventFilter(const_cast<DateDelegate*>(this));//安装事件过滤器,使DateDelegate能够捕获QDateTimeEdit对象
    return editor;
}
void DateDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QString dateStr = index.model()->data(index).toString();//获取指定index数据项的数据
    QDate date = QDate::fromString(dateStr,Qt::ISODate);//转换QString类型表示的日期数据转换为QDate类型
    QDateTimeEdit *edit = static_cast<QDateTimeEdit*>(editor);
    edit->setDate(date);
}
void DateDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QDateTimeEdit *edit = static_cast<QDateTimeEdit*>(editor);//获取编辑控件的对象指针
    QDate date = edit->date();//获取编辑控件中的数据更新
    model->setData(index,QVariant(date.toString(Qt::ISODate)));//调用setDate()函数将数据更新到Model中
}
void DateDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);
}

3.2下拉框代理

构建项目ComboDelegate,使用手动的方式实现对职业的录入编辑

class ComboDelegate:public QItemDelegate
{
    Q_OBJECT
public:
    ComboDelegate(QObject *parent = nullptr);
    //完成创建控件的工作
    QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index)const;
    //设置控件显示的数据,将Model中的数据更新至Delegate中
    void setEditorData(QWidget *editor,const QModelIndex &index)const;
    void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index)const;
    void updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index)const;
};
ComboDelegate::ComboDelegate(QObject *parent):QItemDelegate(parent)
{

}
QWidget *ComboDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    //创建QComboBox控件
    QComboBox *editor = new QComboBox(parent);
    editor->addItem("工人");
    editor->addItem("农民");
    editor->addItem("医生");
    editor->addItem("律师");
    editor->addItem("军人");
    editor->installEventFilter(const_cast<ComboDelegate*>(this));
    return editor;
}
void ComboDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QString str = index.model()->data(index).toString();
    QComboBox *box = static_cast<QComboBox*>(editor);
    int i = box->findText(str);
    box->setCurrentIndex(i);
}
void ComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QComboBox *box = static_cast<QComboBox*>(editor);
    QString str = box->currentText();
    model->setData(index,str);
}

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

3.3输入框代理

构建项目ComboDelegate,使用手动的方式实现对收入的录入编辑。

class SpinDelegate:public QItemDelegate
{
    Q_OBJECT
public:
    SpinDelegate(QObject *parent = nullptr);
    //完成创建控件的工作
    QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index)const;
    //设置控件显示的数据,将Model中的数据更新至Delegate中
    void setEditorData(QWidget *editor,const QModelIndex &index)const;
    void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index)const;
    void updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index)const;
};
SpinDelegate::SpinDelegate(QObject *parent):QItemDelegate(parent)
{

}
QWidget *SpinDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QSpinBox *spinBox = new QSpinBox(parent);
    spinBox->setRange(0,10000);
    spinBox->installEventFilter(const_cast<SpinDelegate*>(this));
    return spinBox;
}
void SpinDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    int value = index.model()->data(index).toInt();
    QSpinBox *box = static_cast<QSpinBox*>(editor);
    box->setValue(value);
}
void SpinDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QSpinBox *box = static_cast<QSpinBox*>(editor);
    int value = box->value();
    model->setData(index,value);
}
void SpinDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值