Question

I have problem with QComboBox as item delegeate editor for QTableWidget. QTableWidget uses SqlTypeDelegate as item delegate.

When I draw QTableWidget inside QGraphicsScene(through QGraphicsProxyWidget) then QComboBox popup list of available items is not shown. But if I'm using QTableWidget as a normal widget(drawn not through QGraphicsScene\View) then QComboBox behavior is normal - it shows item list.

What should I do to force QComboBox to show its item list?

below sample code:

main.cpp:

#include <QtGui/QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QTableWidget>
#include "sqltypedelegate.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QGraphicsScene scene;
    QTableWidget *table = new QTableWidget(4,2);
    table->setItemDelegate(new SqlTypeDelegate(table));
    QGraphicsProxyWidget *proxy = scene.addWidget(table);
    QGraphicsView view(&scene);
    view.show();
    return app.exec();
}

sqltypedelegate.h:

#include <QItemDelegate>
#include <QStyledItemDelegate>
#include <QModelIndex>
#include <QObject>
#include <QSize>
#include <QComboBox>

class SqlTypeDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    SqlTypeDelegate(QObject *parent = 0);
    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;
    void updateEditorGeometry(QWidget *editor,
        const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

sqltypedelegate.cpp:

#include <QtGui>
#include "sqltypedelegate.h"

SqlTypeDelegate::SqlTypeDelegate(QObject *parent)
    : QItemDelegate(parent)
{}

QWidget *SqlTypeDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &/* option */,
    const QModelIndex &/* index */) const
{
    QComboBox *editor = new QComboBox(parent);
    editor->addItem(QString("decimal(50)"));
    editor->addItem(QString("integer"));
    editor->addItem(QString("varchar(50)"));
    editor->addItem(QString("char"));

    editor->setEditable(true);
    return editor;
}

void SqlTypeDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    QString value = index.model()->data(index, Qt::EditRole).toString();
    QComboBox *comboBox = static_cast<QComboBox*>(editor);
    comboBox->setEditText(value);
}

void SqlTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    QComboBox *comboBox = static_cast<QComboBox*>(editor);
    model->setData(index, comboBox->currentText(), Qt::EditRole);
}

void SqlTypeDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
    QComboBox *comboBox = static_cast<QComboBox*>(editor);
    comboBox->setGeometry(option.rect);
}
Was it helpful?

Solution

Finaly I've found solution: event filters! Just lurk for QEvent::MouseButtonRelease and then call showPopup.

bool SqlTypeDelegate::eventFilter(QObject *object, QEvent *event)
{
    QComboBox * comboBox = dynamic_cast<QComboBox*>(object);
    if (comboBox)
    {
        if (event->type() == QEvent::MouseButtonRelease)
        {
            comboBox->showPopup();
            return true;
        }
    }
    else
    {
        return QItemDelegate::eventFilter( object, event );
    }
    return false;
}

OTHER TIPS

I got the same problem and my workaround is add two line codes to createEditor(...).

editor->move(option.rect.x(),option.rect.y());
editor->showPopup();

Then when double clicking the table item, the QComboBox will show the popup items triggered by the second mouse button pressing and hide the popup items triggered by the second mouse button releasing. This works for Qt 4.8.

I also tried the Qt5.0 and the application crashed with or without this workaround. I have reported this issue as a bug.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top