Results 1 to 11 of 11

Thread: How to get rid of focus of qtreewidgetitem after editing with a delegate

  1. #1
    Join Date
    Mar 2011
    Posts
    25
    Thanks
    7
    Qt products
    Qt4

    Default How to get rid of focus of qtreewidgetitem after editing with a delegate

    I have a custom delegate and connected the closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint) to a slot. In this slot I call the signal commitData(widget) and would expect that after closing the editor it would also loose focus and the editor widget would get distroyed.

    For some reason I first have to click outside somewhere in order for the destructor to get called.

    How can I force the destruction of the editor widget and loose focus?

    Thanks

  2. #2
    Join Date
    Mar 2011
    Posts
    25
    Thanks
    7
    Qt products
    Qt4

    Default Re: How to get rid of focus of qtreewidgetitem after editing with a delegate

    Please let me know if I'm not clear enough:

    I expect the widget that was previously created in createEditor() to be destroyed when the following method gets called. I listen to the signal
    closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint) that is connected to SlotCloseEditor.

    Qt Code:
    1. void Class::SlotCloseEditor(QWidget* widget)
    2. {
    3. MyWidget *w= dynamic_cast<MyWidget*>(widget);
    4. if(w)
    5. {
    6. .....
    7. emit commitData(widget);
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

    Why is the destructor of this widget only called when I click outside and not immediately when I call: emit commit Data(widget)

    Thanks

  3. #3
    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 get rid of focus of qtreewidgetitem after editing with a delegate

    The closeEditor() signal is only emitted when the user does something to terminate editing of the cell. For example if the user presses Escape to cancel editing, presses enter/shifts the focus to accept the edited value. Until the signal is emitted your slot code never executes.

    What exactly are you trying to achieve?

  4. #4
    Join Date
    Mar 2011
    Posts
    25
    Thanks
    7
    Qt products
    Qt4

    Default Re: How to get rid of focus of qtreewidgetitem after editing with a delegate

    I DO get to the slot code when I hit enter after I'm done editing. But for some reason the destructor of the editor widget doesn't get called. I want the editor be closed/destroyed when I exit the function.

  5. #5
    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 get rid of focus of qtreewidgetitem after editing with a delegate

    You don't need to do anything special to achieve that:
    Qt Code:
    1. #include <QtGui>
    2. #include <QDebug>
    3.  
    4. class MyLineEdit: public QLineEdit
    5. {
    6. public:
    7. explicit MyLineEdit(QWidget *p = 0): QLineEdit(p) { qDebug() << "Constructed" << this; }
    8. ~MyLineEdit() { qDebug() << "Destroyed" << this; }
    9. };
    10.  
    11. class MyDelegate: public QStyledItemDelegate
    12. {
    13. Q_OBJECT
    14. public:
    15. explicit MyDelegate(QObject *p = 0): QStyledItemDelegate(p) { }
    16.  
    17. QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const {
    18. return new MyLineEdit(parent);
    19. }
    20. };
    21.  
    22. int main(int argc, char *argv[])
    23. {
    24. QApplication app(argc, argv);
    25.  
    26. QTableWidget t(5, 5);
    27. t.setItemDelegate(new MyDelegate(&t));
    28. t.show();
    29.  
    30. return app.exec();
    31. }
    32. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

    Without more of your code we cannot see what you are doing that would change the situation.

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

    iwatsu (25th July 2012)

  7. #6
    Join Date
    Mar 2011
    Posts
    25
    Thanks
    7
    Qt products
    Qt4

    Default Re: How to get rid of focus of qtreewidgetitem after editing with a delegate

    Thanks for the sample code. I expanded the code to illustrate my problem:

    DelegateProblem.h
    Qt Code:
    1. #include <QtGui>
    2.  
    3. class MyTextEdit: public QTextEdit
    4. {
    5. Q_OBJECT
    6. public:
    7. explicit MyTextEdit(QWidget *p = 0): QTextEdit(p) {}
    8. ~MyTextEdit() {}
    9. void keyPressEvent(QKeyEvent *event);
    10. Q_SIGNALS:
    11. void EnterPressed();
    12. };
    13.  
    14. class ButtonEditor : public QAbstractButton
    15. {
    16. Q_OBJECT
    17. public:
    18. ButtonEditor(QWidget *parent = NULL);
    19. ~ButtonEditor() { qDebug() << "Destroyed" << this; }
    20. virtual void mouseDoubleClickEvent( QMouseEvent * event );
    21. virtual void paintEvent(QPaintEvent *e);
    22.  
    23. MyTextEdit *mTextEdit;
    24. Q_SIGNALS:
    25. void SignalEditingFinished(QWidget*);
    26.  
    27. public slots:
    28. void EditingFinished();
    29. };
    30.  
    31. class MyDelegate: public QStyledItemDelegate
    32. {
    33. Q_OBJECT
    34. public:
    35. explicit MyDelegate(QObject *p = 0);
    36.  
    37. QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
    38. {
    39. ButtonEditor *btn = new ButtonEditor(parent);
    40. Q_ASSERT(connect(btn, SIGNAL(SignalEditingFinished(QWidget*)), this, SLOT(SlotCloseEditor(QWidget*))));
    41. return btn;
    42. }
    43.  
    44. public slots:
    45. void SlotCloseEditor(QWidget*);
    46. };
    47.  
    48. class DelegateProblem : public QWidget
    49. {
    50. Q_OBJECT
    51. public:
    52. DelegateProblem(QWidget *parent = 0, Qt::WFlags flags = 0);
    53. ~DelegateProblem() {}
    54. };
    To copy to clipboard, switch view to plain text mode 

    DelegateProblem.cpp

    Qt Code:
    1. #include "DelegateProblem.h"
    2.  
    3. DelegateProblem::DelegateProblem(QWidget *parent, Qt::WFlags flags)
    4. : QWidget(parent, flags)
    5. {
    6. QVBoxLayout *layout = new QVBoxLayout;
    7. QTableWidget *t = new QTableWidget(5, 5);
    8. t->setItemDelegate(new MyDelegate(t));
    9. t->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked);
    10. layout->addWidget(t);
    11. setLayout(layout);
    12. }
    13.  
    14. //---------- MyDelegate---------------------------------------------
    15. //-------------------------------------------------------------------
    16. MyDelegate::MyDelegate( QObject *p /*= 0*/ )
    17. : QStyledItemDelegate(p)
    18. {
    19. Q_ASSERT(connect(this, SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)), this, SLOT(SlotCloseEditor(QWidget*))));
    20. }
    21.  
    22. void MyDelegate::SlotCloseEditor( QWidget* )
    23. {
    24. qDebug() << "I don't hit ~ButtonEditor() afterwards";
    25. }
    26.  
    27. //---------- ButtonEditor -------------------------------------------
    28. //-------------------------------------------------------------------
    29. void ButtonEditor::mouseDoubleClickEvent( QMouseEvent * event )
    30. {
    31. mTextEdit->setText(text());
    32. mTextEdit->setVisible(true);
    33. Q_ASSERT(connect(mTextEdit, SIGNAL(EnterPressed()), this, SLOT(EditingFinished())));
    34. }
    35.  
    36. void ButtonEditor::paintEvent( QPaintEvent *e )
    37. {
    38. QStylePainter painter( this );
    39. opt.initFrom(this);
    40. opt.palette = palette();
    41. opt.state |= QStyle::State_AutoRaise;
    42. painter.drawControl(QStyle::CE_PushButtonBevel, opt);
    43. }
    44.  
    45. ButtonEditor::ButtonEditor( QWidget *parent /*= NULL*/ )
    46. : QAbstractButton(parent)
    47. {
    48. mTextEdit = new MyTextEdit(this);
    49. mTextEdit->setVisible(false);
    50. mTextEdit->setAcceptRichText(false);
    51. mTextEdit->setFrameShape(QFrame::Box);
    52. mTextEdit->setFrameShadow(QFrame::Plain);
    53. }
    54.  
    55. void ButtonEditor::EditingFinished()
    56. {
    57. mTextEdit->setVisible(false);
    58. emit SignalEditingFinished(this);
    59. }
    60.  
    61. //---------- MyTextEdit -------------------------------------------
    62. //-------------------------------------------------------------------
    63. void MyTextEdit::keyPressEvent( QKeyEvent *event )
    64. {
    65. if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
    66. {
    67. emit EnterPressed();
    68. }
    69. QTextEdit::keyPressEvent(event);
    70. }
    To copy to clipboard, switch view to plain text mode 

    Double click on the button and the custom text edit appears. after entering something, press the Enter key: MyDelegate::SlotCloseEditor() gets called but not the ButtonEditor() destructor (unless I click into another cell)
    What prevents it from being called?

    Thanks!

  8. #7
    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 get rid of focus of qtreewidgetitem after editing with a delegate

    At the moment when the user triggers editing (by clicking, double-clicking, or moving the current cell) a blank button is created in the table cell. When the user double clicks the blank button a text edit is created (this has nothing to do with the delegate). A text edit is a multi-line editor so hitting Enter does not close the editor and you have implemented a kludge to intercept and attempt to do something with the Enter key press. On my machine the SlotCloseEditor() is never called.

    What effect are you trying to achieve?

  9. #8
    Join Date
    Mar 2011
    Posts
    25
    Thanks
    7
    Qt products
    Qt4

    Default Re: How to get rid of focus of qtreewidgetitem after editing with a delegate

    add this to mouseDoubleClickEvent() to show the cursor directly after double clicking on the button.

    Qt Code:
    1. mTextEdit->setFocus(Qt::OtherFocusReason);
    To copy to clipboard, switch view to plain text mode 

    Are you typing something and press Enter? You should hit the MyDelegate::SlotCloseEditor() function.

  10. #9
    Join Date
    Mar 2011
    Posts
    25
    Thanks
    7
    Qt products
    Qt4

    Default Re: How to get rid of focus of qtreewidgetitem after editing with a delegate

    I'm still having this problem. I'm expecting that the editor gets closed (~ButtonEditor() should get called) when hitting Enter in the text edit field. That's why I implemented this kludge.

    1. Double click in first cell
    2. add some text
    3. hit Enter key
    MyDelegate::SlotCloseEditor() gets called: then I should hit the ButtonEditor destructor...

    What prevents it from being called?
    Thanks!

  11. #10
    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 get rid of focus of qtreewidgetitem after editing with a delegate

    In your example the text editor you create separately closes, emits a signal, triggers a slot:
    Qt Code:
    1. void MyDelegate::SlotCloseEditor( QWidget* )
    2. {
    3. qDebug() << "I don't hit ~ButtonEditor() afterwards";
    4. }
    To copy to clipboard, switch view to plain text mode 
    that does nothing. The button, i.e. the "editor", remains active and will not be destroyed until the focus is lost.

    I still have no idea why you create a button as the "editor" or why you use a multiline editor QTextEdit only to remove the possibility of inserting a new line.

  12. #11
    Join Date
    Mar 2011
    Posts
    25
    Thanks
    7
    Qt products
    Qt4

    Default Re: How to get rid of focus of qtreewidgetitem after editing with a delegate

    Quote Originally Posted by ChrisW67 View Post
    In your example the text editor you create separately closes, emits a signal, triggers a slot:
    Qt Code:
    1. void MyDelegate::SlotCloseEditor( QWidget* )
    2. {
    3. qDebug() << "I don't hit ~ButtonEditor() afterwards";
    4. }
    To copy to clipboard, switch view to plain text mode 
    that does nothing. The button, i.e. the "editor", remains active and will not be destroyed until the focus is lost.
    Are you saying it's not possible to force it to loose the focus?

    I still have no idea why you create a button as the "editor" or why you use a multiline editor QTextEdit only to remove the possibility of inserting a new line.
    I'm reusing a class that allows multiline but for my case I don't need that feature. The button editor allows to popup a menu in order to change units but it's also possible to rename the button text.

Similar Threads

  1. Retrieve QTreeWidgetItem in delegate
    By torres in forum Newbie
    Replies: 2
    Last Post: 3rd June 2016, 19:34
  2. Replies: 11
    Last Post: 3rd March 2012, 22:21
  3. Replies: 5
    Last Post: 23rd September 2010, 13:58
  4. Focus on QTreeWidgetItem
    By johnmauer in forum Qt Programming
    Replies: 0
    Last Post: 30th July 2010, 16:34
  5. Replies: 2
    Last Post: 24th May 2009, 10:27

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.