2015-06-10 44 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表明在其他职位,但没有在这种情况下