Pregunta

Tengo QTableView, llenado por QSqlRelationalTableModel. Los cambios deben estar comprometidos o revertidas en el botón de golpe. Cuando editar alguna fila, cambia de estado en la vista durante la edición de acabados, y con éxito confirma cambios DB cuando submitAll () llama. Pero cuando se intenta eliminar la fila, se queda a la vista. Aquí está la ranura, conectado al botón Quitar:

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)

¿Qué estoy haciendo mal?

¿Fue útil?

Solución

he investigado, que este comportamiento es por diseño desagradable. Las filas se eliminan del modelo de cometer, y no hay vistas saben, las filas que deben extraerse y cuáles no lo son. Lo único que hace cuando las filas eliminadas de modelo es '!' marcador en header.model (). headerData (índice, vert) .text (). Y es repugnante.

Me da vergüenza la forma en que solucionado el problema, pero aquí está mi fea Hack:

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)

I también lo añadió a QtDesigner a diseño de la interfaz Simplificar.

segunda solución, no tan desagradable:

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);
}

Otros consejos

¿Se implementa el método removeRows?

Tener una mirada aquí:

pyqt: Tratar de entender para insertrows QAbstractDataModel y QTreeView

Creo que lo que falta es simplemente una emitDataChanged que cuenta la opinión de que algo ha cambiado! Sin eso, la vista no puede saber si tiene que refrescarse!

Espero que esto ayude!

Si desea eliminar la fila seleccionada a partir de un modelo que sólo tiene que llamar: modelo-> RemoveRow (fila); Aquí fila es el número de fila que desea eliminar. Esta bien que funciona para mí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top