PDA

View Full Version : QTableView



cpuinthebrain
25th June 2015, 11:08
Hello,

I'm a bit confused after reviewing all examples related to SQL and QTableView.So many models and approaches.
What i need is very simple: QWidget with QTableView. QDialog with fields and button "add" and SQL table.
When the user enters in the fields of the dialog data and click on the button "add" the new record to appear in the table.

I have tried to achieve this firstly with QSqlQueryModel.After that i tried with QSqlTableModel.With both i can't managed to release the update of the tableView.The record is in the DB, but the table doesn't update by it's self or manually with some method.

I need an advice how to achieve this simple example.
I also need answers of:
- Do i have to update the model only and the table will be updated autimaticly.Which model, and which method to use?
- Do i need to update the tableView after inserted a new record in the DB.Which model, and which method to use?

THANK YOU IN ADVANCE

anda_skoa
25th June 2015, 12:19
I haven't used the SQL models in read/write mode myself yet, but according to the documentation QSqlQueryModel is read-only by default, only QSqlTableModel supports writing.

How do you add the data to the table model?
Do you call submit afterwards?

Or do you add the data to the database table?
Do you call select() on the table model afterwards?

Cheers,
_

cpuinthebrain
25th June 2015, 12:47
partners.cpp


Partners::Partners(QWidget *parent) :
QWidget(parent),
ui(new Ui::Partners)
{
ui->setupUi(this);

//QSqlQueryModel *model = new QSqlQueryModel;

//model->setQuery("SELECT Name, City, Bulstat FROM partners");
//model->setHeaderData(0, Qt::Horizontal, QObject::tr("Име"));
//model->setHeaderData(1, Qt::Horizontal, QObject::tr("Град"));
//model->setHeaderData(2, Qt::Horizontal, QObject::tr("ЕИК:"));

QSqlTableModel *model = new QSqlTableModel();
model->setTable("partners");
model->select();
model->setEditStrategy(QSqlTableModel::OnFieldChange);
model->setHeaderData(1, Qt::Horizontal, tr("Име:"));
model->setHeaderData(3, Qt::Horizontal, tr("Град:"));
model->setHeaderData(7, Qt::Horizontal, tr("ЕИК:"));

ui->tableView_partners->setModel(model);
ui->tableView_partners->hideColumn(0);
ui->tableView_partners->hideColumn(2);
//ui->tableView_partners->hideColumn(3);
ui->tableView_partners->hideColumn(4);
ui->tableView_partners->hideColumn(5);
ui->tableView_partners->hideColumn(6);
//ui->tableView_partners->hideColumn(7);
ui->tableView_partners->hideColumn(8);
ui->tableView_partners->setColumnWidth(1,333);
ui->tableView_partners->setColumnWidth(3,200);
ui->tableView_partners->setColumnWidth(7,200);
//ui->tableView_partners->horizontalHeader()->sectionResizeMode(QHeaderView::Interactive);
//ui->tableView_partners->horizontalHeader()->setStretchLastSection(true);
ui->tableView_partners->show();

}

Partners::~Partners()
{
delete ui;
}


void Partners::updatePartnersTable()
{
qDebug() << "record added";
}






partnersadddialo.cpp



void PartnersAddDialog::on_pushButton_add_clicked()
{

QSqlQuery query;
query.prepare("INSERT INTO partners (Name, City, Address, MOL, Bulstat, VAT, Phone, eMail)"
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
query.addBindValue(ui->lineEdit_name->text());
query.addBindValue(ui->lineEdit_city->text());
query.addBindValue(ui->lineEdit_address->text());
query.addBindValue(ui->lineEdit_mol->text());
query.addBindValue(ui->lineEdit_bulstat->text());
query.addBindValue(ui->lineEdit_vat->text());
query.addBindValue(ui->lineEdit_tel->text());
query.addBindValue(ui->lineEdit_mail->text());

query.exec();
emit updateTable();
this->close();

}

anda_skoa
25th June 2015, 14:11
So you are adding to the database table directly.
You'll need to update the model by letting it fetch data from the database again, i.e. by calling select().

Cheers,
_

cpuinthebrain
25th June 2015, 15:19
Sounds good, but i don't know how to access it in the updateTable() function? or is there any way to have global access to the model?

anda_skoa
25th June 2015, 15:54
You have three options:

1) a member variable holding a pointer to the model
2) getting the model from the view and casting
3) connect the updateTable() signal to the model's select() slot

