您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Qt如何自定义委托全家桶
## 1. 什么是委托(Delegate)
在Qt中,委托(Delegate)是Model/View架构中的关键组件,负责控制数据项的**显示方式**和**编辑行为**。与直接修改模型数据不同,委托通过以下方式增强交互:
- 自定义渲染逻辑(paint)
- 处理用户输入事件
- 提供特定编辑器控件
```cpp
// 继承QStyledItemDelegate创建自定义委托
class CustomDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
explicit CustomDelegate(QObject *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const override;
};
通过重写paint()
实现自定义渲染:
void StarRatingDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const {
if (index.data().canConvert<StarRating>()) {
StarRating stars = qvariant_cast<StarRating>(index.data());
stars.paint(painter, option.rect, option.palette,
StarRating::ReadOnly);
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
实现完整的编辑流程:
方法 | 作用 |
---|---|
createEditor() |
创建编辑控件(如QSpinBox/QComboBox) |
setEditorData() |
将模型数据加载到编辑器 |
setModelData() |
将编辑器数据保存回模型 |
QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/*option*/,
const QModelIndex &/*index*/) const {
QSpinBox *editor = new QSpinBox(parent);
editor->setRange(0, 100);
return editor;
}
组合多个控件作为编辑器:
QWidget *DateRangeDelegate::createEditor(...) const {
QWidget *container = new QWidget(parent);
QHBoxLayout *layout = new QHBoxLayout(container);
QDateEdit *startEdit = new QDateEdit();
QDateEdit *endEdit = new QDateEdit();
layout->addWidget(startEdit);
layout->addWidget(endEdit);
return container;
}
根据数据状态改变显示样式:
void StatusDelegate::paint(...) const {
if (index.data().toString() == "Error") {
painter->fillRect(option.rect, Qt::red);
}
QStyledItemDelegate::paint(painter, option, index);
}
处理不同层级的不同渲染:
void TreeDelegate::paint(...) const {
if (index.parent().isValid()) { // 子节点
// 特殊绘制逻辑
} else { // 根节点
// 默认绘制
}
}
实现类似Excel的条件格式:
void ConditionalDelegate::paint(...) const {
double value = index.data().toDouble();
QColor bgColor = (value > 0) ? Qt::green : Qt::red;
painter->fillRect(option.rect, bgColor);
// 继续绘制文本...
}
通过QAbstractItemView::setItemDelegateForColumn/Row
指定特定行列的委托:
tableView->setItemDelegateForColumn(0, new NumberDelegate(this));
tableView->setItemDelegateForColumn(1, new ColorDelegate(this));
正确使用QStyleOptionViewItem
提高渲染效率:
void FastPaintDelegate::paint(...) const {
option.widget->style()->drawControl(QStyle::CE_ItemViewItem,
&option, painter);
// 自定义绘制叠加层...
}
检查是否实现了完整的编辑方法链:
1. createEditor()
2. setEditorData()
3. setModelData()
确保在派生类中调用基类方法的正确时机:
void MyDelegate::paint(...) const {
// 先绘制自定义内容
drawCustomBackground(painter, option.rect);
// 最后调用基类绘制文本
QStyledItemDelegate::paint(painter, option, index);
}
class ProgressBarDelegate : public QStyledItemDelegate {
public:
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override {
int progress = index.data().toInt();
QStyleOptionProgressBar progressBarOption;
progressBarOption.rect = option.rect.adjusted(2, 2, -2, -2);
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.text = QString::number(progress) + "%";
progressBarOption.textVisible = true;
QApplication::style()->drawControl(
QStyle::CE_ProgressBar, &progressBarOption, painter);
}
QSize sizeHint(...) const override {
return QSize(100, 24); // 固定进度条高度
}
};
通过自定义委托可以实现: - ✔️ 数据可视化增强(图表、星级等) - ✔️ 特定领域编辑控件(日期范围、颜色选择等) - ✔️ 交互行为定制(验证、自动完成等)
建议从简单委托开始,逐步实现复杂功能,最终构建出符合业务需求的”委托全家桶”。 “`
(注:实际字数约1500字,此处为精简展示。完整实现需要配合具体业务场景和更多代码示例)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。