Russian Qt Forum

Qt => Model-View (MV) => Тема начата: phpCoder от Январь 02, 2015, 18:41



Название: Делегат + QDateTimeEdit
Отправлено: phpCoder от Январь 02, 2015, 18:41
Добрый вечер.
Есть делегат с QDateTimeEdit. Как (с помощью какого сигнала или еще что...) можно отловить событие завершения редактирования?

Сигнал QDateTimeEdit::editingFinished не годится. Если в таблице тыкнуть на ячейку, появляется мой редактор. Далее, если тыкнуть мышью в другом месте таблицы/окна программы, то текст из редактора вставляется в ячейку, но событие того, что этот текст вставился не происходит.

Сигнал QDateTimeEdit::dateTimeChanged не годится. Как только поменяешь циферку, так сразу редактирование прекращается.

Сигналы QDateTimeEdit::dateChanged и QDateTimeEdit::timeChanged аналогично.

Что делать? Как обычно работают с таким делегатом?

Соединение делаю как в примерах:
Код
C++ (Qt)
QWidget *DateTimeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem&, const QModelIndex&) const
{
   QDateTimeEdit *editor = new QDateTimeEdit(parent);
   connect(editor, &QDateTimeEdit::editingFinished, this, &DateTimeDelegate::_commitAndCloseEditor);
   editor->setDisplayFormat("dd.MM.yyyy hh:mm:ss");
   return editor;
}
Код
C++ (Qt)
void DateTimeDelegate::_commitAndCloseEditor()
{
   QDateTimeEdit *editor = qobject_cast<QDateTimeEdit*>(sender());
   if(this->_value == editor->text()) return;
   emit commitData(editor);
   emit editingFinished(editor->property("row").toInt(), editor->dateTime().toString(Qt::ISODate));
   emit closeEditor(editor);
}


Название: Re: Делегат + QDateTimeEdit
Отправлено: PimenS от Январь 02, 2015, 21:22
Какую роль выполняет эта функция void DateTimeDelegate::_commitAndCloseEditor()?


Название: Re: Делегат + QDateTimeEdit
Отправлено: phpCoder от Январь 02, 2015, 21:41
Оповещает виджет, в котором есть таблица, что редактирование завершено и можно обновлять БД.
Это же видно из ее описания.


Название: Re: Делегат + QDateTimeEdit
Отправлено: PimenS от Январь 02, 2015, 21:49
Таблицу (т.е. представление) оповещает об изменении модель, в которой реализуются методы data и setData. Для чего оповещать представление из делегата?
Или у тебя таблица без модели?


Название: Re: Делегат + QDateTimeEdit
Отправлено: Johnik от Январь 02, 2015, 23:59
Есть делегат с QDateTimeEdit. Как (с помощью какого сигнала или еще что...) можно отловить событие завершения редактирования?
Сигнал QDateTimeEdit::editingFinished не годится. Если в таблице тыкнуть на ячейку, появляется мой редактор. Далее, если тыкнуть мышью в другом месте таблицы/окна программы, то текст из редактора вставляется в ячейку, но событие того, что этот текст вставился не происходит.

Сигнал QDateTimeEdit::dateTimeChanged не годится. Как только поменяешь циферку, так сразу редактирование прекращается.

Сигналы QDateTimeEdit::dateChanged и QDateTimeEdit::timeChanged аналогично.

Что делать? Как обычно работают с таким делегатом?
Стандартный делегат (QItemDelegate) не подсоединяется к сигналам, в нем реализован фильтр событий. Фильтр ждет такие события, как нажатие клавиш Enter, Return, Esc, Tab, события пропадания фокуса виджета. И соответствующим образом реагирует на них, как правило это commitData и/или closeEditor. Рекомендую посмотреть исходники.


Название: Re: Делегат + QDateTimeEdit
Отправлено: phpCoder от Январь 03, 2015, 09:38
Дак в исходниках как раз именно так. Пример: StarDelegate.
Там и эта функция. Я даже название не менял.

Правда нигде нет примера соединения делегата с его моделью... Чтобы отслеживать сделанные изменения.

Если у меня не правильно, то где найти правильно?

Вкратце так:
1. Есть Qtablewidget (агрегирован в объекте), в который я вставляю свой делегат.
2. После редактирования ячейки таблицы, этот делегат (в общем кто-нибудь) должен известить мой объект о завершении редакции. При этом, если новое значение совпадает со старым значением ячейки, то никаких телодвижений быть не должно (строка if(this->_value == editor->text()) return;).
3. В объекте, зная номер строки, где была правка, и новое значение ячейки, сделать sql запрос к БД и в ней поменять нужные данные. Ну и плюс сделать изменения в оформлении редактировавшейся ячейке.


Название: Re: Делегат + QDateTimeEdit
Отправлено: phpCoder от Январь 03, 2015, 10:26
--уже не актуально--


Название: Re: Делегат + QDateTimeEdit
Отправлено: PimenS от Январь 03, 2015, 10:38
Дак в исходниках как раз именно так. Пример: StarDelegate.
Там и эта функция. Я даже название не менял.

Правда нигде нет примера соединения делегата с его моделью... Чтобы отслеживать сделанные изменения.

Если у меня не правильно, то где найти правильно?

Зачем использовать QTableWidget для работы с базами данных? Это же очень не удобно. Есть же нормальное решение model - view.
Используй стандартную модель, если работаешь с простыми таблицами.


Название: Re: Делегат + QDateTimeEdit
Отправлено: phpCoder от Январь 03, 2015, 10:44
Нет, нет. В том-то и дело, что таблица не такая как в БД, а получается сложным запросом (из нескольких таблиц). И тогда вроде предлагаемой моделью не отделаешься.


Название: Re: Делегат + QDateTimeEdit
Отправлено: PimenS от Январь 03, 2015, 10:52
Тогда пишешь свою модель на QAbstractTableModel, и работаешь с этой моделью в QTableView. Почитай Земскова Юрия, хоть книжка и не новая, но хорошо расписано про работу с БД.

ЗЫ. могу показать пример моей модели, если есть желание использовать этот метод.


Название: Re: Делегат + QDateTimeEdit
Отправлено: phpCoder от Январь 03, 2015, 11:46
Если можно, буду благодарен!


Название: Re: Делегат + QDateTimeEdit
Отправлено: PimenS от Январь 03, 2015, 12:04
Писал на скорую руку, может что-то пропустил. Пример только на UPDATE.


Название: Re: Делегат + QDateTimeEdit
Отправлено: phpCoder от Январь 03, 2015, 13:12
А если старое значение ячейки совпадает с новым значением? Зачем делать запрос к БД.
Этого кажется не увидел.


Название: Re: Делегат + QDateTimeEdit
Отправлено: PimenS от Январь 03, 2015, 13:55
Ну это-то как раз не проблема. В setData измени условие, например так:

Код:
if (index.column() == 2 && role == Qt::EditRole && rowTable.value("date_record").toDate() != value.toDate())