Results 1 to 8 of 8

Thread: How to create a QStyledItemDelegate made of two QDoubleSpinBox widgets

  1. #1
    Join Date
    Mar 2013
    Posts
    4
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default How to create a QStyledItemDelegate made of two QDoubleSpinBox widgets

    Hello,

    I am trying to use an editor made of two QDoubleSpinBox when subclassing QStyledItemDelegate. I have no problem connecting the delegate and editor to the model but I failed to have my editor to show up in my view. I had no such problem with a simpler editor (e.g. a single QSpinBox).

    Constructor for the Editor
    Qt Code:
    1. Data_editor::Data_editor( QWidget *parent)
    2. :QFrame(parent)
    3. {
    4. lower_bound_spin_ = new QDoubleSpinBox(this);
    5. upper_bound_spin_ = new QDoubleSpinBox(this);
    6.  
    7. QHBoxLayout* layout = new QHBoxLayout(this);
    8. layout->addWidget(new QLabel("Lower", this));
    9. layout->addWidget(lower_bound_spin_);
    10. layout->addStretch();
    11. layout->addWidget(new QLabel("Upper", this));
    12. layout->addWidget(upper_bound_spin_);
    13.  
    14. this->setLayout(layout);
    15.  
    16. this->setFocusPolicy( Qt::StrongFocus );
    17. }
    To copy to clipboard, switch view to plain text mode 

    Implementation of the delegate
    Qt Code:
    1. QWidget *Data_delegate::createEditor(QWidget *parent,
    2. const QStyleOptionViewItem &option,
    3. const QModelIndex &index) const
    4.  
    5. {
    6. Data_editor* editor = new Data_editor( parent);
    7.  
    8. return editor;
    9.  
    10. }
    11.  
    12. void Data_delegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
    13. const QModelIndex &index) const
    14. {
    15. QStyledItemDelegate::paint(painter, option, index);
    16. }
    17.  
    18.  
    19. QSize Data_delegate::sizeHint(const QStyleOptionViewItem &option,
    20. const QModelIndex &index) const
    21. {
    22. return QStyledItemDelegate::sizeHint(option, index);
    23.  
    24. }
    25.  
    26. void Data_delegate::updateEditorGeometry(QWidget *editor,
    27. const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
    28. {
    29. editor->setGeometry(option.rect);
    30. }
    To copy to clipboard, switch view to plain text mode 

    I played a bit with eventFilter and try to record the log of the events passing through
    Qt Code:
    1. bool Data_delegate::eventFilter(QObject *object, QEvent *event)
    2. {
    3. Data_editor *editor = qobject_cast<Data_editor*>(object);
    4. if (!editor)
    5. return false;
    6.  
    7. QWidget *w_focused = QApplication::focusWidget();
    8. QEvent::Type t = event->type();
    9.  
    10. std::string class_name = (w_focused!=0)?w_focused->metaObject()->className():std::string("000");
    11. ostream_<<class_name <<" "<< QString("%1").arg(t).toStdString()+"\n";
    12.  
    13. if (event->type() == QEvent::KeyPress) {
    14. switch (static_cast<QKeyEvent *>(event)->key()) {
    15. case Qt::Key_Tab:
    16. emit commitData(editor);
    17. emit closeEditor(editor, QAbstractItemDelegate::EditNextItem);
    18. return true;
    19. case Qt::Key_Backtab:
    20. emit commitData(editor);
    21. emit closeEditor(editor, QAbstractItemDelegate::EditPreviousItem);
    22. return true;
    23. case Qt::Key_Enter:
    24. case Qt::Key_Return:
    25.  
    26. QMetaObject::invokeMethod(this, "_q_commitDataAndCloseEditor",
    27. Qt::QueuedConnection, Q_ARG(QWidget*, editor));
    28. return false;
    29. case Qt::Key_Escape:
    30. // don't commit data
    31. emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
    32. break;
    33. default:
    34. return false;
    35. }
    36. if (editor->parentWidget())
    37. editor->parentWidget()->setFocus();
    38. return true;
    39. } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
    40. //the Hide event will take care of he editors that are in fact complete dialogs
    41. //if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
    42. if (!editor->isActiveWindow() || (w_focused != editor)) {
    43. QWidget *w = w_focused;
    44. //QWidget *w = QApplication::focusWidget();
    45. while (w) { // don't worry about focus changes internally in the editor
    46. if (w == editor)
    47. return false;
    48. w = w->parentWidget();
    49. }
    50. emit commitData(editor);
    51. emit closeEditor(editor, NoHint);
    52. }
    53. } else if (event->type() == QEvent::ShortcutOverride) {
    54. if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
    55. event->accept();
    56. return true;
    57. }
    58. }
    59. return false;
    60. }
    To copy to clipboard, switch view to plain text mode 

    Which output (first column widget className, second Qcolumn Event type):
    Data_tree_view 75
    Data_tree_view 70
    Data_tree_view 70
    Data_tree_view 70
    Data_tree_view 70
    Data_tree_view 69
    Data_tree_view 69
    Data_tree_view 69
    Data_tree_view 69
    Data_tree_view 13
    Data_tree_view 14
    Data_tree_view 17
    Data_tree_view 26
    Data_editor 8
    Data_editor 67
    Data_editor 74
    Data_editor 12
    Data_editor 10
    Data_editor 11
    Data_editor 12
    Data_tree_view 9

    The editor is painted (event 12) but is never shown. The last event (which probably occurred when I moved the cursor) is the FocusOut event which commit the data and close the editor.

    So what is missing in my delegate/editor such the editor will be shown in my view? Online comments seem to point out to a focus issue but I cannot get it right.

    Thanks

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to create a QStyledItemDelegate made of two QDoubleSpinBox widgets

    The default behaviour will be looking to commit and close the editor when the widget you provided as the editor loses focus. I expect that widget will lose focus immediately when the focus shifts into one of its child spin boxes. You should look specifically at that event and whether you need to block it from propagating.

    Cannot say I have done a lot of event filtering myself so I will be interested in the other responses.

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

    abgeos (19th March 2013)

  4. #3
    Join Date
    Mar 2013
    Posts
    4
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to create a QStyledItemDelegate made of two QDoubleSpinBox widgets

    Thanks,

    It is the first time that I work explicitly with the child-parent relationship of widgets as well as with event filtering. So this is not obvious to me.

    I was under the impression that the eventFilter member function of the delegate would have taken care of the out of focus event within a child of the delegate widget (line 45 of the last code snippet in my original post):
    Qt Code:
    1. QWidget *w = QApplication::focusWidget();
    2. while (w) { // don't worry about focus changes internally in the editor
    3. if (w == editor)
    4. return false;
    5. w = w->parentWidget();
    6. }
    To copy to clipboard, switch view to plain text mode 
    It seems that this is not the case. I'll run more tests.

    Thanks
    Last edited by abgeos; 19th March 2013 at 19:35. Reason: spelling corrections

  5. #4
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: How to create a QStyledItemDelegate made of two QDoubleSpinBox widgets

    Quote Originally Posted by abgeos View Post
    . . . I failed to have my editor to show up in my view.
    Try setting the layout margins in Data_editor to 0:
    Qt Code:
    1. layout->setMargin(0);
    To copy to clipboard, switch view to plain text mode 
    Last edited by norobro; 19th March 2013 at 19:46. Reason: typo

  6. #5
    Join Date
    Mar 2013
    Posts
    4
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to create a QStyledItemDelegate made of two QDoubleSpinBox widgets

    norobro: Right on!

    Thank you so much I would have never tried that. If you have a minute would you care to explain why it works?

    The editor show up nicely with the two QDoubleSpinBox and I can interact with them at will. However the display of the model remains visible while the editor is active. Any idea how to remove, blank or hide the model display for that item while the editor is active.

    Thanks.
    Last edited by abgeos; 19th March 2013 at 20:56. Reason: spelling corrections

  7. #6
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: How to create a QStyledItemDelegate made of two QDoubleSpinBox widgets

    You're welcome. According to the docs QLayout::setMargin() is obsolete so you should use QLayout::setContentsMargins() instead.

    I encountered this once upon a time and as I recall the row height for a QTreeView with the default font (9 pt) on my system is 13 and the default margin is 11. The upper and lower margins take up more space than is available on the row so there is no space to paint the layout contents. Try incrementing the margins up from zero and I think you will see your spinboxes disappearing.


    Quote Originally Posted by abgeos View Post
    Any idea how to remove, blank or hide the model display for that item while the editor is active.
    Put the following statement in the Data_editor ctor:
    Qt Code:
    1. setAutoFillBackground(true);
    To copy to clipboard, switch view to plain text mode 

  8. The following user says thank you to norobro for this useful post:

    abgeos (20th March 2013)

  9. #7
    Join Date
    Mar 2013
    Posts
    4
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to create a QStyledItemDelegate made of two QDoubleSpinBox widgets

    Thanks for the explanation. Everything is now working properly.

  10. #8
    Join Date
    Jan 2014
    Posts
    1
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: How to create a QStyledItemDelegate made of two QDoubleSpinBox widgets

    Hey abgeos,

    can you post your source code? I am wanting to do a slider and spinbox instead of 2 spinbox and having some issues.

    Appreciate your help!
    Thanks,
    Sunny

Similar Threads

  1. connect mainwindow with self-made widgets
    By pinkiP in forum Qt Programming
    Replies: 11
    Last Post: 10th July 2012, 10:16
  2. Create an array of Widgets
    By gt.beta2 in forum Qt Tools
    Replies: 4
    Last Post: 25th February 2009, 19:44
  3. Replies: 8
    Last Post: 16th January 2009, 16:10
  4. How to get correct header with custom made widgets?
    By Arthur in forum Qt Programming
    Replies: 3
    Last Post: 26th April 2007, 17:07
  5. How to create pop up widgets in designer.
    By gsQT4 in forum Qt Tools
    Replies: 1
    Last Post: 25th May 2006, 16:40

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.