QItemDelegate中编辑器的大小

时间:2017-01-02 14:51:57

标签: c++ qt qcombobox qitemdelegate

我有一个来自QItemDelegate的自定义Delegate,它在第一列中提供了QComboBox,在所有其他列中提供了QLineEdit。

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

QWidget *SensorDisplayDelegate::createEditor(QWidget *parent,
                                             const QStyleOptionViewItem &option,
                                             const QModelIndex &index) const
{
    int col = index.column();
    if(col == 0)
    {
        QComboBox *comboBox = new QComboBox(parent);
        connect(comboBox, SIGNAL(activated(int)), this, SLOT(setData(int)));
        comboBox->setEditable(false);
        //comboBox->setMaximumSize(editorSize);
        comboBox->setInsertPolicy(QComboBox::NoInsert);
        currentComboBox = comboBox;
        return comboBox;
    }
    else       
    {
        QLineEdit *lineEdit = new QLineEdit(parent);
        return lineEdit;
    }

    return NULL;
}

void SensorDisplayDelegate::setEditorData(QWidget *editor,
                                          const QModelIndex &index) const
{
    int col = index.column();
    if(col == 0)
    {
        QComboBox *comboBox = static_cast<QComboBox*>(editor);
        QStringList comboItems = index.data(Qt::EditRole).toStringList();

        comboBox->addItem("Add New Sensor");
        comboBox->addItems(comboItems);

        QCompleter *completer = new QCompleter(comboItems);
        completer->setCaseSensitivity(Qt::CaseInsensitive);
        comboBox->setCompleter(completer);
        comboBox->showPopup();
    }
    else
    {
        QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
        lineEdit->setText(index.data(Qt::EditRole).toString());
        lineEdit->show();
    }
}

void SensorDisplayDelegate::setModelData(QWidget *editor,
                                         QAbstractItemModel *model,
                                         const QModelIndex &index) const
{
    int col = index.column();
    if(col == 0)
    {
        QComboBox *comboBox = static_cast<QComboBox*>(editor);
        if(comboBox->currentIndex() == 0)
            emit addNewSensor();
        else
            emit populateSensorView(comboBox->currentText());
    }
    else
    {
        QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
        model->setData(index, QVariant(lineEdit->text()));
    }

}

void SensorDisplayDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
    editor->setGeometry(option.rect);
}

QSize SensorDisplayDelegate::sizeHint(const QStyleOptionViewItem &option,
                                      const QModelIndex &index) const
{
    return editorSize;
}


void SensorDisplayDelegate::setData(int option)
{
    emit commitData(currentComboBox);
    emit closeEditor(currentComboBox);
}

editTrigger已设置为selectClicked。我希望组合框覆盖QTableView中的整个单元格。但是,现在它只是在左上角显示为blip。我尝试通过在QTableView上侦听mousePressed的事件过滤器传递单元格大小来设置最小大小。但是,从不调用委托中的相应槽。这是代码:

MultiEventFilter.cpp:

bool MultiEventFilter::eventFilter(QObject *obj, QEvent *event)
{
    if(event->type() == QEvent::MouseButtonPress)
    {
        if(obj->objectName() == "sensorlocationTableView")
        {
            QTableView *sensorView = static_cast<QTableView*>(obj);
            QModelIndexList idxs = sensorView->selectionModel()->selectedIndexes();
            if(!idxs.empty())
            {
                QModelIndex idx = idxs.at(0);
                emit passCellSize(QSize(sensorView->columnWidth(idx.column()),
                                        sensorView->rowHeight(idx.row())));
            }
        }
    }

    return false;
}

安装在qApp上。

MainWindow.cpp:

eFilter = new MultiEventFilter();
    connect(eFilter, SIGNAL(passCellSize(QSize)),
            sensor_display_delegate, SLOT(setEditorSize(QSize)));

SensorDisplayDelegate.cpp slot:

void SensorDisplayDelegate::setEditorSize(const QSize &size)
{
    editorSize = size;
}

其中QSize editorSize是私人成员。 如何正确设置编辑器的大小?我需要一些可以应用于QLineEdit编辑器的通用。 此外,是否有必要在编辑器关闭时显式发出commitData()?我没有在涉及QComboBox的任何示例代码中看到这一点。

1 个答案:

答案 0 :(得分:0)

我怀疑您的eventFilter在设置选择索引之前拦截了点击事件。那么,你有效地总是打一个空的idxs IndexList?

尝试用以下内容替换该循环:

bool MultiEventFilter::eventFilter(QObject *obj, QEvent *event)
{
    if(event->type() == QEvent::MouseButtonPress)
    {
        if(obj->objectName() == "sensorlocationTableView")
        {
            emit locationTableViewClicked();
        }
    }

    return false;
}

....

connect(eFilter, SIGNAL(locationTableViewClicked()),
        sensor_display_delegate, SLOT(setEditorSize()));
...

void SensorDisplayDelegate::setEditorSize()
{
    QModelIndexList idxs = sensorView->selectionModel()->selectedIndexes();
    if(!idxs.empty())
    {
        QModelIndex idx = idxs.at(0);
        editorSize = QSize(sensorView->columnWidth(idx.column()),
                           sensorView->rowHeight(idx.row()));
    }
}