正如我的意见的问题,与子类QStyledItemDelegate
问题指出,试图把任何默认选择setEditorData
这样的:
void setEditorData(QWidget* editor, const QModelIndex &index)const{
QStyledItemDelegate::setEditorData(editor, index);
if(index.column() == 0){ //the column with file names in it
//try to cast the default editor to QLineEdit
QLineEdit* le= qobject_cast<QLineEdit*>(editor);
if(le){
//set default selection in the line edit
int lastDotIndex= le->text().lastIndexOf(".");
le->setSelection(0,lastDotIndex);
}
}
}
的是,(在Qt代码)视图调用我们setEditorData
后here,当编辑器小部件是QLineEdit
时,它试图呼叫selectAll()
here。这意味着我们在setEditorData
中提供的任何选择都会在之后更改。
我能想出的唯一解决方案就是以排队的方式提供我们的选择。因此,我们的选择是在执行回到事件循环时设置的。这里是工作示例:
#include <QApplication>
#include <QtWidgets>
class FileNameDelegate : public QStyledItemDelegate{
public:
explicit FileNameDelegate(QObject* parent= nullptr)
:QStyledItemDelegate(parent){}
~FileNameDelegate(){}
void setEditorData(QWidget* editor, const QModelIndex &index)const{
QStyledItemDelegate::setEditorData(editor, index);
//the column with file names in it
if(index.column() == 0){
//try to cast the default editor to QLineEdit
QLineEdit* le= qobject_cast<QLineEdit*>(editor);
if(le){
QObject src;
//the lambda function is executed using a queued connection
connect(&src, &QObject::destroyed, le, [le](){
//set default selection in the line edit
int lastDotIndex= le->text().lastIndexOf(".");
le->setSelection(0,lastDotIndex);
}, Qt::QueuedConnection);
}
}
}
};
//Demo program
int main(int argc, char** argv){
QApplication a(argc, argv);
QStandardItemModel model;
QList<QStandardItem*> row;
QStandardItem item("document.pdf");
row.append(&item);
model.appendRow(row);
FileNameDelegate delegate;
QTableView tableView;
tableView.setModel(&model);
tableView.setItemDelegate(&delegate);
tableView.show();
return a.exec();
}
这听起来像一个黑客,但我决定写这一点,直到有人有这个问题的更好的方法。
当角色为'Qt :: EditRole'时,您可以让模型返回文件名而不用扩展名。但这样,用户将无法更改扩展名。 – Mike
如果您希望扩展程序可编辑,您不需要绘制选择内容,您需要在行编辑中真正设置选择以排除扩展程序。你提到的第二种方法不适合你。 – Mike
重写'setEditorData'并设置你想要的选择应该工作得很好。但是在[Qt源代码](https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qabstractitemview.cpp.html#4217)中,您可以看到对'le-> selectAll() ;'setEditorData'后面。不幸的是,这意味着你在'setEditorData'中的选择会随着该调用而改变。这就是为什么你的第一种方法不起作用。 – Mike