Название: Проблема с удалением в QSqlTableModel Отправлено: iamfomik от Сентябрь 09, 2008, 22:39 Всем привет.
Недавно перешёл на новую версию QT - 4.4.1 и начал разрабатывать программку, которая работает с MySQL. Так вот, пишу, значит, всё как и обычно делаю и тут замечаю некоторые аномалии: -во-первых, не могу изменить данные у QSqlTableModel методом setRecord с EditStrategy=OnManualSubmit. Всё делаю как обычно а мне в ответ сообщение "No fields to update." До этого проект крупненький разрабатывали, там я точно так же пользовался и всё работало(там была какая-то более старая версия библиотеки). Собрал тот же проект с новой версией QT и точно такая же ошибка. При этом добавление работает отлично. Помогло только откат до предыдущей версии. -во-вторых, в программе никак не могу реализовать удаление из списка QListView. Ставлю у модели EditStrategy=OnManualSubmit, устанавливаю для QListView эту модель и описываю слот на удаление записи: Код: if(model->removeRow(ui.listView->currentIndex().row())) Пробовал понять исходный код QSqlTableModel, но после минуты осмотра он мне показался правильным =) Уж и не знаю как проблему исправить. Желающие прояснить ситуацию есть? =) Название: Re: Проблема с удалением в QSqlTableModel Отправлено: ритт от Сентябрь 09, 2008, 23:27 давай компилябельный пример, на котором можно посмотреть "аномалию"
лучше всего будет пример на базе стандартных примеров по скл под линуксом какая версия кутэ? Название: Re: Проблема с удалением в QSqlTableModel Отправлено: iamfomik от Сентябрь 10, 2008, 14:12 под линуксом версия 4.4.0, сейчас под виндой тоже. Ещё тестировал на FreeBSD.
во вложении два примера и стуктура БД к ним. первая программа просто изменяет запись. Вторая программа позволяет добавлять и удалять записи через QListView. после некоторых экспериментов: версия QT 4.4.1 FreeBSD первая программа пишет "No Fields to update" вторая программа делает так - removeRow возвращает true но из ListView строка не удаляется, а если нажать на SaveAll то строка удаляется. версия QT 4.4.1 Windows первая работает аналогично вторая никак не хочет реагировать и удалять версия QT 4.4.0 Windows первая программа работает отлично. вторая так же как и QT 4.4.1 FreeBSD Мне просто хочется использовать версию 4.4.1, потому хотелось бы разобраться с первой проблемой. Кстати говоря, setRecord там нормально изменяет запись, и если к той модели ещё и QSqlTableView подключить то, если после изменения потыкать по ячейкам, видно что запись изменяется. Однако model->submitAll в любом случае вызывает ошибку - "No fields to update". Впринципе вторая проблема не является проблемой, скорее корявостью. Может это я не так удаляю??? Мне нужно чтобы при нажатии на кнопку из списка удалялась строка, и только по нажатию на кнопку "saveAll" записи удалялись бы из БД. Вариант с изменением EditStrategy на любую другую для меня не приемлем. Название: Re: Проблема с удалением в QSqlTableModel Отправлено: ритт от Сентябрь 10, 2008, 20:08 первая проблема похожа на багу - перепробовал разные варианты, а желаемого эффекта не добился...
попозжа пороюсь в коде модели...кстати, ещё под 4.5.0 попробую прогнать - может известная бага вторая проблема - вовсе и не проблема. если бы у тебя был тэйблвью вместо листвью, сразу бы увидел, что строка при мануалсабмит только помечается на удаление, а удаляется непосредственно при сабмите. если не хочется наследоваться от модели, можно просто ловить её (модели) сигнал headerDataChanged для Qt::Vertical и сравнивать headerData для Qt::DisplayRole с QLatin1String("!") - так визуально строка помечается на удаление Название: Re: Проблема с удалением в QSqlTableModel Отправлено: iamfomik от Сентябрь 10, 2008, 20:21 хммм.... а как бы мне по сигналу от модели void beforeDelete( int row ) скрыть элемент в листВью ??? Или придётся наследовать? А если наследовать то как лучше сделать?
Название: Re: Проблема с удалением в QSqlTableModel Отправлено: ритт от Сентябрь 10, 2008, 20:50 сигнал beforeDelete высылается перед фактическим удалением строки - т.е. уже после submitAll
я так понял, что тебе это не подходит... > ловить сигнал headerDataChanged для Qt::Vertical бла-бла-бла самый простой способ реализовать данный перехват и не перегружать скл-модель - отнаследоваться от QSortFilterProxyModel, перегрузить filterAcceptsRow (проверять дату на равность QLatin1String("!")) и включить у прокси динамиксортфильтер таким образом строка будет скрываться из вьюхи в тот же момент, когда нажали кнопку "удалить", а фактически удаляться из бд строка будет только после submitAll (кстати, reverAll автоматически сделает строку снова видимой) по первой проблеме могу ещё предлложить отказаться от "ручного" перебора данных и довериться замечательному классу QDataWidgetMapper. позже я код всё-равно посмотрю, но на данный момент использование QDataWidgetMapper полностью закрыло бы проблему Название: Re: Проблема с удалением в QSqlTableModel Отправлено: iamfomik от Сентябрь 11, 2008, 09:44 На счёт прокси модели - это выход.
А QDataWidgetMapper'ы не всегда подходят. Во-первых проект уже написан, и делать глобальные изменения неуместно(я пока выбрал для него вариант откатить до старой версии QT). Во-вторых, не все поля таблицы можно связать через маппер, например иногда нужно что-то в ручную записать, то что не отображается, то что считается вручную. Хотя я бы конечно лучше использовал маппер(не понимаю почему я им не воспользовался =)) Как вариант решения проблемы с не полной универсальностью маппера - создать виртуальный виджет, он по интерфейсам будет подходить к мапперу, но он не будет рисоваться. Или есть другой способ? Или в QTуже есть подобие виртуального виджета? Название: Re: Проблема с удалением в QSqlTableModel Отправлено: ритт от Сентябрь 11, 2008, 10:56 колеса ("виртуального виджета") изобретать не надо. датавиджетмапперу можно установить делегат - надеюсь, этим всё сказано и не нужно расжёвывать? :)
если какие-то поля не нужно отображать, думаю, и редактировать их не нужно - просто не мапим их даже в случае, если ты всё-равно не захочешь связываться с датавиджетмаппером, можно писать данные через setData, а не через setRecord... Название: Re: Проблема с удалением в QSqlTableModel Отправлено: iamfomik от Сентябрь 11, 2008, 16:54 С виджет маппером наоборот - очень хочу с ним связываться. Использовать setData конечно можно, но гораздо больше кода будет...но это всё ладно...
Если какие-то поля не нужно отображать, то это не значит что их не нужно маппить. Вот на счёт делегатов это ты точно сказал, я совсем и забыл про них. Не совсем представляю как написать делегат который будет кушать и виджеты и просто переменные, но думаю способ найду. Кстати и проблему с удалением я намерен решить тоже при помощи делегата - есть такой QStyledItemDelegate, отнаследуюсь от него и просто буду удалённые записи помечать или скрывать. Спасибо за помощь, если проверишь ошибку под QT 4.5 отпишись потом, если не сложно. |