2017-01-02 3 views
0

У меня есть пользовательский делегат, подкласса из QItemDelegate, который предоставляет QComboBox в первом столбце и QLineEdit во всех остальных столбцах.Размер редактора в QItemDelegate

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); 
} 

РедактированиеTrigger настроен на выборClicked. Я хочу, чтобы поле со списком охватывало всю ячейку в QTableView. Однако теперь он просто выглядит как промах в левом углу. Я попытался установить минимальный размер, передав размер ячейки через фильтр событий, который прослушивает mousePressed в QTableView. Однако соответствующий слот в делегате никогда не вызывается. Вот код:

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 слот:

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

где QSize editorSize является частным членом. Как правильно задать размер редактора? Мне нужно что-то общее, которое можно применить и к редакторам QLineEdit. Кроме того, нужно ли явно выделять commitData(), когда редактор закрыт? Я не видел этого в примерах с QComboBox.

ответ

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())); 
    } 
}