Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Advise: QComboBox delegate which will take its dataset from QSqlQueryModel
Qt 6.11 is out! See what's new in the release blog

Advise: QComboBox delegate which will take its dataset from QSqlQueryModel

Scheduled Pinned Locked Moved General and Desktop
1 Posts 1 Posters 1.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    i92guboj
    wrote on last edited by
    #1

    Hello.

    I am "on my way":http://qt-project.org/forums/viewthread/31269/ to understanding how delegates work.

    Right now, I wanted to implement a QComboBox based delegate that will work on QTableView cells (not that that's relevant, I guess). The important bit is that it will take its dataset from a QSqlQueryModel.

    So far, the autocompletion and the combobox seems to be working, but I can't avoid the feeling of not having done something "the right way(TM)".

    I'll show you my code.

    [code]
    #ifndef COMPLETIONDELEGATE_H
    #define COMPLETIONDELEGATE_H

    #include <QItemDelegate>
    #include <QtSql/QSqlQueryModel>

    class CompletionDelegate : public QItemDelegate
    {
    Q_OBJECT
    public:
    explicit CompletionDelegate(QObject *parent = 0, QSqlQueryModel *model = NULL);

    QWidget *createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
    void setEditorData(QWidget* editor, const QModelIndex & index ) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    

    signals:

    public slots:

    private:
    QSqlQueryModel *model;

    };

    #endif // COMPLETIONDELEGATE_H
    [/code]

    [code]
    #include "completiondelegate.h"
    #include <QComboBox>
    #include <QtSql/QSqlQueryModel>
    #include <QDebug>
    #include <QtSql/QSqlRecord>
    #include <QtSql/QSqlQuery>
    #include <QCompleter>

    CompletionDelegate::CompletionDelegate(QObject *parent, QSqlQueryModel *mdl) :
    QItemDelegate(parent)
    {
    model = mdl;
    qDebug() << Q_FUNC_INFO << "we are building this";
    while(mdl->query().next())
    qDebug() << Q_FUNC_INFO << model->query().value(0);
    }

    QWidget CompletionDelegate::createEditor(QWidget parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
    {
    //const QAbstractItemModel model = index.model();
    if (!model)
    {
    return QItemDelegate::createEditor(parent, option, index);
    }
    QComboBox box = new QComboBox(parent);
    box->setEditable(true);
    box->setAutoCompletion(true);
    //box->setModel(const_cast<QAbstractItemModel
    >(model));
    box->setModel(model);
    //box->setModelColumn(index.column());
    box->setModelColumn(0);
    box->completer()->setCompletionMode(QCompleter::PopupCompletion);
    box->installEventFilter(const_cast<CompletionDelegate
    >(this));
    return box;
    }

    void CompletionDelegate::setEditorData(QWidget* editor, const QModelIndex & index ) const
    {
    QComboBox* box = qobject_cast<QComboBox*>(editor);
    const QAbstractItemModel *model = index.model();
    if (!box || !model)
    {
    QItemDelegate::setEditorData(editor, index);
    }
    box->setCurrentIndex(index.row());
    }

    void CompletionDelegate::setModelData(QWidget editor, QAbstractItemModel model, const QModelIndex &index) const
    {
    if (!index.isValid())
    return;
    QComboBox
    box = qobject_cast<QComboBox
    >(editor);
    if (!box)
    return QItemDelegate::setModelData(editor, model, index);
    model->setData(index, box->currentText(), Qt::DisplayRole);
    model->setData(index, box->currentText(), Qt::EditRole);
    }
    [/code]

    Then, I use it like this:

    [code]
    QSqlQueryModel *mdl_articulos = new QSqlQueryModel;
    mdl_articulos->setQuery("SELECT ref,desc,pvp FROM articulos;");
    ui->tableView_cascosYAccesorios->setItemDelegateForColumn(2, new CompletionDelegate(this, mdl_articulos));
    [/code]

    That's a QTableView, as said above.

    When I say that I have a feeling of having done something wrong I am talking specifically about passing the pointer to QSqlQueryModel as an argument to this class. Is that ok or is there a better way? I still don't understand properly what QModelIndex'es are, so I might be duplicating something... I see that all the typical functions that people reimplement in this class work with indexes so...

    How would you go about this?

    Of course, feel free to criticise any other part of the code...

    Thank you for your comments.

    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved