正如我的意見的問題,與子類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