QStyledItemDelegate部分选择默认的QLineEdit编辑器的文本
我有一个QStyledItemDelegate
的子类,它目前不重新实现任何功能(为了简化问题)。QStyledItemDelegate部分选择默认的QLineEdit编辑器的文本
在默认QStyledItemDelegate
实现,当用户开始在QTableView
编辑文本,委托绘制一个QLineEdit
从模型中的文本,并选择它的所有(突出显示所有编辑)。
该文本表示文件名,如“document.pdf”。用户可以编辑这整个文本,但是,我只想在最初突出显示基本名称部分(“文档”)而不是后缀(“pdf”)。我怎样才能做到这一点? (我不需要的如何做到这一点的逻辑,我需要知道如何让QStyledItemDelegate
突出文本的一部分)
我已经试过:
在
setEditorData()
使用QLineEdit::setSelection()
突出显示一些文字。这没有效果。paint()
试图根据其他受访者对类似问题推荐的内容进行绘制,但不成功。我几乎没有QPainter
的经验。这里是一个例子:Adjusting the selection behaviour of QStandardItem with QStyledItemDelegate
请帮助,并提前致谢。我们将非常感谢带有说选择文本的前3个字符的代码片段。
正如我的意见的问题,与子类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();
}
这听起来像一个黑客,但我决定写这一点,直到有人有这个问题的更好的方法。
非常感谢Mike。由于我编辑的列大于0,因此,如果(index.column()== 0)对代码进行非常小的修改以完全正常工作,它看起来像是一种工作,你认为值得提交一个错误报告给Qt提供更好的API来访问小部件,以便用户完全控制它?非常感谢:) – CSLover
@CSLover,欢迎您。这就是我的意思,你需要将其更改为列,如果你有文件名:) – Mike
@CSLover,我不太确定这个错误报告。但个人而言,我认为这不值得提交错误报告。他们似乎把''le-> selectAll()'调用为'QLineEdit',这样覆盖'setEditorData'的用户就不必调用'selectAll()'来让他们的行编辑中的文本被选中默认。省略该调用可能会导致很多已编写的代码默认显示“QLineEdit”,并且没有选择。 – Mike
当角色为'Qt :: EditRole'时,您可以让模型返回文件名而不用扩展名。但这样,用户将无法更改扩展名。 – Mike
如果您希望扩展程序可编辑,您不需要绘制选择内容,您需要在行编辑中真正设置选择以排除扩展程序。你提到的第二种方法不适合你。 – Mike
重写'setEditorData'并设置你想要的选择应该工作得很好。但是在[Qt源代码](https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qabstractitemview.cpp.html#4217)中,您可以看到对'le-> selectAll() ;'setEditorData'后面。不幸的是,这意味着你在'setEditorData'中的选择会随着该调用而改变。这就是为什么你的第一种方法不起作用。 – Mike