Results 1 to 3 of 3

Thread: Changing index in combobox delegate only calls setModelData after losing focus

  1. #1
    Join Date
    Feb 2014
    Posts
    4
    Thanks
    3
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Changing index in combobox delegate only calls setModelData after losing focus

    Hi all, I hope you can help me with this problem.

    I have a QTableView in which the first row contains comboboxes (>100). The comboboxes influence the rest of the contents of the QTableView.
    I've noticed that the setModelData() method does get called (and the table gets properly updated), but not immediately after selecting a new item from the combobox, but you need to click somewhere else (lose focus) before it gets called. This is quite inconvenient, and I'd like to know how to skip that click.

    My comboboxes are made by calling setItemDelegateForRow for the first row of the table. The implementation of createEditor, setEditorData and setModelData is standard. My comboboxdelegate is derived from QStyledItemDelegate. Here is my code from ComboboxDelegate.cpp:

    Qt Code:
    1. MainComboBoxDelegate::MainComboBoxDelegate(QObject *parent, MainTableListModel *model) : QStyledItemDelegate(parent)
    2. {
    3. m_model = model;
    4. }
    5.  
    6. QWidget *MainComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option , const QModelIndex & index) const
    7. {
    8. if(index.row() == 0 && index.column() != 0)
    9. {
    10. QComboBox* editor = new QComboBox(parent);
    11.  
    12. editor->setModel(m_model);
    13. editor->setEditable(false);
    14. return editor;
    15. }
    16. else
    17. return QStyledItemDelegate::createEditor(parent, option, index);
    18. }
    19.  
    20. void MainComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    21. {
    22. if(index.row() == 0)
    23. {
    24. QString temp = index.model()->data(index, Qt::EditRole).toString();
    25. QComboBox *comboBox = static_cast<QComboBox*>(editor);
    26. comboBox->setCurrentIndex(comboBox->findText(temp));
    27. }
    28. }
    29.  
    30. void MainComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    31. {
    32. if(index.row() == 0)
    33. {
    34. QComboBox *comboBox = static_cast<QComboBox*>(editor);
    35. QString value = comboBox->currentText();
    36. model->setData(index, value, Qt::EditRole);
    37. }
    38. }
    39.  
    40. void MainComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
    41. {
    42. editor->setGeometry(option.rect);
    43. }
    To copy to clipboard, switch view to plain text mode 

    And this is how I create them in my view class:

    Qt Code:
    1. ui->Main_Table_View->setItemDelegateForRow(0, new MainComboBoxDelegate(ui->Main_Table_View, Maintablelistmodel));
    2. for(int i = 1; i < Maintablemodel->columnCount(); ++i)
    3. ui->Main_Table_View->openPersistentEditor(Maintablemodel->index(0, i));
    To copy to clipboard, switch view to plain text mode 

    The Maintablelistmodel is a QSortFilterProxyModel which contains only one column.
    As the comboboxes get created this way, it's hard to pick up signals from them manually, but it may be an option.
    Is there something I'm doing wrong, or is it some kind of limitation? Am I missing something?

    Any help is highly appreciated.

  2. #2
    Join Date
    Nov 2011
    Posts
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Changing index in combobox delegate only calls setModelData after losing focus

    Same problem here:


    Qt Code:
    1. void PropertyItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    2. {
    3. QVariant value = index.data(Qt::EditRole);
    4. QVariant::Type type = index.data(SensorPropertyModel::PropertyTypeRole).type();
    5.  
    6. switch(type) {
    7.  
    8. case QVariant::StringList:
    9. {
    10. QComboBox* comboBox = static_cast<QComboBox*>(editor);
    11. value = index.data(SensorPropertyModel::ListIndexRole);
    12. comboBox->setCurrentIndex(value.toInt());
    13. break;
    14. }
    15.  
    16. default:
    17. break;
    18. }
    19. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void PropertyItemDelegate::setModelData(QWidget* editor,
    2. const QModelIndex& index) const
    3. {
    4. if(!index.isValid()) {
    5. return;
    6. }
    7. QVariant value = index.data(Qt::EditRole);
    8. QVariant::Type type = index.data(SensorPropertyModel::PropertyTypeRole).type();
    9.  
    10. switch(type) {
    11.  
    12. case QVariant::StringList:
    13. {
    14. QComboBox* comboBox = static_cast<QComboBox*>(editor);
    15. value = comboBox->currentText();
    16. int nValue = comboBox->currentIndex();
    17. model->setData(index, nValue, SensorPropertyModel::ListIndexRole);
    18. break;
    19. }
    20.  
    21. default:
    22. break;
    23. }
    24.  
    25. model->setData(index, value, Qt::EditRole);
    26. }
    To copy to clipboard, switch view to plain text mode 

    Any help is appreciated!


    Added after 18 minutes:


    Found a workaround:

    Qt Code:
    1. case QVariant::StringList:
    2. {
    3. QComboBox* comboBox = static_cast<QComboBox*>(editor);
    4. value = index.data(SensorPropertyModel::ListIndexRole);
    5. connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
    6. comboBox->setCurrentIndex(value.toInt());
    7. break;
    8. }
    To copy to clipboard, switch view to plain text mode 

    Notice the connect-line.

    Qt Code:
    1. void PropertyItemDelegate::onCurrentIndexChanged(int nIndex)
    2. {
    3. QComboBox* cb = static_cast<QComboBox*>(sender());
    4. if(cb) {
    5. emit commitData(cb);
    6. }
    7. }
    To copy to clipboard, switch view to plain text mode 

    See here: http://qt-project.org/forums/viewthread/4531
    Last edited by Zampano; 30th May 2014 at 10:13.

  3. The following user says thank you to Zampano for this useful post:

    Meladi (4th June 2014)

  4. #3
    Join Date
    Feb 2014
    Posts
    4
    Thanks
    3
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: Changing index in combobox delegate only calls setModelData after losing focus

    For me this worked too, but I had to put the connect into another method than setModelData, because that method is hit only when you click somewhere outside the combobox - which is part of the problem. Putting it in createEditor or setEditorData works.

Similar Threads

  1. Replies: 2
    Last Post: 8th March 2014, 18:38
  2. Model/View/Delegate How gets setEditorData / setModelData
    By moviemax in forum Qt Programming
    Replies: 0
    Last Post: 11th July 2011, 11:29
  3. QTreeWidget Delegate setModelData limitations
    By kubas in forum Qt Programming
    Replies: 0
    Last Post: 8th September 2009, 08:40
  4. How to get index of a combobox delegate selection
    By vieraci in forum Qt Programming
    Replies: 12
    Last Post: 21st July 2009, 16:37
  5. QGLWidget window redrawing contents when losing focus
    By Barry79 in forum Qt Programming
    Replies: 1
    Last Post: 3rd April 2009, 13:37

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.