How to fill database sqlite tablewidget - c++

I am writing "SQLite" database and I create the database table like this:
void MainWindow::createdata()
{
QSqlQuery query;
query.exec("DROP TABLE messages");
query.exec("CREATE TABLE messages("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"IPAddress VARCHAR(20),"
"date VARCHAR(10),"
"message VARCHAR(30))");
query.prepare("INSERT INTO messages(IPAddress, date, message) values(?,?,?)");
query.addBindValue("192.168.1.1");
query.addBindValue("jun 3 2016");
query.addBindValue("hello");
if (query.exec()) {
qDebug() << "ok!";
}
else
{
qDebug() << query.executedQuery();
qDebug() << query.lastError();
}
}
And i create "qtablewidget" like this:
QTableWidget* table = new QTableWidget();
table->setRowCount(10);
table->setColumnCount(4);
table->setWindowTitle("Received Message");
table->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
table->setHorizontalHeaderLabels(QString("ID;HostAddress;Date;Message").split(";"));
table->setStyleSheet("QTableView {selection-background-color: blue;}");
table->setEditTriggers(QAbstractItemView::NoEditTriggers);
table->setSelectionBehavior(QAbstractItemView::SelectRows);
table->setSelectionMode(QAbstractItemView::SingleSelection);
QSqlQuery query("SELECT * FROM messages");
but i don't know how should i fill the "tablewidget" to show with query.
Can anyone please help me?Thanks

You should use QTableView (Model based version of table view) and then using QSqlQueryModel, you can populate your table.
QSqlQueryModel *model = new QSqlQueryModel();
model->setQuery(query);
tableView->setModel(model);
To use QSqlQueryModel with a QTableWidget, you should iterate through QSqlQueryModel row by row and add them to your QTableWidget.
QSqlQueryModel *model = new QSqlQueryModel();
model->setQuery(query);
int i;
QSqlRecord row
for(i = 0, row = model->record(i); !row.isEmpty(); i++, row = model->record(i)){
// Get each field using `value` method of variabale 'row'
// and insert this fields to its corresponding cell in QTableWidget
}
Relevant Question:
Setting the model to a QTableWidget

Related

Select query returns "value: not positioned on a valid record" in Qt

I have been working on a small code which is supposed to fill up columns on a QTableWidget with values fetched from a SQL table.
Here's a small snippet:
QString path = "C:\\ENTRIES.db";
QString itemToSearch = "ABC"; //This comes as a parameter to a slot actually, assigning it here for simplicity
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(path);
db.open();
QSqlQuery query(db);
query.prepare("SELECT * FROM METADATA WHERE ITEM LIKE ':item %'");
query.bindValue(":item", itemToSearch);
if(query.exec())
{
ui->tableWidgetSearchResults->setVisible(true);
ui->tableWidgetSearchResults->clearContents();
int rCount = ui->tableWidgetSearchResults->rowCount();
while(query.next())
{
ui->tableWidgetSearchResults->setRowCount(rCount + 1);
QTableWidgetItem *qtwParamName = new QTableWidgetItem;
qtwParamName->setFlags(qtwParamName->flags() & ~Qt::ItemIsSelectable & ~Qt::ItemIsEditable);
qtwParamName->setText(query.value(0).toString());
ui->tableWidgetSearchResults->setItem(rCount, 0, qtwParamName);
QTableWidgetItem *qtwParamValue = new QTableWidgetItem;
qtwParamValue->setFlags(qtwParamValue->flags() & ~Qt::ItemIsSelectable & ~Qt::ItemIsEditable);
qtwParamValue->setText(query.value(1).toString());
ui->tableWidgetSearchResults->setItem(rCount, 1, qtwParamValue);
rCount++;
}
}
else
{
qDebug() << "Error message: " << query.lastError().text() ;
ui->tableWidgetSearchResults->setHidden(true);
}
db.close();
When executing query.value(<index here>).toString()); lines, the Application Output prints:
QSqlQuery::value: not positioned on a valid record
QSqlQuery::value: not positioned on a valid record
I'm not sure of what I am missing here.
Note: I am using Qt 5.6, MSVC 2013 compiler and SQLite 3.8.
#CL. Thanks for the hint. I tried this line and it worked:
query.prepare("SELECT * FROM METADATA WHERE ITEM LIKE '" + itemToSearch + "%'");
Apparently bindValue was inappropriate in this case.

Empty qsqlrelationaltablemodel

When I put model->select(); after relations, the model is empty, when I put it back before relations, the table displays correctly, but when I edit any cell the whole row becomes empty and gets "!" on the left. No errors.
QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this, db1);
model->setTable("syllabi");
model->setEditStrategy(QSqlTableModel::OnFieldChange);
model->select();
model->setRelation(3, QSqlRelation("activity_types", "activity_type_id", "activity_type_name"));
model->setRelation(0, QSqlRelation("teachers", "teacher_id", "teacher_name"));
//model->select();
qDebug() << model->lastError();
ui->tableView->setModel(model);
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));
ui->tableView->horizontalHeader()->setStretchLastSection(true);
ui->tableView->setColumnHidden(9, true);

