Russian Qt Forum

Qt => Базы данных => Тема начата: Denz от Май 11, 2013, 21:51



Название: primeInsert, datachanged
Отправлено: Denz от Май 11, 2013, 21:51
QSqlTableModel. Хочу, чтобы при добавлении строки, она сразу же заполнялась дефолтными значениями.
Хотел использовать сигнал primeInsert, у него есть два аргумента: номер строки, и объект класа QSqlRecord.
Я так понимаю, чтобы сделать заполнение строки значениями по умолчанию, я должен создать слот, который будет принимать этот сигнал, считывать из него номер строки и добавлять в неё данные. Зачем нужен второй параметр? Почитал документацию, так и не понял.

Мне не понятно, откуда вообще берется этот параметр. Потому что при вставке строки он никак не задается. А InsertRow посылает этот сигнал. То есть QSqlRecord  как определяется мне не ясно.

Еще один вопрос
В таблице есть поле, значение в котором автоматически изменяется при изменении значений других полей.
Для этого я использую dataChanged.
 
Код:
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(SetConclusion(QModelIndex, QModelIndex)));

Код:
void MainWindow::SetConclusion(QModelIndex leftIndex,QModelIndex rightIndex) {

    int Row = leftIndex.row();
    int Column = leftIndex.column();
    if(Column == 1 || Column == 2 || Column == 0) {
        QString ConclusionString = QString("%1 %2").arg(model->data(model->index(Row,1)).toString()).arg(model->data(model->index(Row,2)).toString());
        model->setData(model->index(Row, 53), ConclusionString);
        model->setData(model->index(Row,54), model->data(model->index(Row,2)).toString().toLower());
    }
    if(Column == 3 || Column == 6 || Column == 7 || Column == 8 || Column == 51 || Column == 52 || Column == 0 ) {
        model->setData(model->index(Row,55), model->data(model->index(Row,3)).toString().toLower());
        model->setData(model->index(Row,56), model->data(model->index(Row,6)).toString().toLower());
        model->setData(model->index(Row,57), model->data(model->index(Row,7)).toString().toLower());
        model->setData(model->index(Row,58), model->data(model->index(Row,8)).toString().toLower());
        model->setData(model->index(Row,59), model->data(model->index(Row,51)).toString().toLower());
        model->setData(model->index(Row,60), model->data(model->index(Row,52)).toString().toLower());
    }
}

Я заметил, что если в условие также не включать
Код:
 Column == 0
, значение не изменяется. В этом поле у меня  находится автоинкрементируемый СУБД SQLite id.  Но строки не добавляются, они просто редактируются.
Почему так происходит?  (фактически теперь все эти условия можно выбросить в помойку, потому что они всегда верные)
И как вам вообще мое решение? Я не имею представление, как обычно поступают в таких ситуациях, так что возможно, реализовал все через задний проход.  


Название: Re: primeInsert
Отправлено: mta88 от Май 12, 2013, 04:37
Из Qt Assistant
Цитировать
Цитировать
void QSqlTableModel::primeInsert(int row, QSqlRecord & record) [signal]
This signal is emitted by insertRows(), when an insertion is initiated in the given row of the currently active database table.
The record parameter can be written to (since it is a reference), for example to populate some fields with default values and set the generated flags of the fields.
Do not try to edit the record via other means such as setData() or setRecord() while handling this signal.

Как видно, во второй строке советуется записывать дефолтные значения полей во второй параметр (этот параметр и есть ваша новая строка).
В третье строке запрещается искать эту новую строку другими способами.

Так что записывайте все во второй параметр.



Название: Re: primeInsert
Отправлено: Denz от Май 12, 2013, 08:04
mta88, спасибо.

Вопрос по работе сигналов: они же только посылают информацию, но никак её не преобразовывают, не выполняют какие-либо другие операции, так ведь?
То есть мне нужно инициализировать указатель на QSqlRecord, и в том случае, если значения по умолчанию следует изменить, я просто меняю значения указателя на адрес, по которому находится другой объект?

И где лучше соединять слоты со сигналами? В конструкторе класса?
Посмотрю сейчас примеры на сайте Qt,  но, вероятно, это не внесет ясности, есть хорошая статья на тему использования QSqlRecord?
Меня интересует, как должен выглядеть объект этого класса, чтобы все поля заполнились, например, значением "неизвестно".

Можете привести простейший пример?


Название: Re: primeInsert
Отправлено: mta88 от Май 12, 2013, 09:49
вообще primeInsert кажется плохой идеей
он нужен только при использовании insertRows (вставке нескольких пустых записей)
проще несколько раз использовать insertRow (вставка одной готовой записи)

если все-же нужен primeInsert, то слот будет выглядеть как-то так
Код:
void mySlot(int row, QSqlRecord & record)
{
  record.setValue(...);
  record.setValue(...);
}

создавать слоты и соединять сигналы со слотами можно где угодно, избегая явного говнокода конечно-же

и необходимости в указателях здесь нигде не видно


Название: Re: primeInsert, datachanged
Отправлено: Denz от Май 19, 2013, 13:45
Обновил вопрос в открывающем топик посте, пожалуйста, обратите внимание, если кто может помочь советом, буду рад выслушать.


Название: Re: primeInsert, datachanged
Отправлено: eJinn от Май 24, 2013, 22:24
А как ты добавляешь строку?
Мне кажется, что тебе надо использовать не primeInsert, а beforeInsert.