Недавно я сделал образец, чтобы лучше ознакомиться с QStyledItemDelegate
, касающимся встроенного редактирования. клеток:
В этом примере я обновил базовую модель данных, перегружая QStyledItemDelegate::setModelData()
. .
Прочитав этот вопрос, я только что проверил, что произойдет, если ввод будет завершен (или, строго говоря, прерван) с помощью ESC. Вот что я наблюдал:
Базовые данные остаются неизменными.
Копнув глубже (т.е. установив точку останова в моем перегруженном setModelData()
), я заметил, что setModelData()
в этом случае даже не вызывается.
Может быть, проблему с ОП можно легко решить, немного изменив дизайн его делегата.
Наконец, мой производный класс (объявление), который я использовал для получения «полнофункционального» делегата для редактирования ячеек таблицы в строке:
class ValueNameDelegate: public QStyledItemDelegate {
// methods:
public:
/// @name Construction & Destruction
//@{
/// constructor.
ValueNameDelegate();
/// destructor.
virtual ~ValueNameDelegate() = default;
// disabled:
ValueNameDelegate(const ValueNameDelegate&) = delete;
ValueNameDelegate& operator=(const ValueNameDelegate&) = delete;
//@}
protected:
/// @name Overloaded Event Handlers
//@{
// inserts editor in table (by setParent(pQParent)) and
// returns the editor widget to edit cell.
virtual QWidget* createEditor(
QWidget *pQParent, const QStyleOptionViewItem &qOption,
const QModelIndex &qMIndex) const override;
// removes editor from table (by setParent(nullptr)).
virtual void destroyEditor(
QWidget *pQEditor, const QModelIndex &qMIndex) const override;
// reads data from table model and updates editor.
virtual void setEditorData(
QWidget *pQEditor, const QModelIndex &qMIndex) const override;
// reads data from editor and updates table model.
virtual void setModelData(
QWidget *pQEditor, QAbstractItemModel *pQModel,
const QModelIndex &qMIndex) const override;
//@}
};
Примечание:
В моем случае заранее создан только один виджет редактора. Он повторно используется для каждого редактирования ячейки (вместо создания для каждого редактирования нового).
Это немного отличается от примера делегата Qt Spin Box, но работает как положено.
Я не могу себе представить, как это не должно иметь никакого значения в отношении проблемы OP.
Согласно обратной связи, OP хочет обработать событие потери фокуса, например прерывание ввода. Это противоречит тому, как это обрабатывается по умолчанию в QLineEdit
.
Итак, мое решение состоит в том, чтобы предоставить перегруженную версию QLineEdit
. Вместо изменения поведения QLineEdit
он просто отслеживает в члене bool _confirmed
, Ввод был нажат. Самым сложным было определить другое подходящее событие или сигнал для сброса члена. Наконец, я решил, что focusOutEvent()
просто вызывается в нужное время и, следовательно, подходит для этой задачи.
testQLineEdit-Finished.cc
:
#include <QtWidgets>
class LineEdit: public QLineEdit {
private:
// flag: true ... last finished editing was confirmed
bool _confirmed;
public:
// Construction & Destruction
explicit LineEdit(
const QString &contents = QString(), QWidget *pQParent = nullptr):
QLineEdit(contents, pQParent),
_confirmed(false)
{
QObject::connect(this, &QLineEdit::returnPressed,
[this](){ onSigReturnPressed(); });
}
LineEdit(QWidget *pQParent): LineEdit(QString(), pQParent) { }
virtual ~LineEdit() = default;
LineEdit(const LineEdit&) = delete;
LineEdit& operator=(const LineEdit&) = delete;
public:
// returns whether last finished editing was confirmed.
bool isConfirmed() { return _confirmed; }
protected:
virtual void focusOutEvent(QFocusEvent *pQEvent) override
{
_confirmed = false;
QLineEdit::focusOutEvent(pQEvent);
}
private:
void onSigReturnPressed() { _confirmed = true; }
};
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
LineEdit qEdit(QString::fromUtf8("Hello World"));
qEdit.show();
// install signal handlers
QObject::connect(&qEdit, &LineEdit::editingFinished,
[&]() {
qDebug() << "Edit confirmed:" << qEdit.isConfirmed();
});
// runtime loop
return app.exec();
}
![Снимок testQLineEdit-Finished](https://i.stack.imgur.com/f4fvq.png)
Вывод Edit confirmed: true
был достигнут нажатием Enter, false
строк - щелчком мыши.
Делается это довольно просто, а можно сделать и посложнее. Тем не менее, он показывает принцип, достигнутый с довольно небольшим количеством строк кода.
person
Scheff's Cat
schedule
10.03.2018