How to show the result of multiple selects in QTableView using QSqlQueryModel - c++

I am using the following approach to show the result of a select statement in the QTableView. How should I modify this code to show the result of two or more different select statements in the same QTableView?
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
QString dbPath = "test1.db";
db.setDatabaseName(dbPath);
QSqlQueryModel *model = new CustomSqlModel();
QSqlQuery* query = new QSqlQuery(db);
query->prepare("SELECT * FROM MyTable");
query->exec();
model->setQuery(*query);
model->setHeaderData(0, Qt::Horizontal, "Col1");
model->setHeaderData(1, Qt::Horizontal, "Col2");
model->setHeaderData(2, Qt::Horizontal, "Col3");
QTableView* tableView = new QTableView();
tableView->setModel(model);
I need to append the data selected from the same table in another database test2.db to the data already shown in the tableView.

To append the result of one query to another, use a compound SELECT statement:
SELECT * FROM MyTable
UNION ALL
SELECT * FROM MyOtherTable
This requires that the subselects have the same number of columns.
If the other table is in another database, you must ATTACH it to the first one:
db.exec("ATTACH '/somewhere/else/test2.db' AS test2");
...
query->prepare("SELECT * FROM MyTable UNION ALL SELECT * FROM test2.MyTable");

Related

Filtering query by QLineEdit and updating QSqlQueryModel

I got a lineExdit and a tableView i want live update tableView base on typing text in lineEdit.
void updateTableView(QString *st)
{
QSqlQuery * qry = new QSqlQuery(mydb);
qry->prepare("select * from Poems where Title like ?%");
qry->addBindValue(st);
qry->exec();
You are abusing the pointers when it is not necessary, for example the QSqlQuery is creating it using the dynamic memory, and you do not eliminate it, the same with the QString.
Assuming that the QTableView model is a QSqlQueryModel then you should do the following:
...
// constructor
connect(your_le, &QLineEdit::textChanged, this, &YourClass::updateTableView);
...
void updateTableView(const QString & st)
{
QSqlQuery query(mydb);
query.prepare("select * from Poems where Title like ?");
query.addBindValue(QString("%1%").arg(st));
query.exec();
your_QSqlQueryModel->setQuery(query);
}

How to bind a selected row's first column value to a variable and use it in an SQL Command in QT?

Here is my code, it crashes on button click:
QSqlQueryModel*Acceuil::consulter_evenements()
{
QSqlDatabase bd= QSqlDatabase::database();
QSqlQueryModel * model=new QSqlQueryModel();
model->setQuery("SELECT E.* FROM EVENEMENT AS E JOIN CATALOGUES_EVENEMENTS as CE JOIN CATALOGUES as C ON C.ID_Catalogue = CE.ID_Catalogue AND E.ID=CE.ID_Evenement AND C.ID_Catalogue='"+ui->listeCatalogues->selectionModel()->selectedRows(0).at(0).data(Qt::DisplayRole).toString()+"' GROUP BY ID_Catalogue");
return model;
}
I tried binding "ui->listeCatalogues->selectionModel()->selectedRows(0).at(0).data(Qt::DisplayRole).toString()" to a QString but it crashed as well.
Replacing the query with a simple one such as "SELECT * FROM EVENEMENT" did not work as well.
When you use model->setQuery( ... ) you should use QSqlQuery as argument.
Create QSqlQuery object. Bind all values to query with QSqlQuery::bindValue or similar methods. And only after that make model->setQuery( queryWithMybindedValues )

How to fill database sqlite tablewidget

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

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);

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);