目录
1、简述
QComboBox是个很基础的控件,也是继承自QWidget
2、效果
效果是这样的:
3、源代码
3.1、代理类
我们先建立代理类,继承自QStyledItemDelegate:
1、头文件:
#ifndef ITEMDELEGATE_H
#define ITEMDELEGATE_H
#include <QStyledItemDelegate>
class ItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
signals:
void deleteItem(const QModelIndex &index);
public:
ItemDelegate(QObject * parent=0);
virtual ~ItemDelegate(){}
void paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
};
#endif // ITEMDELEGATE_H
2、源文件:
#include "ItemDelegate.h"
#include <QPainter>
#include <QMouseEvent>
#include <QStyledItemDelegate>
#include <QToolTip>
#include <QApplication>
ItemDelegate::ItemDelegate(QObject * parent)
: QStyledItemDelegate(parent)
{
}
void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem viewOption(option);
if (viewOption.state & QStyle::State_HasFocus)
{
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
}
QStyledItemDelegate::paint(painter, viewOption, index);
int height = (viewOption.rect.height() - 9) / 2;
QPixmap pixmap = QPixmap(":/delete");
QRect decorationRect = QRect(viewOption.rect.left() + viewOption.rect.width() - 30, viewOption.rect.top() + height, 9, 9);
painter->drawPixmap(decorationRect, pixmap);
}
bool ItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
int height = (option.rect.height() - 9) / 2;
QRect decorationRect = QRect(option.rect.left() + option.rect.width() - 30, option.rect.top() + height, 9, 9);
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (event->type() == QEvent::MouseButtonPress && decorationRect.contains(mouseEvent->pos()))
{
emit deleteItem(index);
}
if (event->type() == QEvent::MouseMove && decorationRect.contains(mouseEvent->pos()))
{
QCursor cursor(Qt::PointingHandCursor);
QApplication::setOverrideCursor(cursor);
QString strText = QStringLiteral("删除账号信息");
QToolTip::showText(mouseEvent->globalPos(), strText);
}
else
{
QCursor cursor(Qt::ArrowCursor);
QApplication::setOverrideCursor(cursor);
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
3.2、应用类
在我们的程序中应用这个代理:
1、头文件:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void deleteItem(const QModelIndex &index);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
2、源文件:
#include "widget.h"
#include "ui_Widget.h"
#include "ItemDelegate.h"
#include <QMessageBox>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
ItemDelegate *pDelegate = new ItemDelegate(this);
ui->comboBox->addItem(QPixmap(":/shasha.png"), QStringLiteral("沙师弟"));
ui->comboBox->addItem(QPixmap(":/jiejie.png"), QStringLiteral("二师兄"));
ui->comboBox->addItem(QPixmap(":/kongkong.png"), QStringLiteral("猴哥"));
ui->comboBox->addItem(QPixmap(":/tangtang.png"), QStringLiteral("师傅"));
ui->comboBox->setItemDelegate(pDelegate);
connect(pDelegate, SIGNAL(deleteItem(QModelIndex)), this, SLOT(deleteItem(QModelIndex)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::deleteItem(const QModelIndex &index)
{
if (QMessageBox::question(this, QStringLiteral("提示"), QStringLiteral("确认要删除所选账号吗?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes)
{
ui->comboBox->removeItem(index.row());
}
}
4、QStyledItemDelegate
4.1、简述QStyledItemDelegate
当在 Qt 项目视图中显示来自模型的数据时,单个项目由委托绘制。此外,当一个项目被编辑时,它提供了一个编辑器小部件,小部件在编辑时放置在项目视图的顶部。 QStyledItemDelegate 是所有 Qt 项目视图的默认委托,并在创建它们时安装在它们上。
模型中项目的数据被分配了一个 ItemDataRole。项目可以为每个角色存储一个 QVariant。 QStyledItemDelegate 实现了用户期望的最常见数据类型的显示和编辑,包括布尔值、整数和字符串。
4.2、数据类型
数据将根据它们在模型中的角色而不同地绘制。下面是委托可以为每个角色处理的角色和数据类型:
- Qt::BackgroundRole:QBrush
- Qt::CheckStateRole:Qt::CheckState
- Qt::DecorationRole:QIcon、QPixmap、QImage、QColor
- Qt::DisplayRole:QString 和带有字符串表示的类型
- Qt::EditRole:详见 QItemEditorFactory
- Qt::FontRole:QFont
- Qt::SizeHintRole:QSize
- Qt::TextAlignmentRole:Qt::Alignment
- Qt::ForegroundRole:QBrush
子类化 QStyledItemDelegate
如果委托不支持绘制所需的数据类型,或者想自定义项目的绘制,则需要子类化 QStyledItemDelegate,并重新实现paint() 和sizeHint()。为每个项目单独调用paint() 函数,使用sizeHint(),可以为每个项目指定提示。
自定义委托可以在不使用编辑器项目工厂的情况下提供编辑器。在这种情况下,必须重新实现以下虚函数:
- createEditor():返回用于更改模型数据的小部件,并且可以重新实现以自定义编辑行为。
- setEditorData():为小部件提供要操作的数据。
- updateEditorGeometry():确保编辑器相对于项目视图正确显示。
- setModelData():将更新的数据返回给模型。
- QStyledItemDelegate 与 QItemDelegate
这两个类的区别在于 QStyledItemDelegate 实现了paint()函数。除非需要自定义项目显示,否则建议在实现自定义委托或使用 Qt 样式表时使用 QStyledItemDelegate 作为基类。
4.3、成员函数
1、QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index)
重新实现: QAbstractItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const。
返回用于编辑由 index 指定的项目以进行编辑的小部件。父小部件和样式选项用于控制编辑器小部件的显示方式。(设置qss/Style要在父小部件上设置)
2、QString displayText(const QVariant &value, const QLocale &locale)
此函数返回委托将用于在语言环境中显示模型的 Qt::DisplayRole 的字符串。 value 是模型提供的 Qt::DisplayRole 的值。
默认实现使用 QLocale::toString 将值转换为 QString。
对于空模型索引,即模型返回无效 QVariant 的索引,不会调用此函数。
3、bool eventFilter(QObject *editor, QEvent *event)
如果editor是一个有效的 QWidget 并且event被处理,则返回 true,否则返回false。
默认处理以下按键事件:
- Tab
- Backtab
- Enter
- Return
- Esc
如果编辑器的类型是 QTextEdit 或 QPlainTextEdit,则不处理 Enter 和 Return 键。
在 Tab、Backtab、Enter、Return 键按下事件的情况下,编辑器的数据提交到模型并关闭编辑器。
- 如果事件是按 Tab 键,则视图将在视图中的下一项上打开编辑器。
- 如果事件是 Backtab 键,则视图将打开视图中前一项的编辑器。
- 如果事件是 Esc 键按下事件,则编辑器将关闭而不提交其数据。
4、void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index)
使用索引索引的值初始化选项。
当子类需要 QStyleOptionViewItem,但又不想自己设置所有信息时,此方法很有用。
5、void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)
重新实现:QAbstractItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const。
在子类中重新实现paint()时。使用 initStyleOption() 以与 QStyledItemDelegate 相同的方式设置选项。
尽可能在绘画时使用option。特别是它的 rect 变量来决定在哪里绘制和它的状态来确定它是启用还是选择。
绘制后,应该确保绘制器返回到调用此函数时提供的状态(在绘画之前调用 QPainter::save() 和之后调用 QPainter::restore())。
6、void setEditorData(QWidget *editor, const QModelIndex &index)
重新实现:QAbstractItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const。
从模型索引指定的数据模型项设置编辑器要显示和编辑的数据。
默认实现将数据存储在编辑器小部件的用户属性中。
7、void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index)
重新实现:QAbstractItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const。
从编辑器小部件获取数据并将其存储在项目索引处的指定模型中。
默认实现从编辑器小部件的用户属性获取要存储在数据模型中的值。
8、QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index)
重新实现:QAbstractItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const。
返回委托显示由索引指定的项目所需的大小,同时考虑选项提供的样式信息。
9、void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index)
重新实现:QAbstractItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const。
根据option更新由 index 指定的项目的编辑器。