У меня проблема с QComboBox в качестве редактора удаления элементов для QTableWidget.
QTableWidget использует SqlTypeDelegate в качестве делегата элемента.
Когда я рисую QTableWidget внутри QGraphicsScene (через QGraphicsProxyWidget), всплывающий список доступных элементов QComboBox не отображается.
Но если я использую QTableWidget в качестве обычного виджета (рисуется не через QGraphicsScene \ View), тогда поведение QComboBox нормальное — он показывает список элементов.
Что я должен сделать, чтобы заставить QComboBox показать свой список элементов?
ниже пример кода:
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);
}
Наконец, я нашел решение: фильтры событий!
Просто прячитесь за QEvent :: MouseButtonRelease и затем вызывайте 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;
}
Я получил ту же проблему, и мой обходной путь — добавить двухстрочные коды для createEditor (…).
editor->move(option.rect.x(),option.rect.y());
editor->showPopup();
Затем, если дважды щелкнуть элемент таблицы, QComboBox покажет всплывающие элементы, вызванные нажатием второй кнопки мыши, и скроет всплывающие элементы, вызванные отпуском второй кнопки мыши. Это работает для Qt 4.8.
Я также попробовал Qt5.0, и приложение рухнуло с этим решением или без него.
Я сообщил об этой проблеме как об ошибке.