您当前的位置: 首页 >  qt

lw只吃亿点.

暂无认证

  • 5浏览

    0关注

    47博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Qt代理的实现(常规控件篇,含源码+注释)

lw只吃亿点. 发布时间:2021-12-26 22:35:49 ,浏览量:5

文章目录
  • 一、QSpinBox控件示例图
  • 二、常规控件解释(个人理解)
  • 三、需要实现的类及其内容
  • 四、使用方法
  • 五、QSpinBox控件源码(定义、调用)
    • CSpinBoxDelegate类
      • CSpinBoxDelegate.h
      • CSpinBoxDelegate.cpp
    • CMainWindow调用类
      • CMainWindow.h
      • CMainWindow.cpp
  • 总结
  • 相关文章

一、QSpinBox控件示例图

下图为QSpinBox代理控件的实现,源码在本文第五节(源码含详细注释) 在这里插入图片描述

二、常规控件解释(个人理解)

这类控件主要有如下操作:

  1. 创建对应的对象指针并返回
  2. 获取包含代理的item值,并将其设置到控件上
  3. 获取控件的值,并将其设置到相应的item上
  4. 设置控件的显示位置

这种类型的控件代表主要有输入框、日期/时间框、进度条、轮选框等

三、需要实现的类及其内容
//1.创建相应的控件指针并返回。(每次双击包含代理的item就会调用一次此函数)
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
//参数作用
// parent:指定控件的父控件
// option:在创建控件中可以获取其rect来设置控件的绘制区域(如果这样设置,updateEditorGeometry函数可以不用,本人实测有效)。
// index:在创建控件时同样可以直接使用该参数的data将值设置到创建的控件中(如果这样设置,setEditorData函数可以不用,本人实测有效)。

//2.从传入的index获取值,设置相应控件的值。(当相应控件创建后会调用一次函数;在退出代理控件的时候也会调用该函数。)
void setEditorData(QWidget *editor, const QModelIndex &index) const
//参数作用
// editer: 获取自己创建的控件指针(需要强转,可以使用dynamic_cast()转换)
// index:使用该参数的data将值设置到强转的控件中

//3.通过控件指针获取值,设置相应的item的值。(当退出代理控件的时候会调用该函数。)
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
//参数作用
// editor:获取控件中的值(该值用于设置到item中)
// model:通过index获取当前item从而设置值
// index:配合model获取当前item

//4.设置控件的显示位置(在创建后会调用一次)
//如果该函数没有任何内容,绘制的控件将会绘制在QTableView对象的左上角(当需求方是QTableView时,在创建控件时的option也可以获取rect来设置绘画区域)
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
//参数作用
// editor:获取自己创建的控件指针(需要强转,可以使用dynamic_cast()转换)
// option:获取rect从而设置其绘制的位置
四、使用方法

使用时像按钮代理那样直接使用相应View对象的setModel函数将代理设置到相应位置即可,双击相应item会自动显示出来

五、QSpinBox控件源码(定义、调用) CSpinBoxDelegate类 CSpinBoxDelegate.h
#ifndef CSPINBOXDELEGATE_H
#define CSPINBOXDELEGATE_H

#include 
#include 
#include 
class CSpinBoxDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit CSpinBoxDelegate(QStyledItemDelegate *parent = nullptr);
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    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;
};
#endif // CSPINBOXDELEGATE_H
CSpinBoxDelegate.cpp
#include "CSpinBoxDelegate.h"
#include 

CSpinBoxDelegate::CSpinBoxDelegate(QStyledItemDelegate *parent) : QStyledItemDelegate(parent)
{

}

QWidget *CSpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    //一定要指定父类,否则创建的控件将会显示独立窗口
    QSpinBox *spinBox = new QSpinBox(parent);
    return spinBox;
}

void CSpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    //拿到创建的QSpinBox控件
    QSpinBox *spinBox = dynamic_cast(editor);
    //获取当前item的值
    int value = index.data().toInt();
    spinBox->setValue(value);
}

void CSpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    //拿到创建的QSpinBox控件
    QSpinBox *spinBox = dynamic_cast(editor);
    //通过传入的model和index变量将值设置到当前item上
    model->setData(index, spinBox->value());
}

void CSpinBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    //拿到创建的QSpinBox控件
    QSpinBox *spinBox = dynamic_cast(editor);
    //设置控件的显示位置
    spinBox->setGeometry(option.rect);
}
CMainWindow调用类 CMainWindow.h
#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H

#include 
#include 
#include 
namespace Ui {
class CMainWindow;
}

class CMainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit CMainWindow(QWidget *parent = 0);
    ~CMainWindow();
private:
    Ui::CMainWindow *ui;
    QStandardItemModel  *m_model;   //tableView的模板变量
    CSpinBoxDelegate    *m_delegate;    //tableView的代理变量
};
#endif // CMAINWINDOW_H
CMainWindow.cpp
#include "CMainWindow.h"
#include "ui_CMainWindow.h"

CMainWindow::CMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::CMainWindow)
{
    ui->setupUi(this);
    //创建view模型对象
    m_model = new QStandardItemModel;
    //添加标题
    m_model->setHorizontalHeaderLabels(QStringList() setItem(index, 1, new QStandardItem(QString("第%1列第2列").arg(index)));
        m_model->setItem(index, 2, new QStandardItem(QString("%1").arg(index)));
    }
}

CMainWindow::~CMainWindow()
{
    delete m_delegate;
    delete m_model;
    delete ui;
}
总结

常规控件主要适合双击显示的代理(不需要保持显示在界面上的控件),如单选按钮、复选按钮等如此实现出来会感觉缺点东西,并且设置的控件获取和设置值也需符合代理设定,

相关文章

Qt代理的实现(按钮篇,含源码+注释) Qt之QTableView的简单使用(含源码+注释) Qt之QTableView设置多列表头复选框(自定义QHeaderView)、单元格复选框(含源码+注释) Qt之QSortFilterProxyModel的简单使用(QTableView搜索功能,含源码+注释) Qt之QTreeView的简单使用(含源码+注释) Qt之QListView的简单使用(含源码+注释)

友情提示——哪里看不懂可私哦,让我们一起互相进步吧 (创作不易,请留下一个免费的赞叭 谢谢 ^o^/)

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。 注:如有侵权,请联系作者删除

关注
打赏
1654352885
查看更多评论
立即登录/注册

微信扫码登录

0.1781s