QStyledItemDelegate类的使用

之前在开发项目的时候遇到一个问题,如下图所示:


我在ui界面上设置了这个ComboBox的item的CSS样式之后,但是在调试的时候,总是没有效果。于是,自己翻看帮助文档。如果不使用QML的话, 只能使用QStyledItemDelegate这个类来修改item的样式。

帮助文档对QStyledItemDelegate类的描述:

The QStyledItemDelegate class provides display and editing facilities for data items from a model.

When displaying data from models in Qt item views, e.g., a QTableView, the individual items are drawn by a delegate. Also, when an item is edited, it provides an editor widget, which is placed on top of the item view while editing takes place. QStyledItemDelegate is the default delegate for all Qt item views, and is installed upon them when they are created.

The QStyledItemDelegate class is one of the Model/View Classes and is part of Qt's model/view framework. The delegate allows the display and editing of items to be developed independently from the model and view.

The data of items in models are assigned an ItemDataRole; each item can store a QVariant for each role. QStyledItemDelegate implements display and editing for the most common datatypes expected by users, including booleans, integers, and strings.

翻译:

QStyledItemDelegate 这个类提供了显示和编辑items数据的模型。

在Qt的项目视图显示数据时,个人数据是通过代理来描绘出来的,例如QTableView.当一个item被编辑的时候,它提供了一个控件,这个控件代替了你正在编辑的这个区域。QStyledItemDelegate这个类是所有Qt的item视图的默认代理,同时也是在控件被创建的时候默认的安装上的。

QStyledItemDelegate类是Qt模型/视图框架的一部分。它允许开发人员使用自己开发的模型/视图来显示和编辑items.

items是通过ItemDataRole来进行分发的。每一个item能够存储QVariant中的所有角色。QStyledItemDelegate 类实现了数据被用户所期望的显示与编辑样式,包括布尔类型,整型,字符串等等。

所以经过我的理解,我认为,这个QStyledItemDelegate是一个样式的代理类。它可以将你写好的样式直接显示出来。

Delegate  类
概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件。一般来讲, view负责把数据展示给用户,也处理用户的输入。为了获得更多的灵性性,交互通过delegagte执行。它既提供输入功能又负责渲染view中的每个数据项。 
使用Delegate的原因  Qt中当用到QTreeView和QTableView等用于显示item的视图时,你要编辑一个item用到的编辑工具可能是除了默认文字编辑lineEdit以外的工具,例如button,spinBox,甚至Slider,ProgressBar,也有可能是自定义的widget。所以Qt提供了一个委托类,用来处理View中的数据展示方式。

Delegate类的继承架构见下图:


自从Qt4.4,出现了两个delegate基类,QStyledItemDelegate vs. QItemDelegate。默认的delegate是QStyledItemDelegate,即你不自己写delegate的时候,默认那个lineEdit是来自QStyledItemDelegate。Qt Assistant建议用户如果自定义delegate或者用到了Qt style sheets的话,最好继承自QStyledItemDelegate,为什么呢?首先这两个类在绘制代理和为item提供编辑器上面是独立的,没什么联系,互不影响;不同的是QStyledItemDelegate使用当前style来绘制item(的代理),即如果程序设置了总体的风格(用QSS或其他定义方式),QStyledItemDelegate会使用这个风格设置。


先看看Qt Demos看了里面spinboxDelegat的例子:
1. 自定义的delegate继承自QItemDelegate。


2. 必须重载的一些函数:
       (1)  QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const;
       (2)  void setEditorData(QWidget *editor, const QModelIndex &index) const;
       (3)  void setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex &index) const;
       (4)  void updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option, const QModelIndex &index) const;


3. createEditor创建自定义widget并返回之。
        setEditorData是将model中当前有的数据设置到代理上。自己从model取出数据,自己setValue到editor上。
        setModelData是将editor上的数据保存到Model中。
        updateEditorGeometry就是将editor设置到一定位置,并且有一定大小,使这个editor看起来像是正好嵌入到格子里面一样。用的是option.rect。


