Results 1 to 1 of 1

Thread: How to implement a well behaved editor for QAbstractItem::createEditor()

  1. #1
    Join Date
    Oct 2006
    Posts
    279
    Thanks
    6
    Thanked 40 Times in 39 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to implement a well behaved editor for QAbstractItem::createEditor()

    This is a repost of this.

    I have created a custom item delegate which let's users edit a list of file paths:
    item_delegate.png
    I have achieved this through a custom class DirEdit. Now the selected path is commited and the editor is closed when the user presses enter, but I would like to add two cases where the editor should be closed without the user having to press enter:
    1. When the user selects a file by activating a combo box entry(by clicking or pressing return)
    2. When the user selects a file by clicking the "ellipsis" tool button.


    I have been experimenting with clearFocus() and other methods, but nothing seems to work. Below is a complete example:
    Qt Code:
    1. #include <QtWidgets>
    2.  
    3. class DirEdit : public QWidget
    4. {
    5. QLineEdit* lineEdit=nullptr;
    6. public:
    7. DirEdit(QWidget* parent=nullptr)
    8. : QWidget(parent)
    9. {
    10. new QHBoxLayout(this);
    11. layout()->setMargin(0);
    12. layout()->addWidget(lineEdit=new QLineEdit(this));
    13.  
    14. QCompleter *completer = new QCompleter(this);
    15.  
    16. auto model = new QDirModel(completer);
    17. model->setFilter(QDir::AllDirs|QDir::NoDotAndDotDot);
    18. completer->setModel(model);
    19.  
    20. lineEdit->setCompleter(completer);
    21. connect(completer, static_cast<void (QCompleter::*)(const QString&)>(&QCompleter::activated), [this](const QString& text)
    22. {
    23. // >>>>>>>>>>>>>>>>>>>>>>> TODO: Make the editor close here <<<<<<<<<<<<<<<<<<<<<<<<<<<<
    24. });
    25.  
    26. QToolButton* dotDotDot;
    27. layout()->addWidget(dotDotDot=new QToolButton(this));
    28. dotDotDot->setText("...");
    29. connect(dotDotDot, &QToolButton::clicked, this, [this]()
    30. {
    31. QString dir = QFileDialog::getExistingDirectory(window(), "Select Directory", lineEdit->text());
    32. if(dir!="")
    33. {
    34. lineEdit->setText(dir);
    35. // >>>>>>>>>>>>>>>>>>>>>>> TODO: Make the editor close here <<<<<<<<<<<<<<<<<<<<<<<<<<<<
    36. }
    37. });
    38. setFocusProxy(lineEdit);
    39. }
    40. void setPath(const QString& path)
    41. {
    42. lineEdit->setText(path);
    43. }
    44. QString path()const
    45. {
    46. return lineEdit->text();
    47. }
    48. };
    49.  
    50. class MyDelegate : public QItemDelegate
    51. {
    52. QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
    53. {
    54. return new DirEdit(parent);
    55. }
    56.  
    57. void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem& option, const QModelIndex &)const
    58. {
    59. editor->setGeometry(option.rect);
    60. }
    61.  
    62. void setEditorData(QWidget *editor, const QModelIndex &index) const
    63. {
    64. QVariant value = index.model()->data(index, Qt::DisplayRole);
    65.  
    66. if (DirEdit *dirEdit = dynamic_cast<DirEdit *>(editor))
    67. dirEdit->setPath(value.toString());
    68. }
    69.  
    70. void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    71. {
    72. if (DirEdit *dirEdit = dynamic_cast<DirEdit *>(editor))
    73. model->setData(index, dirEdit->path());
    74. }
    75. };
    76.  
    77. int main(int argc, char* argv[])
    78. {
    79. QApplication app(argc, argv);
    80. QListWidget listWidget;
    81.  
    82. listWidget.setItemDelegate(new MyDelegate);
    83.  
    84. listWidget.addItem(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
    85. listWidget.addItem(QStandardPaths::writableLocation(QStandardPaths::MusicLocation));
    86. listWidget.addItem(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
    87. listWidget.addItem(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
    88.  
    89. for (int i = 0; i<listWidget.count(); i++)
    90. listWidget.item(i)->setFlags(listWidget.item(0)->flags()|Qt::ItemIsEditable);
    91.  
    92. listWidget.show();
    93. return app.exec();
    94. }
    To copy to clipboard, switch view to plain text mode 

    The only restraint is that DirEdit should be a standard element and not need to know about the Item View/Delegate framework.

    thanks


    Added after 1 20 minutes:


    Ok, I found one solution for this myself. It consists of replacing the TODOs with
    Qt Code:
    1. QApplication::postEvent(this, new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier));
    To copy to clipboard, switch view to plain text mode 
    See Stack Overflow for an explanation.
    Last edited by spud; 10th June 2015 at 15:29.

Similar Threads

  1. return the editor pointer from createEditor
    By Naahmi in forum Qt Programming
    Replies: 3
    Last Post: 25th September 2011, 08:32
  2. QTreeView and QAbstractItem Model.
    By Terabyte in forum Qt Programming
    Replies: 1
    Last Post: 13th January 2009, 13:18
  3. designer behaved abnormally...
    By sh123 in forum Qt Tools
    Replies: 3
    Last Post: 10th January 2009, 12:01
  4. designer behaved abnormally...
    By sh123 in forum Qt Tools
    Replies: 1
    Last Post: 16th December 2008, 18:00
  5. Replies: 6
    Last Post: 9th January 2008, 15:56

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.