Showing output of sql query inside a QLabel

I am writing a qt gui application where I am planning to show the output of an sql query inside a QLabel.
Now population the output inside a QTableView model is simple enough and that I can do using;
QSqlDatabase dbSqlite = QSqlDatabase::addDatabase("QSQLITE"); //these 2 lines for SQLite DB connection
dbSqlite.setDatabaseName("/home/aj/test.db");
dbSqlite.setUserName("aj");
QString MyQuerySqlite = ui->sqlite_queryEdit->text(); //take the query from a QLineEdit
dbSqlite.open(); //open db connection
QSqlQuery query(MyQuerySqlite,dbSqlite);
if(query.exec()) //populate in table
{
this->model1=new QSqlQueryModel();
model1->setQuery(MyQuerySqlite);
ui->sqlite_tableView->setModel(model1);
qDebug()<<QDateTime::currentDateTime()<<"SQLITE QUERY SUCCESS "<<dbSqlite.lastError().text();
}
Any idea on how to achieve this inside a QLabel ???
The output of the query will be one single record. For example the name of the world's tallest mountain, or the name of the capital of Engalnd. Just single records.
If you want to use QSqlQueryModel for this, you can use QSqlQueryModel::record ( int row ) to retrieve a specific record and then QSqlRecord::value ( int index ) to get a field's value :
QString str = model1->record(0).value(0).toString();
label->setText(str);
You can get result with value method. For example:
QString country;
QSqlQuery query("SELECT country FROM artist");
while (query.next()) {
country.append( query.value(0).toString() + " ");
}
label->setText(country);
Also you can read data from model1. Something like:
label->setText(model1->data(model1->index(0,0),Qt::DisplayRole).toString());

QT ComboBox ItemData from Database

I have the following code which links a QT QComboBox to my sqlite database and it works great.
However in my database I have the Category and Item table linked with a foreign key.
So when I pull info from the QComboBox I need to get the Category_ID not the name which is listed in the box.
How would I go about setting the QComboBox ItemData to the Category_ID field with a model or better yet use the model to set the QComboBox ItemData as my Category Object?
Thanks,
void MainWindow::populatCat()
{
QSqlQueryModel *model = new QSqlQueryModel();
QString sql;
sql = "select Category_Name From Category ORDER BY Category_Name ASC;";
QSqlQuery* query = new QSqlQuery(db);
query->prepare(sql);
if(!query->exec()){
qDebug () << "Query Erorr: " << query->lastError();
}else{
qDebug () << "Query Successful: " << query->lastQuery();
}
model->setQuery(*query);
ui->cboCat->setModel(model);
}
Okay, I'll present an answer now. :)
QComboBox* myBox = new QComboBox();
connect( myBox, SIGNAL( indexChanged( int ) ), this, SLOT( handleIndexChange( int ) ) );
void myObject::handleIndexChange( int /*index*/ ) {
// We actually don't need the index
QComboBox* box = qobject_cast<QComboBox*>( sender() );
if ( box ) {
QVariant data = box->currentData(); // do whatever w/ data... sounds like call toInt() in your case.
}
}
The essence of all three of my approaches is that you have to do something extra to get data() which corresponds to the current item after a change. It would be nice if it emitted a signal taking the underlying data as the argument, but that could get expensive.

How to make a column of a table editable?

I'm trying to make a table that will allow a user to enter a mark out of 10 given some criteria. I'm connected to my SQLite database and retrieving a column on the left for the description of the criteria, and a column on the right where I want to be able to enter a grade (an editable column). Here is my code:
QSqlQueryModel *model = new QSqlQueryModel();
QSqlQuery* qry = new QSqlQuery(conn.mydb);
qry->prepare("select I.itemDescription, S.grade from Items I, ItemsToStudent S where I.itemID = S.itemID and I.rubricID = ? and S.courseID = ? and S.studentID = ?");
qry->addBindValue(actid);
qry->addBindValue(courseid);
qry->addBindValue(studentid);
qry->exec();
model->setQuery(*qry);
ui->rubricTable->setModel(model);
However, I can't make the second column editable. How would I go about accomplishing this?
The QSqlQueryModel class provides a read-only data model for SQL result sets. You can use QSqlRelationalTableModel like:
QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this,conn.mydb);
model->setEditStrategy(QSqlTableModel::OnFieldChange);
model->setJoinMode(QSqlRelationalTableModel::LeftJoin);
model->setTable( "Items" );
model->setRelation( 0, QSqlRelation( "ItemsToStudent", "itemID", "grade" ) );
model->setFilter( QString("rubricID = ? and courseID = ? and studentID = ?") );
model->select();
model->setHeaderData( 1, Qt::Horizontal, tr("Criteria") );
model->setHeaderData( 2, Qt::Horizontal, tr("Grade") );
ui->rubricTable->setModel(model);
You can also hide the columns you don't want to show like:
ui->rubricTable_tbl->hideColumn(3);