الصف ، المحذوف من النموذج ، يبقى في الرأي ، ماذا أفعل خطأ؟

StackOverflow https://stackoverflow.com/questions/4146633

  •  30-09-2019
  •  | 
  •  

سؤال

لدي qtableview ، مملوءة بواسطة qsqlrelationaltablemodel. يجب ارتكاب التغييرات أو العودة على زر ضرب. عندما أقوم بتحرير بعض الصفوف ، فإنه يغير الحالة في العرض عند الانتهاء من التحرير ، ويلتزم بشكل ناجح التغييرات إلى 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)

ما الخطأ الذي افعله؟

هل كانت مفيدة؟

المحلول

لقد بحثت ، أن هذا السلوك السيئ هو حسب التصميم. يتم حذف الصفوف من النموذج على الالتزام ، ولا توجد وجهات نظر ، والتي يجب رسم الصفوف وأيها ليست كذلك. الشيء الوحيد الذي يتم عندما يتم إزالة الصفوف من النموذج هو "!" علامة في header.model (). headerdata (index ، vert) .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);
}

نصائح أخرى

هل قمت بتنفيذ طريقة Removerwes؟

إلقاء نظرة هنا:

PYQT: محاولة فهم insertrows لـ qabstractdatamodel و qtreeview

أعتقد أن ما هو مفقود هو مجرد emitdatachanged الذي يخبر الرأي بأن شيئًا ما قد تغير! بدون ذلك ، لا يمكن أن يعرف العرض ما إذا كان يتعين عليه تحديث نفسه!

أتمنى أن يساعدك هذا !

إذا كنت ترغب في إزالة الصف المحدد من نموذج تحتاج فقط إلى الاتصال: Model-> Removerow (ROW) ؛ هنا الصف هو رقم الصف الذي تريد حذفه. هذا يفي بالغرض بالنسبة لي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top