Skip to content
QtWS25 Call for Papers
  • 0 Votes
    7 Posts
    155 Views
    J

    @jdent I know: value.isNull()!!

  • 0 Votes
    4 Posts
    114 Views
    JonBJ

    @jdent
    You have to iterate through the rows looking for the value you want.
    If you use a QSortFilterProxyModel you can take advantage of binary search for speed if you sort by primary key. QSqlRelationalTableModel is not important here, all that gives is a "lookup" on one field to map e.g. an integer value to a corresponding string from a related table for display.

  • 0 Votes
    12 Posts
    243 Views
    Christian EhrlicherC

    Please read the docs of submitAll():
    "In OnManualSubmit, on success the model will be repopulated. Any views presenting it will lose their selections."

  • 0 Votes
    8 Posts
    109 Views
    JonBJ

    @jdent

    but I don't'see a method moveColumn()

    bool QAbstractItemModel::moveColumn(const QModelIndex &sourceParent, int sourceColumn, const QModelIndex &destinationParent, int destinationChild)

    But (and I see @SGaist has just posted) you don't want to move columns around in the model to change the order they are displayed. You do this in the view, the QHeaderView which is the QTableView::horizontalHeader() , by moving its sections.

  • 0 Votes
    4 Posts
    125 Views
    JonBJ

    @jdent said in What is the best way to display a Join between 2 or 3 tables? QSqlQueryModel?:

    Ok, I thought there was more explicit support for joins

    Yes, there isn't :) Qt provides low-ish level support for database table access, nothing fancy, nothing for an arbitrary JOIN. The only "extra" is QSqlRelationalTableModel Class, which implements a specific JOIN for a foreign key. There will be third-party code, e.g. KDAB, out there which builds another layer on top if you want it.

  • 0 Votes
    2 Posts
    77 Views
    J

    @jdent The column names contained spaces!! Problem solved!!

  • 0 Votes
    1 Posts
    248 Views
    No one has replied
  • 0 Votes
    3 Posts
    518 Views
    JonBJ

    @Lucky01
    So far you have asked about Laravel and SQL in PHP. Why do you want to use this forum if you are using them and not Qt? Beats me.

  • 0 Votes
    14 Posts
    971 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
    3 Posts
    322 Views
    M

    Guys; May you please some help. I reached to a dead end

  • 0 Votes
    4 Posts
    292 Views
    S

    Hi @JonB yes the selects are used as you've described. While waiting for answers I refound QxORM via Inqlude which looks like it has a soft deleted option so may more than do what I require.

    Thanks for the response

  • 0 Votes
    3 Posts
    420 Views
    A

    @JonB thanks!

  • Aplikacja SQL

    Unsolved Polish
    1
    0 Votes
    1 Posts
    486 Views
    No one has replied
  • 0 Votes
    1 Posts
    1k Views
    No one has replied
  • 0 Votes
    5 Posts
    485 Views
    B

    Well, it took a lot of time for me to solve this problem. I solved it not in the way I wanted, but it works fine.
    Firstly, work with MS Access multi-valued fields is quite strange but quite simple: you should clear a field like DELETE Field.Value FROM MyTable WHERE Table.ID = MyID;. Then you can leave it clear or populate with new values performing several INSERT queries: INSERT INTO MyTable (Field.Value) VALUES (MyValue) WHERE MyTable.ID = MyID;.
    And it turned out that it's not that easy to make such code work in OnManualSubmit strategy table model, so I've made a widget which allows you to modify such fields. It is called MultiValueEditor.
    MultiValueEditor.h

    #ifndef MULTIVALUEEDITOR_H #define MULTIVALUEEDITOR_H #include <QDialog> #include <QListWidget> #include <QHash> #include <QSqlRelation> class MultiValueEditor : public QDialog { Q_OBJECT QModelIndex m_projectIndex; QListWidget* m_list; QHash<int, QListWidgetItem*> m_idToItem; public: explicit MultiValueEditor(QModelIndex t_index, const QSqlRelation& t_relation, QWidget* parent = nullptr); ~MultiValueEditor(); public slots: void accept() override; signals: void signalFinished(); }; #endif // MULTIVALUEEDITOR_H

    MultiValueEditor.cpp

    #include "multivalueeditor.h" #include <QSqlQuery> #include <QVBoxLayout> #include <QDialogButtonBox> #include <QPushButton> #include <QMessageBox> #include <QSqlError> #include <QDebug> #include <QSortFilterProxyModel> #include <QSqlTableModel> MultiValueEditor::MultiValueEditor(QModelIndex t_index, const QSqlRelation& t_relation, QWidget *parent) : QDialog(parent) , m_projectIndex(t_index) { const QString queryStr = QString("SELECT [%1], [%2] FROM [%3] ORDER BY [%2];") .arg(t_relation.indexColumn(), t_relation.displayColumn(), t_relation.tableName()); QSqlQuery query(queryStr, QSqlDatabase::database()); m_list = new QListWidget; while (query.next()) { const int id = query.value(0).toInt(); const QString value = query.value(1).toString(); QListWidgetItem* item = new QListWidgetItem(value); m_list->addItem(item); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(Qt::Unchecked); m_idToItem[id] = item; } QString value = m_projectIndex.data(Qt::EditRole).toString(); if (!value.isEmpty()) { for (const QString& id : value.split(';')) { m_idToItem[id.toInt()]->setCheckState(Qt::Checked); } } QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttonBox, &QDialogButtonBox::accepted, this, &MultiValueEditor::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &MultiValueEditor::reject); QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addWidget(m_list); mainLayout->addWidget(buttonBox); setLayout(mainLayout); setWindowTitle(QString("Edit field '%1'").arg(t_relation.tableName())); setAttribute(Qt::WA_DeleteOnClose); } MultiValueEditor::~MultiValueEditor() {} void MultiValueEditor::accept() { // I use QSFPM, but there can be either QSqlTableModel or QSqlRelationalTableModel const QSortFilterProxyModel* proxyModel = qobject_cast<const QSortFilterProxyModel*>(m_projectIndex.model()); QSqlTableModel* sqlModel = qobject_cast<QSqlTableModel*>(proxyModel->sourceModel()); const QString primaryKeyName = sqlModel->headerData(0, Qt::Horizontal).toString(); const QString tableName = sqlModel->tableName(); const QString fieldName = sqlModel->headerData(m_projectIndex.column(), Qt::Horizontal).toString(); QString queryStr = QString("DELETE [%1].Value FROM [%2] WHERE [%3]=:tableId;") .arg(fieldName, tableName, primaryKeyName); QSqlQuery query; query.prepare(queryStr); const int tableId = m_projectIndex.siblingAtColumn(0).data().toInt(); query.bindValue(":tableId", tableId); if (!query.exec()) { QMessageBox msgBox(QMessageBox::Critical, ERROR_TITLE, QString("Error executing SQL-query\n%1") .arg(query.lastError().text()), QMessageBox::Ok, this); msgBox.exec(); } for (auto it = m_idToItem.constBegin(); it != m_idToItem.constEnd(); ++it) { if (it.value()->checkState() == Qt::Checked) { queryStr = QString("INSERT INTO [%1] ([%2].Value) " "VALUES (:fieldId) WHERE [%3]=:tableId;") .arg(tableName, fieldName, primaryKeyName); query.prepare(queryStr); query.bindValue(":fieldId", it.key()); query.bindValue(":tableId", tableId); query.exec(); } } emit signalFinished(); close(); }

    And in a place where you manage your table view (in my case in the MainWindow) you should connect TableView's double click with the execution of the MultiValueEditor. In my case it looks like this:
    MainWindow.cpp

    void MainWindow::setupDatabaseModels() { //... connect(m_projectTableView, &CustomTableView::doubleClicked, this, &MainWindow::slotEditProject); //... } void MainWindow::slotEditProject(const QModelIndex &index) { const int col = index.column(); if (col == 5) { QSqlRelation relation = QSqlRelation("Employees", "ID", "Name"); MultiValueEditor* multivalueEditor = new MultiValueEditor(index, relation, this); connect(multivalueEditor, &MultiValueEditor::signalFinished, [=](){ m_projectTableModel->select(); }); multivalueEditor->open(); } //... }

    Hope this will help somebody.

  • 0 Votes
    10 Posts
    761 Views
    T

    @Christian-Ehrlicher It caches entries that could have fairly high resolution images in them. 100MB consumed is quite reasonable for my particular use case. I've solved my problem my creating a general-purpose list model class which does not retain too many recent items in memory, and then implementing an application-specific subclass that will automatically produce small, low-resolution thumbnails and save them to a separate table to allow for faster loading later on.

  • 0 Votes
    2 Posts
    919 Views
    Christian EhrlicherC

    Make sure that all needed dlls are found when trying to load the ibase plugin -> check with Dependency Walker if the ibase plugin has all it's dependencies available.

  • 0 Votes
    13 Posts
    5k Views
    W

    @Maikie130 If you have many tools, you can toss them all in the bin dir of one big AppDir made by linuxdeploy. For example, /opt/maiki/usr/bin and everything in that bin dir will get set with rpath by linuxdeploy to look for libraries in /opt/maikie/usr/lib, but nothing else on the system will get impacted by those libraries, so you don't have to duplicate but you can easily accumulate stuff in that appdir that is easy to move to your server.

    The qt plugin has binarties published, so you can just use that rather than building it from source. They use the same appdir style of bundling everything into an image, so you can just grab the binary, chmod it +x and use it.

  • 0 Votes
    14 Posts
    3k Views
    K

    what is your suggestion about server app design ?

    People usually refer to "server app" as "middleware" or "web application". There are tons of web frameworks and ORMs for various languages including Java and C# on "enterprise" side and scripting languages (pphp, python, perl, ruby, node.js). C++ is not really convenient language here. As for protocol, if you are not pursuing real-time data processing with lowest possible latency, it makes sense to use REST API on top of HTTP, so that on server side you have the most typical "web app" with ORM inside and REST outside, and on client side you can easily add web client if needed, and even if not, you get some additional convenience as compared to e.g. RPC over plain TCP

  • 0 Votes
    13 Posts
    3k Views
    Christian EhrlicherC

    @bartoszpaj said in BindValue() in QPSQL is not working?:

    driver()->hasFeature(QSqlDriver::NamedPlaceholders) returns false.

    Good catch. I think it's because support for PostgreSQL 10 was added in a later version. If the version is not known to the driver it will fall back to the oldest.