QStyledItemDelegate частично выделить текст редактора QLineEdit по умолчанию

У меня есть подкласс QStyledItemDelegate который на данный момент не переопределяет никакие функции (для простоты вопроса).

По умолчанию QStyledItemDelegate реализация, когда пользователь начинает редактировать текст в QTableViewделегат рисует QLineEdit с текстом из модели и выбирает все его (выделяет все для редактирования).

Текст представляет собой имена файлов, такие как "document.pdf". Пользователь может редактировать весь этот текст, однако я хочу только выделить часть базового имени ("документ"), а не суффикс ("pdf"). Как я могу это сделать? (Мне не нужна логика того, как это сделать, мне нужно знать, как получить QStyledItemDelegate выделить часть текста)

Я пробовал:

  • в setEditorData() используемый QLineEdit::setSelection() выделить текст. Это не имеет никакого эффекта.

  • в paint() попытался нарисовать на основе того, что другие респонденты рекомендовали подобные вопросы, но не успех. У меня мало опыта с QPainter, Вот пример: Настройка поведения выбора QStandardItem с помощью QStyledItemDelegate

Пожалуйста, помогите, и спасибо заранее. Фрагмент кода, скажем, выбрав первые 3 символа текста, будет очень полезен.

1 ответ

Решение

Как отмечено в моих комментариях к вопросу, проблема с подклассами 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 здесь он пытается позвонить selectAll() здесь, когда редактор виджет QLineEdit, Это означает, что любой выбор, который мы предоставляем в 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();
}

Это может звучать как хак, но я решил написать это, пока у кого-то нет лучшего подхода к проблеме.

Другие вопросы по тегам