QTableView表格控件代理
简单代理控件重写关键函数代理控件析构
简单代理控件
新创建的表格是可以直接进行编辑,默认效果类似于QLineEdit,但是如果想要在表格上嵌入一些复杂的控件默认的效果就不行了,例如下面的例子:
其中在双击表格控件后会出现一个下拉框,这种效果就需要使用代理来实现,代码如下所示:
class VariableDelegate
: public QStyledItemDelegate
{
Q_OBJECT
public:
explicit VariableDelegate(QObject* _parent = nullptr);
~VariableDelegate();
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
};
QWidget* VariableDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QComboBox* delegate_item = new QComboBox(parent);
delegate_item->addItems(QStringList()
InitializeUI();
}
VariableItem::~VariableItem() = default
void VariableItem::SetText(const QString & _text) {
variable_show_->setText(_text);
}
QString VariableItem::GetText() {
return variable_show_->text();
}
void VariableItem::InitializeUI() {
QHBoxLayout* variable_main_layout = new QHBoxLayout();
variable_main_layout->setMargin(0);
variable_show_ = new QLineEdit(this);
variable_main_layout->addWidget(variable_show_, 1);
QPushButton* variable_btn = new QPushButton("Select", this);
variable_main_layout->addWidget(variable_btn);
setLayout(variable_main_layout);
setContentsMargins(0, 0, 0, 0);
}
这段代码在普通的情况下直接可以独立显示出来,其中在窗体的水平方向上放置了一个QLineEdit和QPushButton,具体如下所示:
![复杂控件内容](https://img-blog.csdnimg.cn/51ef394e06304bc1b410416eb8a51f45.png#pic_center)
这种复杂的自定义控件同样可以放到createEditor()函数中,作为一个代理控件返回,具体代码如下:
QWidget* VariableDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
VariableItem* item = new VariableItem(parent);
return item;
}
双击表格控件时就可以在单元格内看到该复杂控件,效果如下: 可以,这个控件是可以修改数据,但是当修改数据并离开单元格后,单元格没有显示当前输入的数据,这是就用到了setModelData()函数,该函数可以将控件的数据设置给单元格去显示。
void VariableDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
VariableItem* item = qobject_cast(editor);
if (item != nullptr) {
model->setData(index, item->GetText(), Qt::EditRole);
}
}
注意设置Data的标识字段时要设置Qt::EditRole,该标志就是QTableView从Model取值显示时的标志,显示效果如下:
现在当离开单元格的编辑状态后已经可以在单元格中显示刚刚输入的内容了,可以配合按钮实现例如选择文件夹、文件或者日期等操作。
当再次双击单元格时,将显示的内容写入到复杂控件中可以重写setEditorData()函数,该函数就可以从当前选中的单元格中返回内容,然后使用Qt::EditRole标识值将数据取出设置即可。
void VariableDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
QString value = index.model()->data(index, Qt::EditRole).toString();
VariableItem* item = qobject_cast(editor);
if (item != nullptr) {
item->SetText(value);
}
}
至此基本表格代理控件就开发完成了。
代理控件析构
在createEditor()函数中会大量创建QWidget对象,这些对象会在setModelData()结束后自动被析构因此不需要自己取手动进行管理。演示如下:
// 给代理控件添加析构函数,并打印数据
VariableItem::~VariableItem() {
qInfo() |