QSqlTableModel:我在哪里可以得到一行是否被标记为已删除
QSqlTableModel: Where can I get whether a row is marked as removed
如果我对从数据库中读取的记录调用 removeRows a !会显示在tableView的第一列。
我唯一想要实现的是该行不会显示在视图中。我用 QSortFilterProxyModel 试过了,但我不知道在哪里可以得到用于显示的标志!在第一列。有没有办法在 QSortFilterProxyModel 中设置一个过滤器,它只包含没有这个标志的行?
视图从哪里获取信息,删除的行标有“!” ?此信息可能隐藏在模型中的某处,但我找不到位置。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
m_ui(new Ui::MainWindow),
m_model(new QSqlTableModel(this)),
m_proxyModel(new QSortFilterProxyModel(this))
{
m_ui->setupUi(this);
m_model->setTable("test");
m_model->setEditStrategy(QSqlTableModel::OnManualSubmit);
m_model->select();
m_proxyModel->setSourceModel(m_model);
m_ui->tableView->setModel(m_proxyModel);
qDebug() << "Select : Row count:" << m_model->rowCount();
connect(m_ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &MainWindow::on_selectionChanged);
}
MainWindow::~MainWindow()
{
delete m_ui;
}
void MainWindow::on_pushButtonNewRecord_clicked()
{
qDebug() << "New Record";
m_record = m_model->record();
m_record.setValue("firstname", "john");
m_record.setValue("lastname", "doe");
m_record.setValue("email", "john.doe@email.com");
m_model->insertRecord(-1, m_record);
qDebug() << "New Record : Row count:" << m_model->rowCount();
}
void MainWindow::on_pushButtonRemoveRow_clicked()
{
qDebug() << "Remove Row";
if (m_row >= 0) {
m_proxyModel->removeRow(m_row);
qDebug() << "Remove Record: Row count:" << m_model->rowCount();
}
for (int i = 0; i < m_model->rowCount(); i++) {
qDebug() << "\n";
qDebug() << "Remove Row: index :" << m_model->index(i, 0);
qDebug() << "Remove Row: isValid:" << m_model->index(i, 0).isValid();
qDebug() << "Remove Row: isDirty:" << m_model->isDirty(m_model->index(i, 0));
qDebug() << "Remove Row: flags :" << m_model->index(i, 0).flags();
qDebug() << "Remove Row: data :" << m_model->index(i, 0).data(Qt::DisplayRole);
qDebug() << "Remove Row: heaader:" << m_model->headerData(i, Qt::Vertical);
QVariant verticalHeader = m_model->headerData(i, Qt::Vertical);
if (verticalHeader == "!") {
qDebug() << "Deleted";
}
//qDebug() << m_model->record(i);
}
}
void MainWindow::on_pushButtonSubmit_clicked()
{
qDebug() << "Submit";
m_model->submitAll();
m_model->select();
}
void MainWindow::on_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
Q_UNUSED(deselected)
if (!selected.isEmpty()) {
m_row = selected.indexes().first().row();
}
}
您必须实现一个 QSortFilterProxyModel 来过滤 Dirty 行,其垂直 header 文本为“!”,您还必须调用 invalidate()
方法来强制应用过滤器.
dirtyfilterproxymodel.h
#ifndef DIRTYFILTERPROXYMODEL_H
#define DIRTYFILTERPROXYMODEL_H
#include <QSortFilterProxyModel>
#include <QSqlTableModel>
class DirtyFilterProxyModel : public QSortFilterProxyModel
{
public:
using QSortFilterProxyModel::QSortFilterProxyModel;
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if(QSqlTableModel *source_model = qobject_cast<QSqlTableModel *>(sourceModel())){
QModelIndex ix = source_model->index(source_row, 0, source_parent);
QString row_header_item = source_model->headerData(source_row, Qt::Vertical, Qt::DisplayRole).toString();
return !(source_model->isDirty(ix) && row_header_item == QLatin1String("!"));
}
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
};
#endif // DIRTYFILTERPROXYMODEL_H
mainwindow.h
// ...
class DirtyFilterProxyModel;
// ...
class MainWindow : public QMainWindow
{
// ...
private:
Ui::MainWindow *m_ui;
<b>DirtyFilterProxyModel *m_proxyModel;</b>
// ...
mainwindow.cpp
<b>#include "dirtyfilterproxymodel.h"</b>
// ...
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
m_ui(new Ui::MainWindow),
m_model(new QSqlTableModel(this)),
<b>m_proxyModel(new DirtyFilterProxyModel(this))</b>
{
// ...
}
void MainWindow::on_pushButtonNewRecord_clicked()
{
// ...
m_model->insertRecord(-1, m_record);
<b>m_proxyModel->invalidate()</b>;
}
// ...
void MainWindow::on_pushButtonRemoveRow_clicked()
{ if (m_row >= 0) {
m_proxyModel->removeRow(m_row);
<b>m_proxyModel->invalidate();</b>
}
}
如果我对从数据库中读取的记录调用 removeRows a !会显示在tableView的第一列。
我唯一想要实现的是该行不会显示在视图中。我用 QSortFilterProxyModel 试过了,但我不知道在哪里可以得到用于显示的标志!在第一列。有没有办法在 QSortFilterProxyModel 中设置一个过滤器,它只包含没有这个标志的行?
视图从哪里获取信息,删除的行标有“!” ?此信息可能隐藏在模型中的某处,但我找不到位置。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
m_ui(new Ui::MainWindow),
m_model(new QSqlTableModel(this)),
m_proxyModel(new QSortFilterProxyModel(this))
{
m_ui->setupUi(this);
m_model->setTable("test");
m_model->setEditStrategy(QSqlTableModel::OnManualSubmit);
m_model->select();
m_proxyModel->setSourceModel(m_model);
m_ui->tableView->setModel(m_proxyModel);
qDebug() << "Select : Row count:" << m_model->rowCount();
connect(m_ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &MainWindow::on_selectionChanged);
}
MainWindow::~MainWindow()
{
delete m_ui;
}
void MainWindow::on_pushButtonNewRecord_clicked()
{
qDebug() << "New Record";
m_record = m_model->record();
m_record.setValue("firstname", "john");
m_record.setValue("lastname", "doe");
m_record.setValue("email", "john.doe@email.com");
m_model->insertRecord(-1, m_record);
qDebug() << "New Record : Row count:" << m_model->rowCount();
}
void MainWindow::on_pushButtonRemoveRow_clicked()
{
qDebug() << "Remove Row";
if (m_row >= 0) {
m_proxyModel->removeRow(m_row);
qDebug() << "Remove Record: Row count:" << m_model->rowCount();
}
for (int i = 0; i < m_model->rowCount(); i++) {
qDebug() << "\n";
qDebug() << "Remove Row: index :" << m_model->index(i, 0);
qDebug() << "Remove Row: isValid:" << m_model->index(i, 0).isValid();
qDebug() << "Remove Row: isDirty:" << m_model->isDirty(m_model->index(i, 0));
qDebug() << "Remove Row: flags :" << m_model->index(i, 0).flags();
qDebug() << "Remove Row: data :" << m_model->index(i, 0).data(Qt::DisplayRole);
qDebug() << "Remove Row: heaader:" << m_model->headerData(i, Qt::Vertical);
QVariant verticalHeader = m_model->headerData(i, Qt::Vertical);
if (verticalHeader == "!") {
qDebug() << "Deleted";
}
//qDebug() << m_model->record(i);
}
}
void MainWindow::on_pushButtonSubmit_clicked()
{
qDebug() << "Submit";
m_model->submitAll();
m_model->select();
}
void MainWindow::on_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
Q_UNUSED(deselected)
if (!selected.isEmpty()) {
m_row = selected.indexes().first().row();
}
}
您必须实现一个 QSortFilterProxyModel 来过滤 Dirty 行,其垂直 header 文本为“!”,您还必须调用 invalidate()
方法来强制应用过滤器.
dirtyfilterproxymodel.h
#ifndef DIRTYFILTERPROXYMODEL_H
#define DIRTYFILTERPROXYMODEL_H
#include <QSortFilterProxyModel>
#include <QSqlTableModel>
class DirtyFilterProxyModel : public QSortFilterProxyModel
{
public:
using QSortFilterProxyModel::QSortFilterProxyModel;
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if(QSqlTableModel *source_model = qobject_cast<QSqlTableModel *>(sourceModel())){
QModelIndex ix = source_model->index(source_row, 0, source_parent);
QString row_header_item = source_model->headerData(source_row, Qt::Vertical, Qt::DisplayRole).toString();
return !(source_model->isDirty(ix) && row_header_item == QLatin1String("!"));
}
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
};
#endif // DIRTYFILTERPROXYMODEL_H
mainwindow.h
// ...
class DirtyFilterProxyModel;
// ...
class MainWindow : public QMainWindow
{
// ...
private:
Ui::MainWindow *m_ui;
<b>DirtyFilterProxyModel *m_proxyModel;</b>
// ...
mainwindow.cpp
<b>#include "dirtyfilterproxymodel.h"</b>
// ...
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
m_ui(new Ui::MainWindow),
m_model(new QSqlTableModel(this)),
<b>m_proxyModel(new DirtyFilterProxyModel(this))</b>
{
// ...
}
void MainWindow::on_pushButtonNewRecord_clicked()
{
// ...
m_model->insertRecord(-1, m_record);
<b>m_proxyModel->invalidate()</b>;
}
// ...
void MainWindow::on_pushButtonRemoveRow_clicked()
{ if (m_row >= 0) {
m_proxyModel->removeRow(m_row);
<b>m_proxyModel->invalidate();</b>
}
}