4. closeEditor() signal 表明用户完成编辑数据,编辑控件可以销毁。


5. commitData() signal 必须在完成编辑数据之后,发送该信号,将会把新数据写回Model


6. paint() and sizeHint(), QitemDelegate默认继承了该方法,如果需要特殊风格绘制单元项中内容,还需重载这两个函数。

我们知道,在经典的 MVC 模型中,view用于向用户展示 model 的数据。但是,Qt提供的不是 MVC 三层架构,而是一个 model/view 设计。这种设计并没有包含一个完整而独立的组件用于管理用户的交互。一般来说,view仅仅是用作对model数据的展示和对用户输入的处理,而不应该去做其他的工作。在这种结构中,为了获得对用户输入控制的灵活性,这种交互工作交给了delegate,也就是“委托”,去完成。简单来说,就像它们的名字一样,view 将用户输入委托给 delegate 处理,而自己不去处理这种输入。这些组件提供一种输入能力,并且能够在某些 view 中提供这种交互情形下的渲染,比如在 table 中通过双击单元格即可编辑内容等。对这种控制委托的标准接口被定义在 QAbstractItemDelegate 类中。
 
delegate 可以用于渲染内容,这是通过 paint() 和 sizeHint() 函数来完成的。但是,对于一些简单的基于组件的delegate,可以通过继承 QItemDelegate 或者 QStyledItemDelegate 来实现。这样就可以避免要完全重写 QAbstractItemDelegate 中所需要的所有函数。对于一些相对比较通用的函数,在这两个类中已经有了一个默认的实现。
 
Qt提供的标准组件使用 QItemDelegate 提供编辑功能的支持。这种默认的实现被用在 QListView,QTableView 和 QTreeView 之中。view 实用的delegate可以通过 itemDelegate() 函数获得。setItemDelegate() 函数则可以为一个标准组件设置自定义的 delegate。
 
Qt 4.4版本之后提供了两个可以被继承的delegate类:QItemDelegate 和 QStyledItemDelegate。默认的delegate是 QStyledItemDelegate。这两个类可以被相互替代,用于给view 组件提供绘制和编辑的功能。它们之间的主要区别在于,QStyledItemDelegate 使用当前的风格(style)去绘制组件。所以,在自定义delegate或者需要使用 Qt style sheets 时,建议使用 QStyledItemDelegate 作为父类。使用这两个类的代码通常是一样的,除了需要使用style进行绘制的部份。如果你希望为view item自定义绘制函数,最好实现一个自定义的style。这个你可以通过QStyle类来实现。
 
如果delegate没有支持为你的数据类型进行绘制,或者你希望自己绘制item,那么就可以继承 QStyledItemDelegate 类,并且重写 paint() 或者还需要重写 sizeHint() 函数。paint() 函数会被每一个item独立调用,而sizeHint()函数则可以定义每一个item 的大小。在重写 paint() 函数的时候,通常需要用 if 语句找到你需要进行渲染的数据类型并进行绘制,其他的数据类型需要调用父类的实现进行绘制。
 
一个自定义的delegate也可以直接提供一个编辑器,而不是使用内置的编辑器工厂(editor item factory)。如果你需要这种功能,那么需要实现一下几个函数:
createEditor(): 返回修改数据的组件;
setEditorData(): 为editor提供编辑的原始数据;
updateEditorGeometry(): 保证editor显示在 item view 的合适位置以及大小;
setModelData(): 根据editor 的数据更新model的数据。

所以,之前的问题解决了,我在ui界面进行构造的时候增加了这几行代码:

    itemDelegate = new QStyledItemDelegate();
    ui->platComboBox->setItemDelegate(itemDelegate);
    ui->methodComboBox->setItemDelegate(itemDelegate);

然后效果就能显示出来了。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值