Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: alexi от Сентябрь 30, 2014, 12:43



Название: Запретить закрытие делигата!
Отправлено: alexi от Сентябрь 30, 2014, 12:43
Проблема заключается в следующем!
При редактировании ячейки создается делигат, туда заносятся данные, после чего они проверяются на корректность и оригинальность, если вдруг введенные данные уже существуют или некорректны ОШИБКА. При ошибке доджно выводиться сообщение и делигат оставаться не уничтоженным. С проверками и сообщением проблем нет, да и с нажатием клавиш при редактировании тоже(Enter tab esc и тд), но вот если кликнуть мышью по другой ячейке то делигат уничтожается. Как сделать так чтобы при выборе др ячейки а\во время редактирования, если ошибка, то ячейка остается в режиме редактирования.


Название: Re: Запретить закрытие делигата!
Отправлено: GreatSnake от Сентябрь 30, 2014, 12:46
Может всё-таки создаётся виджет, а не делЕгат?


Название: Re: Запретить закрытие делигата!
Отправлено: alexi от Сентябрь 30, 2014, 12:53
Да да, виджет, QLineEdit, но я думаю Вы меня поняли, я прост недавно на QT)


Название: Re: Запретить закрытие делигата!
Отправлено: alexi от Сентябрь 30, 2014, 13:19
Прошу прощения за оставленный ранее корявый пост.
Вот код фильтра и процедуры setModelData делегата(виджета) созданного при редактировании

Код:
void IPinput::setModelData(QWidget *editor, QAbstractItemModel *model,
                  const QModelIndex &index) const
{
    QLineEdit *edit = static_cast <QLineEdit*> (editor);
    QString strEdit = edit->text();
    if (!correctIP(strEdit)){
       model->setData(index,Qt::red,Qt::TextColorRole);//пока просто крашу некорректные данные
    }
    model->setData(index,strEdit,Qt::EditRole);
}

...

bool IPinput::eventFilter(QObject *obj, QEvent *event)
{
    QLineEdit *edit = static_cast<QLineEdit *> (obj);
    if (event->type() == QEvent::KeyPress) {
          QKeyEvent *keyPress = static_cast<QKeyEvent *>(event);
          if(keyPress->key() == Qt::Key_Escape){
               edit->setText(oldInputIP);
               return true;
            }else return QItemDelegate::eventFilter(obj, event);
   
    if (event->type()== QEvent::FocusOut){
 //тут можно вставить проверку, но ,     
 //что при true, что при false вызывается диструктор 
        return false;
    }
    }else{
     return QItemDelegate::eventFilter(obj, event);
  }
}


Название: Re: Запретить закрытие делигата!
Отправлено: VPS от Сентябрь 30, 2014, 14:19
Можно попробовать создать своё представление отнаследованное от QAbstractItemView (или его потомков) и переопределить метод:
Код:
void QAbstractItemView::closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint )
в котором запрещать закрытие редактора.


Название: Re: Запретить закрытие делигата!
Отправлено: alexi от Октябрь 01, 2014, 11:03
Каким образом запретить закрытие редактора???


Название: Re: Запретить закрытие делигата!
Отправлено: carrygun от Октябрь 02, 2014, 04:36
Каким образом запретить закрытие редактора???

Написать return?


Название: Re: Запретить закрытие делигата!
Отправлено: alexi от Октябрь 02, 2014, 09:03
Можно попробовать создать своё представление отнаследованное от QAbstractItemView (или его потомков) и переопределить метод:
Код:
void QAbstractItemView::closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint )
в котором запрещать закрытие редактора.

Как правильно это сделать

Код:
class closeDelegate: public QAbstractItemDelegate{

     void closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint);
};
....

closeDelegate *Item =  new closeDelegate();

Я вообще нуб в QT, не догоняю пока как это все работает



Название: Re: Запретить закрытие делигата!
Отправлено: carrygun от Октябрь 02, 2014, 10:26
Нужно написать теперь реализацию метода вашего нового класса, примерно со следующей логикой (псевдокод):
Код
C++ (Qt)
...
closeDelegate::closeEditor(QWidget * editor, QAbstractItemDelegate::EndEditHint hint) {
...
   if (expr) {
       ...
       //closing editor
       QAbstractItemDelegate::closeEditor(editor, hint);
   } else {
       ...
       //ignore
       return;
   }
}
...
 


Название: Re: Запретить закрытие делигата!
Отправлено: alexi от Октябрь 02, 2014, 10:43
эт понятно, я имел в виду, как мне мой класс closeDelegate "прицепить" к QtableWidget


Название: Re: Запретить закрытие делигата!
Отправлено: gil9red от Октябрь 02, 2014, 11:29
эт понятно, я имел в виду, как мне мой класс closeDelegate "прицепить" к QtableWidget

используйте метод setItemDelegate


Название: Re: Запретить закрытие делигата!
Отправлено: alexi от Октябрь 02, 2014, 12:00
Делегат
Код:
class IPinput : public QItemDelegate//редактирование IP таблиц
{
    Q_OBJECT
public:
    IPinput(QObject *parent = 0);
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const;
   // void closeEditor(QWidget *editor, EndEditHint hint);
public slots:
    bool eventFilter(QObject *obj, QEvent *event);
    // bool eventFilter(QObject *obj, QEvent *event);
protected :
   virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);//сюда не попадаем
};
...

void IPinput::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint){
   
    return;
}
....

   ui->tableSpisok->setItemDelegateForColumn(2,new IPinput());
}

virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) программа сюда не заходит


Название: Re: Запретить закрытие делигата!
Отправлено: VPS от Октябрь 02, 2014, 21:10
virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) программа сюда не заходит

alexi, если Вы читали то, что я написал, то там предлагался метод класса - представления, а не делегата.
В документации написано, что в классе - делегате "closeEditor()" - это сигнал (http://qt-project.org/doc/qt-5/qabstractitemdelegate.html#closeEditor). В qt5 в делегатах введён вот такой метод:
Код:
virtual void destroyEditor(QWidget * editor, const QModelIndex & index) const
, который Вам скорее всего поможет, если Вы используете данную версию библиотеки (или выше).
Точнее сказать не могу, так как использую qt4.


Название: Re: Запретить закрытие делигата!
Отправлено: alexi от Октябрь 03, 2014, 07:31
У меня тоже QT 4
Вот предопределяю
Код:
class closeDelegate: public QAbstractItemView{

 protected:
   void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
};

...

void closeDelegate::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint){

    return;

}

Как теперь мне closeDelegate "связать" c QtableWidget или с классом делегата???
Код:
class IPinput : public QItemDelegate//редактирование IP таблиц
{
    Q_OBJECT
public:
    IPinput(QObject *parent = 0);
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const;
   // void closeEditor(QWidget *editor, EndEditHint hint);
public slots:
    bool eventFilter(QObject *obj, QEvent *event);
    // bool eventFilter(QObject *obj, QEvent *event);
protected :
  // virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
};

....

ui->tableSpisok->setItemDelegateForColumn(2,new IPinput());
ui->tableSpisok->setItemDelegateForColumn(1,new IPinput());



Название: Re: Запретить закрытие делигата!
Отправлено: gil9red от Октябрь 03, 2014, 07:41
Попробуйте использовать это:
Код
C++ (Qt)
class closeDelegate: public QTableWidget{
 
protected:
  void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
};
 
QAbstractItemView дальний предок QTableWidget, поэтому у них будет общий метод closeEditor, вот его вы в своей таблице и переопределите.