一、
继续完善上一篇的QlistWidget的自绘操作,为其增加编辑功能:
主要注意两点:
1、设置QlistWidget的每一项具有编辑功能:
QListWidgetItem* item1 = new QListWidgetItem; item1->setFlags(Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsSelectable);
2、编辑后文本可能显示不全,此时要进行文本宽度的测量,然后根据实际宽度进行绘制。
二、实例代码
ListWidget::ListWidget(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags) { ui.setupUi(this); QListWidgetItem* item1 = new QListWidgetItem; item1->setFlags(Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsSelectable); QListWidgetItem* item2 = new QListWidgetItem; item2->setFlags(Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsSelectable); item1->setData(Qt::DecorationRole,QIcon(":/ListWidget/Resources/Save.png")); item1->setData(Qt::DisplayRole,"Save"); item1->setData(Qt::UserRole + 1,"This is Icon of Sage"); item1->setData(Qt::UserRole + 2,":/ListWidget/Resources/Save.png"); item2->setData(Qt::DecorationRole,QIcon(":/ListWidget/Resources/grab.png")); item2->setData(Qt::DisplayRole,"Grab"); item2->setData(Qt::UserRole + 1,"This is Icon of Grab"); item2->setData(Qt::UserRole + 2,":/ListWidget/Resources/grab.png"); ui.listWidget->addItem(item1); ui.listWidget->addItem(item2); ui.listWidget->setItemDelegate(new MyItemPainter(ui.listWidget)); //方法二:采用Model/View架构的方式 /* QAbstractItemModel* mode = ui.listWidget->model(); mode->insertRow(0); mode->setData(mode->index(0,0),"Save",Qt::DisplayRole); mode->setData(mode->index(0,0),"This is the Save Icon",Qt::ToolTipRole); mode->setData(mode->index(0,0),"Save Icon of User",Qt::UserRole); mode->setData(mode->index(0,0),QIcon(":/ListWidget/Resources/Save.png"),Qt::DecorationRole); mode->insertRow(1); mode->setData(mode->index(1,0),"Grab",Qt::DisplayRole); mode->setData(mode->index(1,0),"This is the Grab Icon",Qt::ToolTipRole); mode->setData(mode->index(1,0),"Grab Icon of User",Qt::UserRole); mode->setData(mode->index(1,0),QIcon(":/ListWidget/Resources/grab.png"),Qt::DecorationRole); */ }
#ifndef MYITEMPAINTER_H #define MYITEMPAINTER_H #include <QStyledItemDelegate> class MyItemPainter : public QStyledItemDelegate { Q_OBJECT public: MyItemPainter(QWidget *parent); ~MyItemPainter(); private: QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; 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 // MYITEMPAINTER_H
#include "MyItemPainter.h" #include <QPainter> #include <QTextEdit> #include <QSpinBox> #include <QFontMetrics> MyItemPainter::MyItemPainter(QWidget *parent) : QStyledItemDelegate(parent) { } MyItemPainter::~MyItemPainter() { } //设置显示的总高度 QSize MyItemPainter::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const { //获取每一行的原始大小 QSize size = QStyledItemDelegate::sizeHint(option,index); size.setHeight(60); return size; //重写之前的默认返回值 //return QStyledItemDelegate::sizeHint(option,index); } void MyItemPainter::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const { QRect Rect = option.rect; Rect.adjust(2,2,-2,-2); //取得对应项的数据 QString strDisplay = index.data(Qt::DisplayRole).toString();//名称 QString strTip = index.data(Qt::UserRole + 1).toString();//提示 QString strPath = index.data(Qt::UserRole + 2).toString();//图标路径 //显示操作:当选中某一项时 if (option.state & QStyle::State_Selected) { painter->setBrush(QColor(50,183,183)); painter->drawRoundedRect(Rect,2,2); painter->setBrush(Qt::NoBrush); } //画名称 { //测量字体的宽度,根据字体实际宽度进行绘制文字,避免显示不全 QFont font; painter->setFont(font); QFontMetrics metric(font); QRect fontRect = metric.boundingRect(strDisplay); QRect dst = Rect; dst.setLeft(dst.left()+ 10); dst.setRight(dst.left()+fontRect.width()); dst.setTop(dst.top()+8); dst.setBottom(dst.bottom()-40); painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, strDisplay); } //画图标 { QPixmap pmap(strPath); QRect dst = Rect; dst.setTop(dst.top()+20); dst.setRight(dst.left()+40); QRect area(0,0,24,24); area.moveCenter(dst.center()); painter->drawPixmap(area,pmap); } //画提示 { QRect dst = Rect; dst.setLeft(dst.left()+45); dst.setTop(dst.top()+20); painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, strTip); } //重写之前的默认返回值 //return QStyledItemDelegate::paint(painter,option,index); } //创建一个编辑器返回给视图对象 QWidget * MyItemPainter::createEditor ( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const { QTextEdit* editor = new QTextEdit(parent); return editor; } //读取要编辑的目标数据项的数据,初始化编辑器 void MyItemPainter::setEditorData ( QWidget * editor, const QModelIndex & index ) const { QString value = index.model()->data(index,Qt::EditRole).toString(); QTextEdit* testedit = static_cast<QTextEdit*>(editor); testedit->setText(value); } //读取编辑器中的值,将其写回到目标项中 void MyItemPainter::setModelData ( QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const { QTextEdit* testedit = static_cast<QTextEdit*>(editor); QString value = testedit->toPlainText(); model->setData(index,value,Qt::EditRole); } //更改数据项的尺寸(外观) void MyItemPainter::updateEditorGeometry ( QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index ) const { editor->setGeometry(option.rect); }