我对QStyledItemDelegate
进行了细分,以便对QTableView
进行编辑,我的问题看起来似乎代表永远不会被称为女巫,如果双击则没有编辑行为。另外,我检查了函数签名,它们看起来是正确的。
StudentNotesDelegate
#include "studentnotesdelegate.h"
#include <QLineEdit>
#include <qDebug>
StudentNotesDelegate::StudentNotesDelegate(QWidget *parent): QStyledItemDelegate(parent)
{
}
QWidget *StudentNotesDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
if (index.column() > 3) {
QLineEdit *inputText = new QLineEdit(parent);
qDebug() << "ds:";
inputText->setFrame(false);
return inputText;
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
void StudentNotesDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const {
if (index.column() > 3) {
QString indexValue = index.model()->data(index).toString();
qDebug() << "Value:" << indexValue;
QLineEdit *inputText = static_cast<QLineEdit*>(editor);
inputText->setText(indexValue);
}
}
void StudentNotesDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
if (index.column() > 3) {
QLineEdit *inputText = static_cast<QLineEdit*>(editor);
QString indexValue = inputText->text();
model->setData(index, indexValue, Qt::EditRole);
}
}
void StudentNotesDelegate::updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const {
if (index.column() > 3) {
editor->setGeometry(option.rect);
}
}
#ifndef STUDENTNOTESDELEGATE_H
#define STUDENTNOTESDELEGATE_H
#include <QStyledItemDelegate>
class StudentNotesDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
StudentNotesDelegate(QWidget *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;
};
#endif // STUDENTNOTESDELEGATE_H
这就是我致电setItemDelegate
的方式:
QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery("Removed to avoid horizontal scroll");
ui->listStudentsTable->setModel(model);
model->insertColumns(3, classMaterials.length());
StudentNotes::setModelHeader(model, classMaterials, classMaterials.length());
//ui->listStudentsTable->setItemDelegate(new StudentNotesDelegate);
更新
我使用QStyledItemDelegate
代替QSqlQueryModel
,重新实现了flags()
,data()
和setData()
。
Qt::ItemFlags StudentNotesModel::flags(const QModelIndex &index) const {
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column() > 2)
flags |= Qt::ItemIsEditable;
return flags;
}
QVariant StudentNotesModel::data(const QModelIndex &index, int role) const
{
return QSqlQueryModel::data(index, role);
}
bool StudentNotesModel::setData(const QModelIndex &index, QVariant &value, int role)
{
qDebug() << "setData() call";
if (index.isValid() && index.column() > 2)
{
QAbstractItemModel *model = const_cast<QAbstractItemModel*>(index.model());
model->setData(index, value, Qt::EditRole);
emit dataChanged(index, index);
return true;
}
return false;
}
StudentNotesModel *model = new StudentNotesModel;Class.mat_class = " + mat_class;
model->setQuery("SELECT Student.mat_stud, fname, lname FROM Student, Division, Class "
"WHERE Division.mat_div = Class.mat_class AND Student.mat_class = Class.mat_class" + studentsClassRoom);
ui->listStudentsTable->setModel(model);
QTableView
现在可以编辑,但是当我按Enter键时,它会重置为默认值,我注意到setData()
永远不会被调用。我现在缺少什么?
答案 0 :(得分:0)
您的主要问题是QSqlQueryModel
,它是只读模型。正如医生所说:
默认情况下,模型是只读的。要使它成为读写,你必须 将它子类化并重新实现setData()和flags()。另一种选择是 使用QSqlTableModel,它提供了基于a的读写模型 单个数据库表。
所以编辑委托在这里没有任何意义。因此,请尝试使用QSqlTableModel
或子类化当前模型。
同样在您当前的委托中,尝试在createEditor()
中执行此操作,在每个方法中调用默认实现。
但是子类化可能是一个非常长的过程,所以尽量只使用QSqlTableModel
。假设您的代码现在看起来像:
QSqlQueryModel *mmm = new QSqlQueryModel;
mmm->setQuery("SELECT * FROM newTab");
QTableView *view = new QTableView;
view->setItemDelegate(new ItemDelegate);
view->setModel(mmm);
view->show();
然后将其更改为:
QSqlTableModel *mmm = new QSqlTableModel(this,sdb);
mmm->setTable("newTab");
mmm->setEditStrategy(QSqlTableModel::OnManualSubmit);
mmm->select();
QTableView *view = new QTableView;
view->setItemDelegate(new ItemDelegate);
view->setModel(mmm);
view->show();
这就是你所需要的,物品代表现在正在工作(我在我的电脑上测试过,它有效)
答案 1 :(得分:0)
在我的项目进展之后,对QSqlQueryModel
或QSortFilterProxyModel
进行子分类并没有满足我的需要,所以我切换到QStandardItemModel
,因为我需要阅读一些行和列仅
将某些列设置为只读: StudentNotesModel :: StudentNotesModel(int rows,int columns,QObject * parent) :QStandardItemModel(行,列,父) { }
Qt::ItemFlags StudentNotesModel::flags(const QModelIndex &index) const {
Qt::ItemFlags flags = QStandardItemModel::flags(index);
// Line 1,2, and 3 are read only
if (index.column() < 3) {
flags &= ~Qt::ItemIsEditable;
}
if (index.row() > index.model()->rowCount()) {
qDebug() << index.row();
flags &= ~Qt::ItemIsEditable;
}
return flags;
}
StudentNotesModel *model = new StudentNotesModel;
将某些行设置为只读:
for (int row = 0; row < numRows ; ++row) {
for (int col = 0; col < numColumns; ++col) {
QStandardItem *item = new QStandardItem("0");
if (row == 7 || row == 8)) {
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
}
model->setItem(row, col, item);