Russian Qt Forum

Qt => Model-View (MV) => Тема начата: mwChief от Март 01, 2010, 05:44



Название: QtableView и QSqlTableModel добавление новой строки
Отправлено: mwChief от Март 01, 2010, 05:44
Обьясните пожалуйста как добавлять новую строку в таблицу. Или дайте ссылку на внятный пример.


Название: Re: QtableView и QTableModel добавление новой строки
Отправлено: voronElf от Март 01, 2010, 10:10
Если QStandardItemModel, используй insertRow, из доков понятно вполне как пользоваться. Если своя модель, то я это делал обычно внутри, средствами модели, вызывая layoutChanged сигнал.


Название: Re: QtableView и QTableModel добавление новой строки
Отправлено: Karl-Philipp от Март 01, 2010, 11:15
Обьясните пожалуйста как добавлять новую строку в таблицу. Или дайте ссылку на внятный пример.
ссылка на внятный пример  :D
http://doc.qt.nokia.com/4.6/itemviews-editabletreemodel.html


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: mwChief от Март 01, 2010, 13:27
Сразу ошибся в названии темы - написал QTableModel вместо QSqlTableModel. Правду говорят что утро вечера мудренее  ;D
Загрузил я  табличку из базы, отобразил в QtableView. Пробую добавлять:
Код:
int row=model.rowCount();
model.insertRow(row);
ui->tableView->selectRow(row);
ui->tableView->setFocus();
Если не так попровьте пожалуйста.
Код выполняется по нажатию на кнопку потому возвращаю фокус TableView.
В результате строка добавляется, но если в нее не добавть значение, то в базу она не сохранится.
Если кнопку нажать сразу два раза то по первому нажатию добавится одна строка, а по второму добавится еще одна строка, но она будет не редактируемой.
То же самое будет со всеми последующими.
Что нужно чтобы все строки сразу сохранялись и их можно было редактировать.


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: mwChief от Март 01, 2010, 19:41
Уверен что у меня неправильно. Кто-нибудь обьяснит по шагам что нужно делать чтобы добавить новую строку и чтобы она тут же сохранилась в базу?


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: Пантер от Март 01, 2010, 19:51
Глянь на void QSqlTableModel::setEditStrategy ( EditStrategy strategy )


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: mwChief от Март 01, 2010, 20:13
Смотрел на QSqlTableModel::setEditStrategy. Написано следующее
Note: To prevent inserting only partly initialized rows into the database, OnFieldChange will behave like OnRowChange for newly inserted rows.
А для QSqlTableModel::OnRowChange :
Changes to a row will be applied when the user selects a different row.

Получается мне нужно программно имитировать "user selects a different row."
Вопрос, как это сделать? Это, конечно, с учетом правильности моих выводов и правильности написаного выше кода, в чем я сильно сомневаюсь.


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: Пантер от Март 01, 2010, 20:44
Попробуй QSqlTableModel::OnFieldChange


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: mwChief от Март 01, 2010, 20:56
Абсолютно никакого эффекта.


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: Пантер от Март 01, 2010, 21:01
Приложи сюда минимальный компилябельный пример.


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: mwChief от Март 01, 2010, 21:02
Вот пример, хотелось бы чтоб при нажатии на кнопку добавить все добавленные элементы сохранялись в базу, даже если их не править после вставки.
http://narod.ru/disk/20530310000/example.zip.html


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: Пантер от Март 01, 2010, 22:17
Сильно копаться времени нет, но помогло вот что:
Код
C++ (Qt)
model->insertRow(row);
model->setData(model->index(row, 0), "");
 
Т.е. нужно инициализировать хоть одно поле.


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: mwChief от Март 01, 2010, 22:37
Одна это строка не помогла
Код
C++ (Qt)
model->setData(model->index(row, 0), "");
 
Добавил еще
Код
C++ (Qt)
model->submitAll();
 
