Qt: метод setData в QAbstractItemModel
Я новичок в model view, и я следовал в этом уроке при проверке документации в то же время и я наткнулся на эту маленькую деталь : код учебник, который можно скачать здесь имеет в классе QAbstractItemModel (здесь QAbstractListModel) метод setData, код которого:
def setData(self, index, value, role = QtCore.Qt.EditRole):
if role == QtCore.Qt.EditRole:
row = index.row()
color = QtGui.QColor(value)
if color.isValid():
self.__colors[row] = color
self.dataChanged.emit(index, index)
return True
return False
согласно объяснениям в учебнике и из того, что я понял из документации, если функция возвращает True, тогда представление обновляется, если оно возвращает false, ничего не происходит, но когда я изменил код на:
def setData(self, index, value, role = QtCore.Qt.EditRole):
if role == QtCore.Qt.EditRole:
row = index.row()
color = QtGui.QColor(value)
if color.isValid():
self.__colors[row] = color
self.dataChanged.emit(index, index)
return False # This is what I changed in the code
return False
Я понял, что вид все еще обновляется, если цвет.isValid (), даже если функция возвращает False. Я неправильно понимаю роль возврата в методе setData или это ошибка ?
для справки, я использую PySide 1.2.1, а не PyQt4.
3 ответов
процитировать из видео-учебника относительно setData
:
...эта функция должна возвращать true, если операция прошла успешно, иначе не будет обновляться.
строго говоря, это утверждение является ложным. Документация для помощью переопределенной QAbstractItemModel рассказала, что setData
возвращает true, если данные были установлены успешно, и false в противном случае; он не упоминает, каковы могут быть последствия этого. В частности, в нем ничего не говорится об обновлении представления.
глядя на исходный код Qt, возвращаемое значение setData
тут провериться в нескольких местах, и некоторые из этих проверок может иногда помогите активировать обновление. Но есть буквально десятки вещей, которые могут вызвать обновление, поэтому возвращаемое значение setData
никоим образом не важен для обновления элементов.
возможно, было бы точнее сказать, что setData
должны верните true, в противном случае view не может обновить себя (при определенных обстоятельствах).
я неправильно понимаю роль возврата в методе setData или это ошибка ?
из Qt документация:
боол помощью переопределенной QAbstractItemModel::метод setdata(индекс QModelIndex как const&, с const QVariant & значение, роль инт = с Qt::EditRole) [виртуальный]
задает значение данных роли для элемента в индексе.
возвращает true в случае успеха; в противном случае возвращает false.
в сигнал dataChanged () должен испускаться, если данные были успешно установлены.
реализация базового класса возвращает false. Эта функция и data () должны быть переопределены для редактируемых моделей.
тем не менее, вы, похоже, излучаете сигнал dataChanged (), даже если данные не установлены успешно на основе возвращаемого значения. Кроме того, учебник, на который вы, похоже, ссылаетесь, использует self.__colors
установите в свой код для rowCount()
, ' data () и другие методы. Если вы хотите избегайте обновления, вам нужно будет вернуть False перед любым таким заявлением.
вам нужно обратить внимание на эти критерии, потому что сигнал и цвета управляются внутренне, в то время как возвращаемое значение используется вызывающим абонентом, чтобы увидеть, если setData()
метод был успешно установлен.
основываясь на знаниях выше, вы должны были написать этот код для своей второй попытки заставить его работать так, как вы ожидаете:
def setData(self, index, value, role = QtCore.Qt.EditRole):
if role == QtCore.Qt.EditRole:
row = index.row()
color = QtGui.QColor(value)
if color.isValid():
return False
return False
Я не мог найти много информации об этом. Тем не менее, это сообщение форума "специалистом Qt" предполагает, что это поведение является выбором дизайна разработчиками Qt:
http://qt-project.org/forums/viewthread/31462
более конкретно, представления не теряют свой ввод, если он отклоняется моделью. Это может показаться странным в контексте учебника вы следуете (где цвет меняется из синхронизации с моделью), но в некоторых контекстах это было бы желательно.
в качестве примера предположим, что вы разработали форму, используя QLineEdit
s и QDataWidgetMapper
для сопоставления содержимого формы с вашей моделью. Предположим также, что QDataWidgetMapper::SubmitPolicy
установлено значение AutoSubmit
. В AutoSubmit
режим, каждый раз QLineEdit
изменить, а затем теряет фокус, модель обновляется. Если модель также отклоняет изменение, и текущие данные (без изменения) повторно заполняются в QLineEdit
, Это будет иметь эффект пользователя, чтобы начать все сначала (а не исправление их входа).
альтернативный выбор дизайна заключается в том, чтобы позволить представлению быть несинхронным с моделью и, если это нежелательно, возложить ответственность за изменение этого поведения на программиста.
два способа, которые я могу придумать, чтобы изменить это поведение, были бы:
- создайте пользовательский делегат, который обрабатывает
setData
->false
испуская таможниdataRejected
сигнал, что представление может подключаться и использовать для обновления себя. - создайте представление "без состояния" для модели: принудительно извлекайте данные из модели при каждом обновлении. Таким образом, отправка потенциального изменения в модель не обновит представление, если только эта модель не испустит
dataChanged
сигнал, в этом случае вид будет получать текущее состояние и обновлять себя.