Qt 行,从模型中删除,保留在视图中,我做错了什么?

Qt 行,从模型中删除,保留在视图中,我做错了什么?,qt,pyqt,qtableview,Qt,Pyqt,Qtableview,我有QTableView,由QSqlRelationalTableModel填充。更改应在按下按钮时提交或还原。 当我编辑某行时,它会在编辑完成时更改视图中的状态,并在调用submitAll()时成功地将更改提交给DB。 但当我试图删除行时,它将保留在视图中。这是插槽,连接到移除按钮: def _removeSelectedStatuses(self): ''' Удаляет выбранные строки из таблицы pre[self]: self._m

我有QTableView,由QSqlRelationalTableModel填充。更改应在按下按钮时提交或还原。 当我编辑某行时,它会在编辑完成时更改视图中的状态,并在调用submitAll()时成功地将更改提交给DB。 但当我试图删除行时,它将保留在视图中。这是插槽,连接到移除按钮:

def _removeSelectedStatuses(self):
    '''
    Удаляет выбранные строки из таблицы

    pre[self]: self._model is not None
    '''
    model = self.ConservationStatusesTableView.selectionModel()
    l = model.selectedRows()
    if not len(l): return

    rows = set([i.row() for i in l])
    rows = list(rows)
    rows.sort()
    first = rows[0]
    count = len(rows)
    self._model.removeRows(first, count)

我做错了什么?

您是否实现了removeRows方法

请看这里:

我想缺少的只是一个emitDataChanged,它告诉视图发生了变化!否则,视图将无法知道是否必须刷新自己


希望这有帮助

我调查过,这种恶劣的行为是故意的。提交时会从模型中删除行,并且没有视图知道哪些行必须绘制,哪些行不绘制。从模型中删除行时唯一要做的事情是“!”header.model()中的标记。headerData(索引,垂直)。text()。而且很恶心

我为自己解决问题的方式感到惭愧,但以下是我丑陋的缺点:

from PyQt4 import QtGui
from PyQt4 import QtSql
from PyQt4 import QtCore

class SqlTableView(QtGui.QTableView):
    '''
    Представление, которое не показывает удалённые столбцы, 
    когда коммит ещё не прошёл
    '''


    def __init__(self, parent = None):
        '''
        Конструктор
        '''
        QtGui.QTableView.__init__(self, parent)

    def setModel(self, model):
        '''
        Мы не можем соединиться с моделями, не являющимися QSqlTableModel
        '''
        assert isinstance(model, QtSql.QSqlTableModel)
        QtGui.QTableView.setModel(self, model)

    def paintEvent(self, event):
        '''
        Тут всё и происходит. Осторожно, может стошнить.
        '''
        if self.model() is not None:
            header = self.verticalHeader()
            hm = header.model()
            for i in range(hm.rowCount()):
                if (hm.headerData(i, QtCore.Qt.Vertical).toPyObject() == '!' 
                    and not header.isSectionHidden(i)):
                    header.hideSection(i)
                elif (header.isSectionHidden(i) and 
                    hm.headerData(i, QtCore.Qt.Vertical).toPyObject() != '!'):
                    header.showSection(i)
        PyQt4.QtGui.QTableView.paintEvent(self, event)
我还将其添加到QtDesigner以简化界面设计

第二个解决方案,不那么糟糕:

class PSqlRelationalTableModel : public QSqlRelationalTableModel
{
    Q_OBJECT

public:
    explicit PSqlRelationalTableModel(QObject *parent = 0, 
        QSqlDatabase db = QSqlDatabase());
    virtual ~PSqlRelationalTableModel();

    bool removeRows(int row, int count, 
        const QModelIndex &parent = QModelIndex());

public slots:
    void revertRow(int row);

signals:
    void rowIsMarkedForDeletion(int index);
    void rowDeletionMarkRemoved(int index);

private:
    QSet<unsigned int> rowsToDelete;
};

//////////////////////////////////////////////////////////////////
void PTableView::setModel(PSqlRelationalTableModel *model)
{
    connect(model, SIGNAL(rowIsMarkedForDeletion(int)), 
        this, SLOT(onRowMarkedForDeletion(int)));
    connect(model, SIGNAL(rowDeletionMarkRemoved(int)), 
        this, SLOT(onRowDeletionMarkRemoved(int)));
    QTableView::setModel(model);
}

void PTableView::onRowMarkedForDeletion(int index)
{
    QHeaderView *hv = verticalHeader();
    hv->hideSection(index);
}

void PTableView::onRowDeletionMarkRemoved(int index)
{
    QHeaderView *hv = verticalHeader();
    hv->showSection(index);
}
类PSqlRelationalTableModel:公共QSqlRelationalTableModel
{
Q_对象
公众:
显式PSqlRelationalTableModel(QObject*parent=0,
QSQLDABASE=QSQLDABASE());
virtual~PSqlRelationalTableModel();
布尔值(整数行,整数计数,
常量QModelIndex&parent=QModelIndex());
公众时段:
无效行(整数行);
信号:
无效行标记为删除(整数索引);
void rowdelectionmarkremoved(int索引);
私人:
QSet-rowsToDelete;
};
//////////////////////////////////////////////////////////////////
void PTableView::setModel(PSqlRelationalTableModel*模型)
{
连接(型号、信号(行标记为删除(int)),
这个插槽(onrowsmarkedfordeletion(int));
连接(型号,信号(rowDeletionMarkRemoved(int)),
这个插槽(onrowdelectionmarkremoved(int));
QTableView::setModel(model);
}
void PTableView::onRowMarkedForDelete(int索引)
{
QHeaderView*hv=verticalHeader();
hv->hideSection(索引);
}
void PTableView::onrowdelectionmarkremoved(int索引)
{
QHeaderView*hv=verticalHeader();
hv->showSection(索引);
}

如果要从模型中删除所选行,只需调用:model->removeow(行); 此处的行是要删除的行号。
这对我来说很好。

我最近遇到了同样的问题,并为自己找到了另一个解决方案。 如果只有一个QTableView连接到此模型,则可以在QSqlTableModel.deleteRow()之后使用QTableView.setRowHidden()方法。很好


(我更愿意在custom paint delegate中删除文本…但我没有找到合适的标志来区分未提交的行。)

beginRemoveRows
endRemoveRows
。QSqlRelationalTableModel已经有remove行,使用beginRemoveRows和endRemoveRows正确实现。我调查,这种恶劣的行为是故意的。提交时会从模型中删除行,并且没有视图知道哪些行必须绘制,哪些行不绘制。从模型中删除行时唯一要做的事情是“!”header.model().headerData(index,vert.text())中的标记,这太恶心了。我已经找到了解决方法,稍后将在此处发布。SqTableModel的RemoveRow方法不会立即删除它。它将一行标记为删除,然后在提交()时将其删除。我试图改变这种行为。