тогда заработало.
Спасибо.


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: Пантер от Март 01, 2010, 23:19
А можно сделать ход конем - добавлять запись через QSqlQuery и обновлять модель.


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 08, 2010, 15:47
А у меня почему-то не добавляется. Есть  QSqlTableModel и QTableView. в меню есть кнопка для которой сделан обработчик:
Код:
void MainWindow::on_create_record_triggered()
{
    QSqlRecord rec = model1.record();
    ui->mytable->selectRow(row);//Где row - число строк
    model1->insertRow(row);
    model1->setData(model1->index(row, 0), "");//Пустая строка
    ui->mytable->setFocus();//Так как вызываю ф-ию из меню
}
При нажатии на кнопку реакции никакой, сам обработчик срабатывает


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: crossly от Май 08, 2010, 15:55
Код:
void MainWindow::on_create_record_triggered()
{
    QSqlRecord rec = model1.record();
    model1->insertRecord(-1,rec);
    model1->submitAll();
}


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 08, 2010, 18:04
Никакой реакции


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 09, 2010, 14:44
и зачем вообще -1 в insertrow.  нам нужно число строк и это явно не -1. Я уже все мыслимые методы добавления перепробовал, не добавляет. Может зависит от конкретной совокупности виджетов...вот мои: tableview, sqlrelationtablemodel, и собсно добавляю :
Код
C++ (Qt)
QSqlRecord rec = model1.record(row);
   model1.insertRecord(row,rec);
model1.submitAll();
Хочу получить пустую строку, далее уже имеющимися средствами ее редактировать. Что же может быть не так?


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 09, 2010, 21:32
удаление повесил на эту же кнопку, не работает:
Код
C++ (Qt)
model1.removeRows(row-1,row);
model1.submitAll();
Может всё зависит от сигналов\слотов. Хотя остальное, что есть в этом обработчие есть выполняется да и  model1.lasterror() возвращает (-1"",""). В чем же может быть дело?


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: lit-uriy от Май 09, 2010, 22:06
Код
C++ (Qt)
// ---------- вставка строки в модель ----------
int row = model->rowCount();
 
if (!model->insertRow(row))
{
QMessageBox::critical(this, tr("БД"),
tr("Вставка строки вызвала следующую ошибку:\r\n %1")
.arg(model->lastError().databaseText()));
return;
}
 
// ---------- Удаление строки из модели ----------
 
// Узнаем выделенную строку
QItemSelectionModel *selectionModel = view->selectionModel();
QModelIndexList indexes = selectionModel->selectedIndexes();
 
int size = indexes.size();
 
if (size > 1){
int ret = QMessageBox::critical(this,
tr("Предупреждение"),
tr("Вы уверены что хотите удалить %1 строк?").arg(),
QMessageBox::Yes | QMessageBox::Cancel
);
if (ret == QMessageBox::Cancel){
return;
}
}
 
 
 
foreach(QModelIndex index, indexes)
{
QString str;
int row = index.row();
if (!model->removeRows(row,1)){
str = model->lastError().text();
qDebug() << str << "\n\r";
break;
}
}
 
 
// ---------- Сохранение изменений ----------
if (!model->submitAll()){
qDebug() << "Model Error:" << model->lastError();
model->revertAll();
return;
}
 
 


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 09, 2010, 22:25
Спасибо, добрый человек, но сам до этого додумался недавно:
Код
C++ (Qt)
if(!model1.insertRows(row,1))
{
   qDebug()<<"not insrted, because:"<<model1.lastError();
}
Выдает:
Код:
not insrted, because: QSqlError(-1, "", "") 

Но вот что выдает удаление...:
Код
C++ (Qt)
if(!model1.removeRow(row))
{
   qDebug()<<"not removed in if, because:";
   qDebug()<<model1.lastError();
}

собственно:
Код:
not removed in if, because: 
QSqlError(-1, "Unable to delete row", "")


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 09, 2010, 23:13
И вот что еще интересно, если написать :
Код
C++ (Qt)
model1.insertRows(row,1);
   insertIndex = model1.index(row, 0);
     qDebug()<<insertIndex;
ui->mytable->setCurrentIndex(insertIndex);
ui->mytable->edit(insertIndex);
model1.submitAll();
 
то выдаёт:
Код:
QModelIndex(-1,-1,0x0,QObject(0x0) ) 
edit: index was invalid
edit: editing failed


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: lit-uriy от Май 09, 2010, 23:39
>>not insrted, because: QSqlError(-1, "", "")
а в представлении строка появляется?


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 10, 2010, 08:08
нет, туда я ее и хочу получить и вручную редактировать.
Проблема в индексе, только не могу понять , почему такое может быть и как с этим бороться...
Код
C++ (Qt)
insertIndex = model1.index(22, 0);
   qDebug()<<model1.index(22,0);
   qDebug()<<insertIndex;
