Название: QItemDelegate обновление итема при постоянно открытом состоянни
Отправлено: Pancir от Май 27, 2013, 02:55
Привет с qt только недавно начал знакомится, пишу свое первое приложение...... В моей ситуации делегаты всегда открыты this->ui.tableView->openPersistentEditor(newit->index()); Eсли делегат создает например QLineEdit, я в нем, что-то печатаю потом кликаю в любом другом месте (смена фокуса), то данные сбрасываются в ячейку (провоцируется вызов setModelData в делегате)... Я сделал свой составной виджет, в основе которого лежит QFrame class PasswordEdit : public QFrame { Q_OBJECT public: void setText(QString &text){ this->ui.lineEdit->setText(text); } QString text(){ return this->ui.lineEdit->text(); } private slots: void update(); public: PasswordEdit(QWidget *parent = nullptr); ~PasswordEdit(); private: Ui::PasswordEdit ui; }; Идея его проста на фрэйме висит QLineEdit + QCheckBox + QPushButton... Далее я ввожу некие данные в этот виджет в QLineEdit Кликаю в любом другом месте и в делегате которые создает этот виджет не провоцируется вызов setModelData в отличии от делегата который создает "чистый" QLineEdit... Все это наводит на мысль, что мой составной виджет должен что-то делать еще... то ли флаги какие то ставить которые указывают, что этот виджет изменился то ли еще чего-то... После такого хака... в делегате создающим мой составной виджет провоцируется вызов setModelData, при смене фокуса.. connect(this->ui.lineEdit, SIGNAL(editingFinished()), this, SLOT(update())); void PasswordEdit::update(){ QFrame::setFocus(); } Хоть это и решило мою проблему, но я понимаю, что это решение не правильное.... Так как правильно это решить?
Название: Re: QItemDelegate обновление итема при постоянно открытом состоянни
Отправлено: GreatSnake от Май 27, 2013, 07:10
Ну и где код делегата?
Название: Re: QItemDelegate обновление итема при постоянно открытом состоянни
Отправлено: Pancir от Май 27, 2013, 15:33
Он простой поэтому решил его не выкладывать..... Базовый class DelegateBase : public QItemDelegate { public:
DelegateBase(QObject *parent = 0) : QItemDelegate(parent){}; private: }; Делегат с моим виджетом class SecurityDelegate : public DelegateBase{ public: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { PasswordEdit *editor = new PasswordEdit(parent); QString currentText = index.model()->data(index, Qt::DisplayRole).toString(); editor->setText(currentText); return editor; } void setEditorData(QWidget *editor, const QModelIndex &index) const { PasswordEdit *textEditor = qobject_cast<PasswordEdit *>(editor); if (textEditor) { textEditor->setText(index.model()->data(index, Qt::EditRole).toString()); } } void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { PasswordEdit *textEditor = qobject_cast<PasswordEdit *>(editor); if (textEditor) { model->setData(index, textEditor->text()); } } SecurityDelegate(QObject *parent = 0) : DelegateBase(parent){}; ~SecurityDelegate(){};
}; Делегат с QLineEdit class DefaultDelegate : public DelegateBase{ public: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const{ QLineEdit *editor = new QLineEdit(parent); editor->setFrame(false); return editor; } void setEditorData(QWidget *editor, const QModelIndex &index) const{ QLineEdit *textedit = static_cast<QLineEdit*>(editor); textedit->setText(index.model()->data(index, Qt::EditRole).toString()); } void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const{ QLineEdit *textedit = static_cast<QLineEdit*>(editor); model->setData(index, textedit->text()); } void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const{ editor->setGeometry(option.rect); }
DefaultDelegate(QObject *parent = 0) : DelegateBase(parent){}; ~DefaultDelegate(){};
}; Если рассуждать логически то проблема не в делегате в моем состовном виджете..
Название: Re: QItemDelegate обновление итема при постоянно открытом состоянни
Отправлено: GreatSnake от Май 27, 2013, 15:50
Если рассуждать логически то проблема не в делегате в моем состовном виджете..
Правильно рассуждаешь) Попробуй в конструкторе PasswordEdit C++ (Qt) ui.lineEdit->setFocusProxy( this ); setFocusPolicy( Qt::WheelFocus );
Название: Re: QItemDelegate обновление итема при постоянно открытом состоянни
Отправлено: Pancir от Май 27, 2013, 17:21
Так не работает ввод в QLineEdit, т.е я вообще не могу туда ничего ввести.... Честно говоря я решил проблему иначе.... я просто сбрасываю значения из делегата когда мне они нужны (ручным вызовом setModelData).... Но решение проблемы описанной в этом топике поможет мне получше понимать qt... так, что вопрос еще актуален, что делает QLineEdit чего не делает мой PasswordEdit ....
Название: Re: QItemDelegate обновление итема при постоянно открытом состоянни
Отправлено: GreatSnake от Май 27, 2013, 18:30
Вот пример подобного редактора, который работает: C++ (Qt) class LineEdit : public QFrame { public: LineEdit( QWidget* p = 0 ) : QFrame( p ) { QHBoxLayout* l = new QHBoxLayout( this ); le_ = new QLineEdit; l->addWidget( le_ ); setFocusProxy( le_ ); le_->installEventFilter( this ); } void setText( const QString& s ) { le_->setText( s ); } QString text() const { return le_->text(); } bool eventFilter( QObject* o, QEvent* e ) { if( o == le_ && e->type() == QEvent::FocusOut ) { QFocusEvent* fe = static_cast< QFocusEvent* >( e ); QApplication::sendEvent( this, fe ); } return QFrame::eventFilter( o, e ); } private: QLineEdit* le_; };
|