Cheers,
_

cpuinthebrain
25th June 2015, 16:07
1.First one have no idea how to make it?

2. I tried this
ui->tableView_partners->model()->select();
but it doesn't give me this method select()

3.connect( how to make it, the same question, how to access the model:


connect(d, SIGNAL(updateTable()), model, SLOT(select()));
It gives me error "undeclared identifier model"

anda_skoa
25th June 2015, 17:16
1) member variables are basic C++ knowledge, should be in any C++ tutorial
2) cast missing
3) basic C++ compiler error message: no variable with the name "model" in that context

Cheers,
_

cpuinthebrain
25th June 2015, 19:38
2) what should i cast ? please give an example

3)
I created the model like this

QSqlTableModel *model = new QSqlTableModel(this);

why i can't access them in the function thru

this->model()

The most important - is there any way to access the model from everywhere (other class, functions) - global access?

d_stranz
25th June 2015, 23:38
Do you actually know C++?


this->model()

Does the class that "this" points to have a method called "model()"? If not, and you do actually know C++, then the answer to the question should be pretty obvious.

cpuinthebrain
26th June 2015, 08:04
You are right, i need time to switch from Python.

OK, which is the way to skip the repeating of the creation of QSqlQueryModel twice, but access the model in whole class?



Partners::Partners(QWidget *parent) :
QWidget(parent),
ui(new Ui::Partners)
{
ui->setupUi(this);

QSqlQueryModel *model = new QSqlQueryModel(this);

model->setQuery("SELECT Name, City, Bulstat FROM partners");
model->setHeaderData(0, Qt::Horizontal, QObject::tr("Име"));
model->setHeaderData(1, Qt::Horizontal, QObject::tr("Град"));
model->setHeaderData(2, Qt::Horizontal, QObject::tr("ЕИК:"));

ui->tableView_partners->setModel(model);
ui->tableView_partners->setColumnWidth(0,325);
ui->tableView_partners->setColumnWidth(1,200);
ui->tableView_partners->setColumnWidth(2,200);
ui->tableView_partners->horizontalHeader()->sectionResizeMode(QHeaderView::Interactive);
ui->tableView_partners->show();

}

Partners::~Partners()
{
delete ui;
}


void Partners::addPartner()
{
QSqlQuery query;
query.prepare("INSERT INTO partners (Name, City, Address, MOL, Bulstat, VAT, Phone, eMail)"
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
query.addBindValue(1);
query.addBindValue(2);
query.addBindValue(3);
query.addBindValue(4);
query.addBindValue(5);
query.addBindValue(6);
query.addBindValue(7);
query.addBindValue(8);
query.exec();

QSqlQueryModel *model = new QSqlQueryModel(this);
model->setQuery("SELECT Name, City, Bulstat FROM partners");
ui->tableView_partners->setModel(model);
qDebug() << "record added";
}

Lesiok
26th June 2015, 08:41
Define variable model as a class member not a local variable.

d_stranz
26th June 2015, 18:17
You are right, i need time to switch from Python.


At least all you will need to worry about is punctuation, and not whether your code is indented properly...


Define variable model as a class member not a local variable.

What Lesiok means is define a variable "QSqlQueryModel * model;" as a member of your Partners class. In the constructor, simply say:


model = new QSqlQueryModel(this);

(i.e., omit the type declaration). This will assign the value of the new model instance to the member variable, and more importantly, allow you to access the variable value in other methods of the Partners class. If you need access to this value from outside the partners class, then you can define a member function for Partners that returns the pointer:



// Partners.h

class Partners : public // whatever
{
// ...
public:
QSqlQueryModel * model() const { return model; }

private:
QSqlQueryModel * model;
};

// SomeOtherClass.cpp
void SomeOtherClass::useTheModel()
{
// Assumes a SomeOtherClass member variable Partners * thePartners
thePartners->model()->clear( );
// ...
}