gpt4 book ai didi

c++ - 如何关闭由自定义 QItemDelegate::createEditor() 创建的编辑器

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:50:06 25 4
gpt4 key购买 nike

我创建了一个自定义项目委托(delegate),它允许用户编辑文件路径列表:

screenshot

我通过自定义类 DirEdit 实现了这一点。现在选定的路径已提交,当用户按下 enter 时编辑器关闭,但我想添加两种情况,用户无需按下 enter 即可关闭编辑器:

  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();
}

最佳答案

长话短说

将 TODO 替换为

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

动机:

我在这里找到了答案的关键:Why pressing of "Tab" key emits only QEvent::ShortcutOverride event?

有一个事件过滤器在寻找某些事件,所以我只需要触发其中之一:

// 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;
}
}

我尝试先像@fasked 在另一篇文章中建议的那样发布一个 FocusOut 事件,但在这种情况下不起作用

关于c++ - 如何关闭由自定义 QItemDelegate::createEditor() 创建的编辑器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30752007/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com