Russian Qt Forum
Ноябрь 26, 2024, 18:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSqlTableModel :: dataChanged signal???  (Прочитано 8207 раз)
Flakes
Гость
« : Декабрь 30, 2008, 12:41 »

Всем привет.

Работаю с QTableView и QSqlTableModel::OnFieldChange. После срабатывания submit() сбрасывается selection на модели. Я сохраняю selection в переопределенном setData(). Проблема в том, что мне теперь нужно восстанвоить selection, но никак не могу поймать тот самый момент, когда submit() сделался и модель обновилась, а selection соотвественоо сбросился. Пытался ловить и layoutChanged() и dataChanged(), и даже пулял emit dataChanged() внутри setData(), че то полная фигня, никакой сигнал не отлавливается.

Прошу о помощи!
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Декабрь 30, 2008, 17:38 »

connect(tableView->selectionModel(),SIGNAL(selectionChanged...............
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Flakes
Гость
« Ответ #2 : Декабрь 30, 2008, 21:08 »

А оно не зависнет в бесконечно цикле, когда я сделаю ручной setSelection()?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Декабрь 30, 2008, 21:21 »

А ты проверяй в слоте на пустоту селекта. Подмигивающий
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Flakes
Гость
« Ответ #4 : Декабрь 30, 2008, 21:25 »

Попробую, пасиба.
Записан
Flakes
Гость
« Ответ #5 : Январь 20, 2009, 02:35 »

В прошлый раз не вышло, решил передохнуть, но сейчас все таки уже приперло.

Значит у меня все обстоит так, кидаю полный код на основе cachetable example, чтоб было ясней некуда:

Код:
CustomSqlModel.cpp

CustomSqlModel::CustomSqlModel(QTableView **parentTable, QObject *parent) : QSqlTableModel(parent){
tableView = *parentTable;
}

bool CustomSqlModel::setData(const QModelIndex & index, const QVariant & value, int role){
saveSelection();
return QSqlTableModel::setData(index,value, role);
}

void CustomSqlModel::saveSelection(){
savedIndexList =  tableView->selectionModel()->selection().indexes();
}

void CustomSqlModel::loadSelection(){
// добавить немного волшебства тут
QItemSelection selection;
foreach (QModelIndex index, savedIndexList){
selection.select(index, index);
}
tableView->selectionModel()->select(selection, QItemSelectionModel::Select);
}

Код:
CustomSqlModel.h

class CustomSqlModel : public QSqlTableModel{
public:
CustomSqlModel(QTableView **parentTable, QObject *parent = 0);
QTableView *tableView;
QModelIndexList savedIndexList;
void saveSelection();
bool setData (const QModelIndex & index, const QVariant & value, int role);
void loadSelection();
};

Код:
TableEditor.cpp

TableEditor::TableEditor(){
QTableView *view = new QTableView;
model = new CustomSqlModel(&view, this);
...
connect(revertSelectionButton, SIGNAL(clicked()), this, SLOT(revertSelection()));
connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(revertSelection()));
...
}

void TableEditor::revertSelection(){
model->loadSelection();
}

Код:
TableEditor.h
...
private slots:
void revertSelection();
private:
QPushButton *revertSelectionButton;
...

Как я и предполагал, после setData() оно начинает стучаться в loadSelection() и начинаются зацикливания. Делал проверки на что угодно, пытался делать с флагами, на пустоту селекта  - нет смысла, ибо после setData() селект еще пуст. К тому же selectionChanged() сработает как минимум столько раз, сколько элементов savedIndexList (чтоб не запутать кого, можно выбрать сколько угодно ячеек, редактироваться будет та, на которой установлен current), на деле он сработает куда больше раз, рекурсивно. Была идея делать каждый раз disconnect(), но че то повторный connect уже не срабатывает.
Вся прелесть в том, что если нажать revertSelectionButton - селект загрузиться как надо, автоматом же - нивкакую, начинает циклить и ничего не селектит ваще.

Взываю о помощи!
Записан
Flakes
Гость
« Ответ #6 : Январь 24, 2009, 00:02 »

Посоветуйте куда копать???
Записан
Flakes
Гость
« Ответ #7 : Январь 25, 2009, 19:23 »

Я перетрахался со всеми только возможными сигналами и слотами, будь то от QItemSelectionModel, QSqlTableModel или QTableView, к чему я только не пытался коннектить или переопределять: modelAboutToBeReset(), modelReset(), dataChanged(), submit(), reset(), currentChanged(). Ну как же мне эту суку отловить в момент когда данные засабмителись и модель обновилась?

Просто тишь да гладь. Дайте плиз кусочек рабочего кода.
Записан
Dendy
Гость
« Ответ #8 : Январь 25, 2009, 19:44 »

Чесно говоря, до конца не разбирался. Но вижу одну ошибку. Сохранять список индексов нужно в QList<QPersistentModelIndex>, а не в QModelIndexList.
Записан
Flakes
Гость
« Ответ #9 : Январь 25, 2009, 20:52 »

Ну может и так, только вот сохранением у меня нет проблем.

Еще обнаружил одну особенность, которая не поддается объяснению. Я законнектил selectionChanged и loadSelection, как в примере выше, только разбрасал чуть конкретней, loadSelection(const QItemSelection & selected, const QItemSelection & deselected). Вначале loadSelection поставил условие
Код:
if (!(selected.size() == 0 && deselected.size() != 0))
return;

Ну и вроде остальная часть loadSelection выполняется как раз когда мне надо. Особенность в том, что любые манипуляции с таблицей не срабатывают. Я думал, ну ладно, может selectionChanged срабатывает когда можель обновилась, а данные в таблице еще не успели отобразиться, и селект успевает сбрасываться, до того как я успею его увидеть.

Решил проверить с QTimer::singleShot(2000, tableView, SLOT(setFocus())), все равно не катит, однако катит, когда делается тот же QTimer::singleShot() через button какой-нить. Но это еще можно понять, что оно ушло в новый thread, а в первом треде данные уже изменились, и метод не валидный и срабатывает.

Уже крыша едет.
« Последнее редактирование: Январь 25, 2009, 20:54 от Flakes » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 23.