الصف ، المحذوف من النموذج ، يبقى في الرأي ، ماذا أفعل خطأ؟
-
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) ؛ هنا الصف هو رقم الصف الذي تريد حذفه. هذا يفي بالغرض بالنسبة لي.