Skip to content
  • 0 Votes
    5 Posts
    180 Views
    Christian EhrlicherC

    Do you use Qt6. 7 on win11? Then you are probably using the windows 11 style.

  • 0 Votes
    11 Posts
    414 Views
    Pl45m4P

    @Donald9307

    Just to clear the confusion, do you have any model or in which way do you use your query?
    Because there is no QSqlQuery::setQuery() (as in the title).

    But good to hear that it worked for you :)

  • 0 Votes
    9 Posts
    356 Views
    K

    I have worked with the qsqlcipher plugins well and gone through with the qsqlcipher plugin code and I puted some print statement in the plugin code itself then observed that the fetchNext function taking is more time, Please look into it

  • 0 Votes
    14 Posts
    908 Views
    D

    @RyanSolanki Please mark as solved if you are happy the issue is resolved. Also consider reading up further about Qt's memory management model (maybe it would make sense to pass a parent during the QSqlQueryModel's construction to avoid all that manual memory management or else perhaps smart pointers if there is no clear parent to assign ownership to).

    Furthermore, SGaist's point about passing a pointer to a function whose signature expects a const reference cannot be understated. If the function expects a pointer, give it a pointer. If it expects a const reference, give it an object created on the stack! https://doc.qt.io/qt-5/qsqlquerymodel.html#details
    The documentation is good; use it! It is unclear to me why you are using functions such as "clear" for the model. The setQuery() function already clears the model. Why mess around with new and delete several times when you can just pass in a new query to modify the existing model? Futhermore, why bother clear()-ing the model immediately before you delete it? The destructor is called during the delete, which itself frees up any resources, per the documentation.

    There are deeper problems of comprehension going on here!

  • 0 Votes
    4 Posts
    224 Views
    R

    @Christian-Ehrlicher Yep. QIdentityProxyModel works fine. Thanks.

  • 0 Votes
    2 Posts
    403 Views
    JonBJ

    @hobbyProgrammer
    You cannot have a combo which is both bound to a model and has some extra row inserted into it --- it's one or the other.

    There are several possible approaches:

    Make your SQL query return a UNION ALL which includes a literal <select> as an extra row. Not really nice, because it makes the <select> be an extra row from the query.

    Copy the result set from the query into another model (you probably only need a list, perhaps a QStringList) where you insert the extra <select> as an item and use that as the combo's model. If you don't get a better example, this is the most obvious to code.

    Interpose a QIdentityProxyModel between the query model and the combo, and add the extra row there. I suspect this is the way it's supposed to be done(?).

  • 0 Votes
    9 Posts
    939 Views
    Pl45m4P

    @christian-ehrlicher said in What to subclass?:

    Especially compared to the idea to parse the data somehow from a sqlite file

    Where I have said that? :)
    I never had the idea to "parse" the sqlite file directly.

    I will try to get the data with a query first and see what I can do with it :)
    (I guess QSqlResult is the key?!)

  • 0 Votes
    3 Posts
    941 Views
    D

    So I tried the suggestions by @jwernerny. I dumped the QSqlQueryModel and went with a QStandardItemModel. TableView now displays correctly. Code now looks like this:

    void MainWindow::on_btnLoadTable_clicked() { conn = new Connection("LOCALHOST\\SQLEXPRESS", "Plants"); stdModel = new QStandardItemModel(this); conn->init(); //Set driver and connection options conn->open(); qry1 = new QSqlQuery(conn->db); const int COL_COUNT = 3; if (qry1->exec("spBatchesPerPlant")) { qDebug() << "Executing query..."; int row = 0; //used for counting rows in the query while (qry1->next()) //Loop through the results { for (int col = 0; col < COL_COUNT; col++) { stdItem = new QStandardItem(qry1->value(col).toString()); stdModel->setItem(row, col, stdItem); } row++; } ui->tableView->setModel(stdModel); } }

    Motto of the story: stored procedures generate forward only queries. QSqlQueryModel does not work for forward only queries, so use a standard item (or custom) model.

  • 0 Votes
    3 Posts
    637 Views
    SGaistS

    Hi,

    Add a setter to your model that is Q_INVOKABLE and pass your query through it. Don't forget to add proper error checking to give feedback to your user if something goes wrong.

  • 0 Votes
    3 Posts
    2k Views
    SGaistS

    Hi,

    There’s also no need to allocate the query on the heap as the QSqlQueryModel::setQuery method parameter suggests.

  • 0 Votes
    2 Posts
    790 Views
    SGaistS

    Hi and welcome to devnet,

    You can use a proxy model that adds the columns you want/need.

    You can keep updating the DB content and trigger the GUI update at some known interval or when a certains amount of changed happened to the database.

  • 0 Votes
    6 Posts
    4k Views
    p3c0P

    @Cleiton-Bueno Yes. If the query string is correct it will work.

  • 0 Votes
    2 Posts
    1k Views
    Chris KawaC

    Można użyć modelu proxy, który będzie interpretował jakieś dane (np. "0" i "1") jako checkbox, np.

    class MyProxy : public QIdentityProxyModel { public: MyProxy(QObject* parent) : QIdentityProxyModel(parent) {} QVariant data(const QModelIndex& index, int role) const override { if (role == Qt::CheckStateRole && index.column() == 0) { QString str_value = QIdentityProxyModel::data(index, Qt::DisplayRole).toString(); return (str_value == "1") ? Qt::Checked : Qt::Unchecked; } return QIdentityProxyModel::data(index, role); } bool setData(const QModelIndex& index, const QVariant& value, int role) override { if (role == Qt::CheckStateRole && index.column() == 0) { QString str_value = (value.toInt() == Qt::Checked) ? "1" : "0"; return QIdentityProxyModel::setData(index, str_value, Qt::EditRole); } else return QIdentityProxyModel::setData(index, value, role); } Qt::ItemFlags flags(const QModelIndex& index) const override { Qt::ItemFlags f = QIdentityProxyModel::flags(index); if (index.column() == 0) f |= Qt::ItemIsUserCheckable; return f; } };

    oczywiście numer kolumny i dane rozpoznawane jako "zaznaczony" można sobie dostosować.
    Takiego modelu można użyć potem tak:

    QSqlTableModel* model = new QSqlTableModel(parent, database); MyProxy* proxy = new MyProxy(parent); proxy->setSourceModel(model); tableView->setModel(proxy);
  • 0 Votes
    4 Posts
    1k Views
    kshegunovK

    @_compiler

    Model *derived = static_cast<QSqlQueryModel*>(model);

    This isn't a valid cast because you can't implicitly cast to a derived type (see @mrjj's comment).

    Model *derived = static_cast<Model *>(model);

    Is valid but unsafe, as @SGaist pointed out.

    Ultimately, what is not working?

  • 0 Votes
    2 Posts
    2k Views
    Aleksey_KA

    Yeah, according to QComboBox code should work:

    QVariant QComboBox::itemData(int index, int role) const { Q_D(const QComboBox); QModelIndex mi = d->model->index(index, d->modelColumn, d->root); return d->model->data(mi, role); }

    Will implement this.

  • 0 Votes
    1 Posts
    860 Views
    No one has replied
  • 0 Votes
    2 Posts
    1k Views
    Resurr3ctionR

    I would do:

    int id = model->index(index.row(), 1).data().toInt();

    The sequence of the columns in the query is the same as in the model and the view so 0=name, 1=id. The model is obtained either directly from the class where you have it or from the view using QListView::model().

  • 0 Votes
    6 Posts
    2k Views
    SGaistS

    You have more information about why you can't copy QObject derived class here

  • 0 Votes
    2 Posts
    2k Views
    SGaistS

    Hi and welcome to devnet,

    They index provides you the row/column of the clicked item, so you can request the data from the index of the id column and the same row that you just clicked.

    Hope it helps