我已实施自定义QTableView
和QAbstractTableModel
。 QTableView
使用Qt
- 默认文本行编辑委托来操作字符串数据。我想确保在提交编辑(按enter
)后,该字符串对于其列是唯一的。如果另一行具有该列的相同值,则编辑将被拒绝,可能使用弹出框,然后文本行编辑将以编程方式重新进入编辑模式,以便用户可以再次尝试。
我考虑过使用自定义委托,并可能通过信号和插槽在委托和表视图之间进行通信。委托可以确保setModelData()
内的值是唯一的。要做到这一点,必须注入有关其他列的知识。如果该值不唯一,则委托可以发出表视图将拾取的信号;像notUniqueTryAgain()
这样的东西。在该插槽内,表格会弹出一条消息,然后在单元格上调用edit()
。这是正确的方法吗?
答案 0 :(得分:2)
使用下一位代表:
#ifndef ITEMDELEGATE_H
#define ITEMDELEGATE_H
#include <QItemDelegate>
class ItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit ItemDelegate(QObject *parent = 0);
protected:
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;
signals:
public slots:
};
#endif // ITEMDELEGATE_H
.cpp的
#include "itemdelegate.h"
#include <QLineEdit>
#include <QDebug>
ItemDelegate::ItemDelegate(QObject *parent) :
QItemDelegate(parent)
{
}
QWidget *ItemDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QLineEdit *editor = new QLineEdit(parent);
return editor;
}
void ItemDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QString value =index.model()->data(index, Qt::EditRole).toString();
QLineEdit *line = static_cast<QLineEdit*>(editor);
line->setText(value);
}
void ItemDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
{
QLineEdit *line = static_cast<QLineEdit*>(editor);
QString data = line->text();
int column = index.column();
for(int i = 0; i < model->rowCount(); i++)
{
QModelIndex cur = model->index(i,column);
qDebug() << data << model->data(cur, Qt::EditRole).toString();
if(data == model->data(cur, Qt::EditRole).toString())
{
model->setData(index, "wrong");
return;
}
}
model->setData(index, data);
}
void ItemDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
用法:
ItemDelegate *itDelegate = new ItemDelegate;
ui->tableView->setItemDelegate(itDelegate);
这是一个很好的例子,所以你可以做其他所有事情,例如:
if(data == model->data(cur, Qt::EditRole).toString())
{
//model->setData(index, "wrong");
QMessageBox msgBox;
msgBox.setText("Try again.");
msgBox.exec();
return;
}
等等。
当然,如果视图中有很多项目,它可能会很慢,因此您可以使用QProgressDialog向用户显示您需要的次数:
QProgressDialog progress("Checking...", "Searching", 0, model->rowCount(), 0);
for(int i = 0; i < model->rowCount(); i++)
{
progress.setValue(i);
QModelIndex cur = model->index(i,column);
qDebug() << data << model->data(cur, Qt::EditRole).toString();
if(data == model->data(cur, Qt::EditRole).toString())
{
model->setData(index, "wrong");
return;
}
if (progress.wasCanceled())
return;
}
progress.close();