Результат одинаковый:
Код:
QModelIndex(-1,-1,0x0,QObject(0x0) ) 
QModelIndex(-1,-1,0x0,QObject(0x0) )
при этом rowcount() выдает верное число


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 10, 2010, 13:12
ни у кого больше нет мыслей по этому поводу?


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 10, 2010, 14:17
Почти отрыл собаку, были проблемы с указателем... теперь, вроде как колонки добавляет, думаю строки тоже, но ... таблица теперь не отображается...
В хедере:
Код
C++ (Qt)
QSqlTableModel model1;
QTableView view;
В исходнике:
Код
C++ (Qt)
   model1.setTable("peoples4");
   model1.select();
   ui->mytable->setModel(&model1);
   ui->mytable->setEditTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed);
  view.setModel(&model1);
До этого у меня в исходнике создавался указатель и в setmodel  я указвал просто model1 без &. Почему может не отображаться содержимое таблицы?


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: lit-uriy от Май 10, 2010, 15:07
Расскажи подробнее об этих объектах:
ui->mytable
и
view
Где создаются какой тип имеют.
Также интересно услышать причину создания объекта на стеке вместо динамического создания


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 10, 2010, 16:11
mytable это мой центральный виджет qtableview. Но теперь это не важно, создал тестовый проект , в нем реализовал часть функционала и добавление строк. Добавление работает отлично! А вот с моим проектом интересное творится...: Добавляю в ui новый элемент через дизайнер, ну предположим еще одну кнопку в меню. Все прекрасно добавляется, при запуске предлагает сохранить изменения в project.ui сохраняю и запускась , только вот кнопки созданной нету в программе. Я писал несколько информационыых сообщений в qDebug() чтобы отследить работу некоторых частей и они меня информировали, писали нужные данные, стали мне не нужны - я их удалил, только они по прежнему пишут... Прямо код -призрак. Сделал rebuild all, перенес проект в другую папку, Убрал "только для чтения" ничего не помогло, по прежнему изменения не вносятся, с остальным разобрался, проект немаленький, не хочется с нуля переписывать... Кто-нибудь сталкивался с такой магией?


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 10, 2010, 18:06
В Общем имеет место у меня неправильное использование указателей:
В хедере:
Код
C++ (Qt)
  QSqlTableModel model1;

Далее в исходнике использую указатель, иначе не будет добавлять строки...
Код
C++ (Qt)
  ui->mytable->setModel(&model1);
А вот в другой функции как мне применить указатель, когда я хочу сделать в
Код
C++ (Qt)
void rowexper::on_actionFrty_triggered()
{
  model1.insertRow(model1.rowCount());
  model1.submitAll();//Тут мы не работаем с указателем, поэтому , наверное, строки не добавляются
 
 
}


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: lit-uriy от Май 10, 2010, 18:34
>>Далее в исходнике использую указатель,
Вобще-то указатель ты не используешь, ты используешь адрес объекта созданого на стеке (так же известного под именем "обычная переменная" и "скаляр").

>>А вот в другой функции как мне применить указатель
А к чему ты его собрался применять?

И вопрос в силе: "Также интересно услышать причину создания объекта на стеке вместо динамического создания"


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 10, 2010, 21:36
Под динамическим созданием ты подразумеваешь, на сколько  понял, создание переменной в использующей ее функции. Мне нужно использовать переменную model1 как в главной функции, так и в обработчике кнопки, причем нужно, чтобы кнопка и главная функция могли работать напрямую с переменной для этого использую адрес переменной( спасибо за поправку). Как вот все это грамотнее реализовать пока не соображу .


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: lit-uriy от Май 11, 2010, 16:01
>>Под динамическим созданием ты подразумеваешь, на сколько  понял,
>>создание переменной в использующей ее функции.
нет, я понимаю следующую запись:
Код
C++ (Qt)
var = new ClassName();

>>Как вот все это грамотнее реализовать пока не соображу .
В объявлении класса пишешь:
Код
C++ (Qt)
private:
   ClassName *var;
