Important: Please read the Qt Code of Conduct -

QSpinbox delegate not added with QSqlQueryModel

  • Hi,

    I'm working with inventory management application. It shows available items of the inventory by using a tableview. I want to add a new Column to that tableview which has a SpinBox delegate for each row. Using the spinbox user will tell the quantity he want from that item. (see sample image)

    To do that I intended to use QItemDelegate.

    Before going to the implementation I went through the Spinbox ItemDelegate Example and "this": video. On those examples delegate created for the QStandardItemModel.

    But in my case I have to retrieve data from databases. So I move to QSqlQueryModel. But It not gave me the delegate.

    What can I do?

    Here is my code.

    @#ifndef DIALOG_H
    #define DIALOG_H

    #include <QDialog>
    #include <QtCore>
    #include <QtGui>
    #include <QSqlDatabase>
    #include <QSqlQueryModel>
    #include "delegate.h"

    namespace Ui {
    class Dialog;

    class Dialog : public QDialog

    explicit Dialog(QWidget *parent = 0);
    QSqlDatabase myDatabase();

    Ui::Dialog *ui;
    QSqlQueryModel *model;
    Delegate *mydelegate;

    #endif // DIALOG_H

    @#include "dialog.h"
    #include "ui_dialog.h"

    Dialog::Dialog(QWidget *parent) :
    ui(new Ui::Dialog)

    mydelegate = new Delegate(this);
    model=new QSqlQueryModel(this);
    model->setQuery(QString("SELECT * FROM Main WHERE Main.Type LIKE 'PVSP %';")
                    , myDatabase());


    QSqlDatabase Dialog::myDatabase()
    //Code to connect DB
    return db;

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

    @#include "delegate.h"
    #include <QItemDelegate>
    #include <QModelIndex>
    #include <QObject>
    #include <QSize>
    #include <QSpinBox>

    Delegate::Delegate(QObject *parent) :

    QWidget *Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
    QSpinBox *editor= new QSpinBox(parent);
    return editor;

    void Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    int value= index.model()->data(index,Qt::EditRole).toInt();

    QSpinBox *spinbox= static_cast<QSpinBox*>(editor);


    void Delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    QSpinBox spinbox= static_cast<QSpinBox>(editor);
    int value = spinbox->value();

    void Delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const


    P .S. : All the data displayed in the tableview according to the query.

    Thank in advance.

  • Moderators

    you haven't implemented the sizeHint() method of your delegate.

    Also you could use QAbstractItemView::sizeHintForColumn() to set the size for a specific column.

  • @ raven-worx,

    Thanks for the reply.

    But my poor explanations directed you to the wrong path.

    I edited my post and now I think it says more things than before.

    Thanking you..

  • Moderators

    do you mean "QAbstractItemView::openPersistentEditor()": ?

  • No, I above image is just a sample image to show what I want.

    I detailed the requirement as points.

    1. I have item database. I query it using QSqlQueryModel and set that model to the QTableView. It is working fine and display the data according to the query. :)

    2. Then user should add the items to his cart by selecting how much he wants. To do that I need a 'Amount'Column with QSpinBox delegates as like as in above image. But I can not get that delegate. :(

    Can you help me?

  • Moderators

    so you do want to edit the value of the field in your database?
    Or do you just want to display an additional column in the table for the amount (with no relation to the sql table data)

  • latter one.

    I want to display the additional column as 'Amount' in the tableview. No relation to the table.

  • Moderators

    well...that changes everything ;)

    You would make the view think there is an additional column. To do so you would need to implement a QProxyModel.
    To this QProxyModel you set your sql model. The QProxyModel gets set tot the view.
    Now basically you need to reimplement almost all virtual methods of the QProxyModel class and check if the passed model index points to your faked column (by checking the column index). If so return/call your desired values, else return/call the corresponding QProxyModel implementation.

    This is rather easy when you decide that your additional column should be the last column. If you decide to be anywhere in between other columns (like on the screenshot you've posted) you will have to map the index to the actual column index first before passing it tot he QProxyModel implementation.
    Another possibility instead of the index mapping would be to add it at the last position anyway and then just change the visual index of the column (see QHeaderView to do so), so the logical index stays the same.

    So i think thats enough work to do for now ;)

  • :(

    It means I have to start from the beginning.

    OK raven-worx. Now I begin to work in your path. First have to investigate what is QProxyModel.

    Thank you very much!

    When I got problems I'll contact you. ;)

  • Moderators

    no not from the beginning. All you have so far is more or less reusable :)
    You are just missing the implementation to mimic the fake column.
    So your sql model needs an "extension" with the QProxyModel.

    But what i don't understand is:
    In your delegate you are taken the value for the QSpinBox editor from your model, which is currently an sql model. But you said you want the column not a in relation to the sql table/model.

  • [quote author="raven-worx" date="1390294118"]
    But what i don't understand is:
    In your delegate you are taken the value for the QSpinBox editor from your model, which is currently an sql model. But you said you want the column not a in relation to the sql table/model.[/quote]

    First I try to follow the tutorial which I mentioned in the beginning. So QStandardItemModel created. Then I try to change the model to QSqlQueryModel.

    It happens because of that.

Log in to reply