QStyledItemDelegate 部分 select 默认 QLineEdit 编辑器的文本

QStyledItemDelegate partially select text of default QLineEdit editor

我有一个 QStyledItemDelegate 的子类,目前没有重新实现任何功能(为简单起见)。

使用默认的 QStyledItemDelegate 实现,当用户开始编辑 QTableView 中的文本时,委托会使用模型中的文本绘制 QLineEdit,并选择所有文本(突出显示所有以供编辑)。

文字代表文件名如"document.pdf"。允许用户编辑整个文本,但是,我最初只想突出显示基本名称部分 ("document") 而不是后缀 ("pdf")。我怎样才能做到这一点? (我不需要如何执行此操作的逻辑,我需要知道如何让 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 代码中)当编辑器小部件是 QLineEdit 时视图调用我们的 setEditorData here, it tries to call 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();
}

这听起来像是 hack,但我决定写这篇文章,直到有人有更好的方法来解决这个问题。