А в конструкторе класса инициализируешь этот указатель динамически созданным объектом:
Код
C++ (Qt)
var = new ClassName();


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: crossly от Май 11, 2010, 16:11
а вас QSqlTableModel или QSqlRelationalTableModel ??


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 11, 2010, 18:17
Спасибо, попробую. У меня QSqlTableModel.


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 11, 2010, 18:30
Спасибо, попробую. У меня QSqlTableModel. и вопрос: получается,что сначала в одной потом в другой ф-ии я объявляю новый элемент класса с одним и тем же именем? Вот только программа при запуске падает с критической ошибкой и сообщением в дебаге:
Код:
ASSERT failure in QVector<T>::at: "index out of range", file ../../include/QtCore/../../src/corelib/tools/qvector.h, line 327


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: crossly от Май 11, 2010, 18:33
интересно .... как это у вас так получается.... показать можешь??


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 11, 2010, 18:43
Да сам ненарадуюсь, что сотворил...  Смотрите на здоровье:

main.cpp:
Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent)
   : QMainWindow(parent), ui(new Ui::MainWindowClass)
{
   ui->setupUi(this);
   model1 = new QSqlTableModel;
   proxyModel = new QSortFilterProxyModel;
   db = QSqlDatabase::addDatabase("QMYSQL");
   db.setDatabaseName( "organization" );
   db.setHostName("localhost");
   db.setUserName("root");
   db.setPassword("trenkinan90");
   if(db.open())
   {
 
   QTextCodec::setCodecForCStrings(QTextCodec::codecForName("windows-1251"));
   model1->setTable("peoples4");
   model1->select();
   ui->mytable->setModel(model1);
   ui->mytable->setEditTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed);
row = model1->rowCount();
 
        proxyModel->setSourceModel(model1);
        ui->mytable->setModel(proxyModel);
   QTextCodec::setCodecForTr(QTextCodec::codecForName("windows-1251"));
   model1->setHeaderData(6, Qt::Horizontal,
                  tr("Женат/замужем"));
   model1->setHeaderData(8, Qt::Horizontal,
                  tr("Дата рождения"));
    view.setAlternatingRowColors(true);
    view.setModel(model1);
    QSqlQuery temp;
 }
   else qDebug()<<"Error in opening"<<db.lastError();
}
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
void MainWindow::on_create_triggered()
{
   model1 = new QSqlTableModel;
   model1->insertRow(row);
   model1->submitAll();
}
 

 Заголовочный файл:
Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QAction>
#include<QMenu>
#include<QtSql>
#include <QModelIndex>
#include <QTableView>
#include <QSortFilterProxyModel>
#include <QtGui/QMainWindow>
 
namespace Ui
{
   class MainWindowClass;
}
 
class MainWindow : public QMainWindow
{
   Q_OBJECT
 
public:
   MainWindow(QWidget *parent = 0);
   ~MainWindow();
   int row;
   QTableView view;
QSqlRecord rec;
QModelIndex insertIndex;
   QSqlDatabase db;
   QMenu menu;
 
private:
   Ui::MainWindowClass *ui;
   QSqlTableModel *model1;
   QSortFilterProxyModel *proxyModel;
 
private slots:
   void on_create_triggered();
};
Это созданный мной тестовый проект, с остальным функционалом не связан. Но и там и тут одна и та же ошибка. Думаю, связано с неаккуратной работой с памятью( с указателями).


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: crossly от Май 11, 2010, 18:50
ох ты еп........ товарисч.... модель нужно создавать после соединения с БД.... потому как ей нужно действующее соединение.... и совсем не нужно делать это 2 раза...


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 11, 2010, 20:46
Простое человеческое Спасибо тебе, crossly. Заработало. Не бейте ногами, я ж не знал, что нужно сначала то а потом это=) ну вы понимаете что=). Буду делать дальше. Удаление пока не пробовал, думаю там все тоже работает


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: lit-uriy от Май 11, 2010, 23:54
ну два раза, разумеется, создавать модель не нужно.


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 12, 2010, 07:06
Вопрос не по теме, но новую создавать не хочу : Как сделать боевую раскраску а-ля "тельняшка"(полоса белая-полоса светло серая) в таблице и как сделать один столбец синим?


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: Kolobok от Май 12, 2010, 10:41
Как сделать боевую раскраску а-ля "тельняшка"(полоса белая-полоса светло серая) в таблице

setAlternatingRowColors ( bool enable )


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 12, 2010, 11:14
уже давно сделал. Что дальше?


Название: Re: QtableView и QSqlTableModel добавление новой строки
Отправлено: trenkinan от Май 12, 2010, 23:51
Извините, разобрался, Использовал по ошибке сразу две модели... А как теперь сделать один Столбец синим?