做网站还需要买空间吗,境外服务器代理平台,外国做美食视频网站,关键词快速排名平台目录 1 我们为什么要使用自定义代理类#xff1f; 2 自定义代理类的基本设计要求 3 自定义代理的功能 4 基于QSpinBox的自定义代理类 5 自定义代理类的使用 1 我们为什么要使用自定义代理类#xff1f; 传统的模型-视图框架可以让我们实现逻辑展示相分离#xff0c;我们… 目录 1 我们为什么要使用自定义代理类 2 自定义代理类的基本设计要求 3 自定义代理的功能 4 基于QSpinBox的自定义代理类 5 自定义代理类的使用 1 我们为什么要使用自定义代理类 传统的模型-视图框架可以让我们实现逻辑展示相分离我们只需要关心模型就可以在模型上做的任何更改都会走动更新到视图上去其实就是观察者模式。Qt基于传统的模型-视图框架MVCmodel、view、controler推出了MVD(model、view、delegate)框架。具体有什么用呢 如果我们使用QTableView来作为表格控件显示数据但是突然有需求需要在里面添加一些交互的控件例如按钮、进度条之类的直接使用模型是无法实现的。可以使用QTableWidget控件可以很轻松的实现但是这个不支持模型-视图框架。代理的作用就来了代理可以把控件委托给模型来代理就可以实现在表格中添加控件进行交互了。 2 自定义代理类的基本设计要求 Qt中有关代理的几个类的层次结构如图5-12所示。 QAbstractItemDelegate是所有代理类的抽象基类QStyledItemDelegate是视图组件使用的缺省的代理类QItemDelegate也是类似功能的类。QStyledItemDelegate与QItemDelegate的差别在于QstyledltemDelegate可以使用当前的样式表设置来绘制组件因此建议使用QStyledItemDelegate作为自定义代理组件的基类。 不管从QStyledItemDelegate还是QItemDelegate继承设计自定义代理组件都必须实现如下 的4个函数 createEditor()函数创建用于编辑模型数据的widget组件如一个QSpinBox组件或一个 QComboBox组件 setEditorData()函数从数据模型获取数据供widget组件进行编辑 setModelData()将widget上的数据更新到数据模型 updateEditorGeometry()用于给widget组件设置一个合适的大小。 3 自定义代理的功能 在实例samp5_3中导入数据文件进行编辑时QTableView组件为每个单元格提供的 是缺省的代理编辑组件就是一个QLineEdit组件。在编辑框里可以输入任何数据所以比较通用。 但是有些情况下希望根据数据的类型限定使用不同的编辑组件例如在samp5_3的实例的数据中 第1列“测深”是整数使用QSpinBox作为编辑组件更合适“垂深”“方位”“总位移”是浮点数 使用QDoubleSpinBox更合适而“固井质量”使用 一个QComboBox从一组列表文字中选择更合适。 要实现这些功能就需要为TableView的某列 或某个单元格设置自定义代理组件。本节在实例 samp5_3的基础上为TableView增加自定义代理 组件功能。设定自定义代理组件之后的TableView 运行时其编辑状态的效果如图5-11所示。 图5-11 设置自定义代理组件后的TableView编辑时的效果 4 基于QSpinBox的自定义代理类 1、自定义代理类的基本结构 下面设计一个基于QSpinBox类的自定义代理类用于“测深”数据列的编辑。 定义一个自定义类的名称为QWIntSpinDelegate设置基类为QStyledItemDelegate添加到项目里。在头文件qwintspindelegate.h中包含对自定义类QWIntSpinDelegate的定义在其中添加4个需要重定义的函数的定义qwintspindelegate.h的内容如下 #include QStyledItemDelegate
class QWIntSpinDelegate : public QStyledItemDelegate
{Q_OBJECT
public:QWIntSpinDelegate(QObject *parent0);
//自定义代理组件必须继承以下4个函数
//创建编辑组件QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem option,const QModelIndex index) const Q_DECL_OVERRIDE;
//从数据模型获取数据显示到代理组件中void setEditorData(QWidget *editor, const QModelIndex index) const Q_DECL_OVERRIDE;
//将代理组件的数据保存到数据模型中void setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex index) const Q_DECL_OVERRIDE;
//更新代理编辑组件的大小void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem option,const QModelIndex index) const Q_DECL_OVERRIDE;
}; 自定义代理组件必须重新实现这4个函数函数的原型都是固定的。 2、createEditor()函数的实现 createEditor()函数用于创建需要的编辑组件QWIntSpinDelegate类希望创建一个QSpinBox作为编辑组件函数的实现如下 QWidget *QWIntSpinDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem option, const QModelIndex index) const
{ //创建代理编辑组件QSpinBox *editor new QSpinBox(parent); //创建一个QSpinBoxeditor-setFrame(false); //设置为无边框editor-setMinimum(0);editor-setMaximum(10000);return editor; //返回此编辑器
} 这段代码创建了一个QSpinBox类型的编辑器editorparent指向视图组件然后对创建的editor做一些设置将editor作为函数的返回值。 3、setEditorData()函数 setEditorData()函数用于从数据模型获取数值设置为编辑器的显示值。当双击一个单元格进入编辑状态时就会自动调用此函数其实现代码如下 void QWIntSpinDelegate::setEditorData(QWidget *editor,const QModelIndex index) const
{//从数据模型获取数据显示到代理组件中
//获取数据模型的模型索引指向的单元的数据int value index.model()-data(index, Qt::EditRole).toInt();QSpinBox *spinBox static_castQSpinBox*(editor); //强制类型转换spinBox-setValue(value); //设置编辑器的数值
} 函数传递来的参数editor指向代理编辑组件index是关联的数据单元的模型索引。通过强制类型转换将editor转换为QSpinBox类型组件spinBox然后将获取的数值设置为spinBox的值。 4、setModeIData()函数 setModelData()函数用于将代理编辑器上的值更新给数据模型当用户在界面上完成编辑时会自动调用此函数将界面上的数据更新到数据模型。其代码如下 void QWIntSpinDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex index) const
{ //将代理组件的数据保存到数据模型中QSpinBox *spinBox static_castQSpinBox*(editor); //强制类型转换spinBox-interpretText(); //解释数据如果数据被修改后就触发信号int value spinBox-value(); //获取spinBox的值model-setData(index, value, Qt::EditRole); //更新到数据模型
} 程序先获取代理组件编辑器里的数值然后利用传递来的数据模型model和模型索引参数index将编辑器的最新值更新到数据模型里。 5、updateEditorGeometry()函数 updateEditorGeometry()函数用于为代理组件设置一个合适的大小函数传递的参数option的rect变量定义了单元格适合显示代理组件的大小直接设置为此值即可。代码如下。 void QWIntSpinDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem option, const QModelIndex index) const
{ //设置组件大小editor-setGeometry(option.rect);
} 5 自定义代理类的使用 同样的可以创建基于QDoubleSpinBox的自定义代理组件类QWFloatSpinDelegate用于编 辑浮点数还可以创建基于QComboBox的自定义组件类QWComboBoxDelegate。在主窗口的类 定义中定义3个代理类的实例变量省略了其他定义内容 class MainWindow : public QMainWindow
{Q_OBJECT
private:QWIntSpinDelegate intSpinDelegate; //整型数QWFloatSpinDelegate floatSpinDelegate; //浮点数QWComboBoxDelegate comboBoxDelegate; //列表选择
} 在MainWindow的构造函数中为tableView的某些列设置自定义代理组件。增加了自定义代理组件的构造函数代码如下去掉了初始化状态栏等一些不重要的内容 MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui-setupUi(this);theModel new QStandardItemModel(2,FixedColumnCount,this); //创建数据模型theSelection new QItemSelectionModel(theModel);//Item选择模型connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));//为tableView设置数据模型ui-tableView-setModel(theModel); //设置数据模型ui-tableView-setSelectionModel(theSelection);//设置选择模型//为各列设置自定义代理组件ui-tableView-setItemDelegateForColumn(0,intSpinDelegate); //测深整数ui-tableView-setItemDelegateForColumn(1,floatSpinDelegate); //浮点数ui-tableView-setItemDelegateForColumn(2,floatSpinDelegate); //浮点数ui-tableView-setItemDelegateForColumn(3,floatSpinDelegate); //浮点数ui-tableView-setItemDelegateForColumn(4,comboBoxDelegate); //Combbox选择型
} 为TableView的某一列设置自定义代理组件使用setltemDelegateForColumn()函数为某一行设置自定义代理组件可使用setltemDelegateForRow()函数若为整个TableView设置一个自定义代理组件则调用setltemDelegate()函数。 如此增加了自定义代理功能后在编辑“测深”列时会在单元格的位置出现一个SpinBox组件用于输入整数在编辑第2至4列的浮点数时会出现一个DoubleSpinBox组件用于输入浮点数而在编辑“固井质量”列时会自动出现一个ComboBox组件用于从下拉列表中选择一个字符串。