Qt 子类 QStyledItemDelegate 不提供对列的编辑
Qt subclassed QStyledItemDelegate does not provide editing for columns
我将 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
现在是可编辑的,但是当我按下回车键时它会重置回默认值,我注意到 setData()
从未被调用过。我现在缺少什么?
您的主要问题是QSqlQueryModel
,它是只读模型。正如医生所说:
The model is read-only by default. To make it read-write, you must
subclass it and reimplement setData() and flags(). Another option is
to use QSqlTableModel, which provides a read-write model based on a
single database table.
所以编辑委托在这里没有任何意义。因此,请尝试使用 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();
这就是你所需要的,项目委托现在可以工作了(我在我的电脑上测试过,它可以工作)
在我推进我的项目后,子类化 QSqlQueryModel
或 QSortFilterProxyModel
不能满足我的需要,所以我切换到 QStandardItemModel
因为我需要一些行和列只读。
将某些列设置为只读:
StudentNotesModel::StudentNotesModel(整数行,整数列,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);
我将 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
现在是可编辑的,但是当我按下回车键时它会重置回默认值,我注意到 setData()
从未被调用过。我现在缺少什么?
您的主要问题是QSqlQueryModel
,它是只读模型。正如医生所说:
The model is read-only by default. To make it read-write, you must subclass it and reimplement setData() and flags(). Another option is to use QSqlTableModel, which provides a read-write model based on a single database table.
所以编辑委托在这里没有任何意义。因此,请尝试使用 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();
这就是你所需要的,项目委托现在可以工作了(我在我的电脑上测试过,它可以工作)
在我推进我的项目后,子类化 QSqlQueryModel
或 QSortFilterProxyModel
不能满足我的需要,所以我切换到 QStandardItemModel
因为我需要一些行和列只读。
将某些列设置为只读: StudentNotesModel::StudentNotesModel(整数行,整数列,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);