2015-06-10 79 views
2

我創建了一個自定義項目的委託,它可以讓用戶編輯的文件路徑列表的定製QItemDelegate :: createEditor()創建編輯:如何附近

screenshot

我已經通過這個實現自定義類DirEdit。現在,選擇的路徑將提交併且當用戶按下進入編輯器是關閉的,但我想補充的兩種情況下,編輯應用戶不用按回車被關閉:

  1. 當用戶選擇文件通過激活組合框條目(通過單擊或按回車鍵)
  2. 當用戶通過單擊「省略號」工具按鈕選擇文件時。

我一直用clearFocus()和其他方法實現,但似乎沒有任何工作。下面是一個完整的例子:

#include <QtWidgets> 

class DirEdit : public QWidget 
{ 
    QLineEdit* lineEdit=nullptr; 
public: 
    DirEdit(QWidget* parent=nullptr) 
     : QWidget(parent) 
    { 
     new QHBoxLayout(this); 
     layout()->setMargin(0); 
     layout()->addWidget(lineEdit=new QLineEdit(this)); 

     QCompleter *completer = new QCompleter(this); 

     auto model = new QDirModel(completer); 
     model->setFilter(QDir::AllDirs|QDir::NoDotAndDotDot); 
     completer->setModel(model); 

     lineEdit->setCompleter(completer); 
     connect(completer, static_cast<void (QCompleter::*)(const QString&)>(&QCompleter::activated), [this](const QString& text) 
      { 
// >>>>>>>>>>>>>>>>>>>>>>> TODO: Make the editor close here <<<<<<<<<<<<<<<<<<<<<<<<<<<< 
      }); 

     QToolButton* dotDotDot; 
     layout()->addWidget(dotDotDot=new QToolButton(this)); 
     dotDotDot->setText("..."); 
     connect(dotDotDot, &QToolButton::clicked, this, [this]() 
      { 
       QString dir = QFileDialog::getExistingDirectory(window(), "Select Directory", lineEdit->text()); 
       if(dir!="") 
       { 
        lineEdit->setText(dir); 
// >>>>>>>>>>>>>>>>>>>>>>> TODO: Make the editor close here <<<<<<<<<<<<<<<<<<<<<<<<<<<< 
       } 
      }); 
     setFocusProxy(lineEdit); 
    } 
    void setPath(const QString& path) 
    { 
     lineEdit->setText(path); 
    } 
    QString path()const 
    { 
     return lineEdit->text(); 
    } 
}; 

class MyDelegate : public QItemDelegate 
{ 
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const 
    { 
     return new DirEdit(parent); 
    } 

    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem& option, const QModelIndex &)const 
    { 
     editor->setGeometry(option.rect); 
    } 

    void setEditorData(QWidget *editor, const QModelIndex &index) const 
    { 
     QVariant value = index.model()->data(index, Qt::DisplayRole); 

     if (DirEdit *dirEdit = dynamic_cast<DirEdit *>(editor)) 
      dirEdit->setPath(value.toString()); 
    } 

    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const 
    { 
     if (DirEdit *dirEdit = dynamic_cast<DirEdit *>(editor)) 
      model->setData(index, dirEdit->path()); 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    QApplication app(argc, argv); 
    QListWidget listWidget; 

    listWidget.setItemDelegate(new MyDelegate); 

    listWidget.addItem(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); 
    listWidget.addItem(QStandardPaths::writableLocation(QStandardPaths::MusicLocation)); 
    listWidget.addItem(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); 
    listWidget.addItem(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); 

    for (int i = 0; i<listWidget.count(); i++) 
     listWidget.item(i)->setFlags(listWidget.item(0)->flags()|Qt::ItemIsEditable); 

    listWidget.show(); 
    return app.exec(); 
} 
+0

也許'QAbstractItemView中:: closePersistentEditor(工作)'可以幫幫我? – vahancho

+0

@vahancho我不這麼認爲,因爲它不是一個持久性編輯器(由QAbstractItemView :: openPersistentEditor()創建) – bgp2000

+0

嗯,我想你需要關閉'QCompleter :: popup()'?怎麼樣調用'completer-> popup() - > close()'? – vahancho

回答

0

TL; DR

與更換TODOS

QApplication::postEvent(this, new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier)); 

動機:

我找到了鑰匙的答案在這裏:Why pressing of "Tab" key emits only QEvent::ShortcutOverride event?

有一個事件過濾器,用於尋找某些事件,所以我只需要三gger其中之一:

// Edited for brevity. 
bool QItemDelegate::eventFilter(QObject *object, QEvent *event) 
{ 
    QWidget *editor = qobject_cast<QWidget*>(object); 

    if (event->type() == QEvent::KeyPress) { 
     switch (static_cast<QKeyEvent *>(event)->key()) { 
     case Qt::Key_Enter: 
     case Qt::Key_Return: 
      QMetaObject::invokeMethod(this, "_q_commitDataAndCloseEditor", 
             Qt::QueuedConnection, Q_ARG(QWidget*, editor)); 
      return false; 
    } 
} 

我第一次嘗試張貼focusOut事件像@fasked表明在其他職位,但沒有在這種情況下