Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Изменение значений в модели и отображении, Изменение значений в модели и отображени 
:(
    Опции темы
olegkuzn
Дата 28.6.2012, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

Репутация: нет
Всего: нет



Здраствуйте.
Помогите решить проблему.

1. Есть класс модели производный от QAbstractItemModel
2. Есть класс отображения данныйх модели производный от QTreeView
3. Есть класс Delegate производный от QItemDelegate

В классе делегата есть перегруженная ф-ция createEditor. 
В одном из вариантов работы она возвращает указатель на объект класса QSpinBox и устанавливается связь 
с моделью данных по изменению значений в виджете.

Код

void setTmpIndex(const QModelIndex& p_index) { m_tmpIndex = p_index; }

// QModelIndex m_tmpIndex; - переменная для  хранения индекса данных которые в данный момент редектируются

/*virtual*/
QWidget* Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
. . .
    {
    Q_UNUSED(option);
    QSpinBox* pSpin = new QSpinBox(parent);
    pSpin->setRange(1,100);

    PropertyModel* pModel = (PropertyModel*)(index.model());
    pModel->setTmpIndex(index); 

   // устанавливаем связь сигнал-слот созданного виджета с моделью 
    QObject::connect(pSpin,SIGNAL(valueChanged(int)),pModel,SLOT(ValueChanged(int))); 
    return pSpin;
    }
. . .
}


В SLOTE модели должно произойти изменение данных с родительским индексом и отображение
данных в классе отображения модели.

Код

void PropertyModel::ValueChanged(int p_i)
{
   // объект класса 

    QModelIndex parent = m_tmpIndex.parent(); // получаем родительский индекс
    setData(parent,QVariant(p_i),Qt::EditRole);   // изменяем данные в родительском индексе
    emit dataChanged(parent,parent);                 // пытаемся прорисовать данные в отображении
}
 

В ф-ции PropertyModel::ValueChanged пытаюсь "прорисовать" данные родительского индекса в отображении.
Результат - 0. Хотя после окончания работы виджета данные "перерисовываются". Как сделать так, чтобы данные изменялись в отоборажении
по сигналу виджета valueChanged(int i).

Если есть примеры с подобной задачей то не могли уприслать или указать - где их найти.

Заранее спасибо.
PM MAIL   Вверх
math64
Дата 28.6.2012, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Логичнее разместить слот в делегате, а не нагружать модель не свойственными ей функциями. Модель можно использовать в двух QTreeView,
Именно в этом случае имеет смысл обновлять модель до окончания редактирования.
Код

class Delegate : public QItemDelegate {
Q_OBJECT
public:
  QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
  {
  QSpinBox* editor = new QSpinBox(parent);
  QObject::connect(editor,SIGNAL(valueChanged(int)),this,SLOT(editorDataChanged()));
  m_editor = editor;
  m_index = index;
  return editor;
  }
  void setModelData(QWidget *editor, QAbstactItemModel* model,  const QModelIndex &index) const;
  void setEditorData(QWidget *editor, const QModelIndex &index) const;
private slots:
 void editorDataChanged() {
   setModelData(m_editor, const_cast<QAbstactItemModel*>(m_index.model()), m_index);
 }
private:
  mutable QWidget* m_editor;
  mutable QModelIndex m_index;
}


PM   Вверх
olegkuzn
Дата 28.6.2012, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

Репутация: нет
Всего: нет



Да. Действиельно так как вы предложили выглядит лучше. 
Но к сожалению не решена проблема - как при  редактировании данных по одному индексу 
происходила перерисовка данных по другому индексу.  
Думал сделать так :
Код

/*virtual */
bool PropertyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid())
        return false;

    if(index.column() == 1 && role == Qt::EditRole)
    {
        AbstractPropertyItem* item = static_cast<AbstractPropertyItem*>(index.internalPointer());
        item->setValue(value);

        QModelIndex parent = index.parent(); // получаем индекс родительских данных
        emit dataChanged(parent, parent);     // посылаем сигнал на обновление данных в классе отображения производном от QTreeView
                                                                // (при изменении данных в дочетних объектах данные в родительском объекте тоже изменяются - 
                                                                // так реализована ф-ция QVariant PropertyModel::data(const QModelIndex &p_index, int p_role) const )

        return true;
    }
    else
        return false;
}



Результата нет.

PM MAIL   Вверх
math64
Дата 29.6.2012, 07:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



А зачем ты делаешь emit dataChanged(parent, parent);  ? Ты же не значение родительского индекса меняшь:
Код

emit dataChanged(index, index); 


Добавлено через 3 минуты и 49 секунд
судя по комментарию, emit dataChanged(parent, parent);  тоже нужен, но каких-то emit не хватает. Как у тебя устроена модель?
PM   Вверх
olegkuzn
Дата 29.6.2012, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

Репутация: нет
Всего: нет



Мне необходимо сделать так, чтобы после изменения данных индекса index  по сигналу valueChanged(int i) 
изменялось отображение данных родительского индекса index.parent(). При изменении данных в дочерних объектах
данные в родительском объекте тоже изменяются (так реализована ф-ция QVariant PropertyModel::data).
выражение  emit dataChanged(parent, parent); должно (по идее) произвести эти изменения.

(Например в рабочей среде Qt Creator в редакторе форм в окне свойств объекта при при редактировании подсвойства "Ширина" 
 свойства "geometry" данные изменяютcя как в редакторе св-ва "Ширина" так и в родительском объекте "geometry")

PM MAIL   Вверх
math64
Дата 29.6.2012, 08:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Возможно, у тебя неправильно реализована:
QVariant PropertyModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const;
Обрати внимание на различие Qt::EditRole и Qt::DisplayRole. Как правило, они должны возвращать одно и тоже,
но могут быть различия (например, Qt::EditRole возвращает число, Qt::DisplayRole - строку)
Редактор работает с Qt::EditRole, при отображении нередактирующегося значения используется Qt::DisplayRole.

PM   Вверх
olegkuzn
Дата 29.6.2012, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

Репутация: нет
Всего: нет



Проверил работу с помощью консоли приложения.
Пока ничего не нашел. Хотя.
При начале редактирования в помощью виджета выскакивает сообщение :

Can't select indexes from different model or with different parents

Из-за чего такое сообщение может появляться.
Может здесь ошибка.



PM MAIL   Вверх
math64
Дата 29.6.2012, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Такая ошибка возникает, когда одной модели передаёшь индекс от другой модели (different model).
У тебя скорее всего different parents. Возникнет, например при
Код

emit dataChanged(parent, index); 

PM   Вверх
olegkuzn
Дата 29.6.2012, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

Репутация: нет
Всего: нет



Методом околонаучного тыка изменил выражение "emit dataChanged(parent, parent);"   на выражение "emit dataChanged(index, parent);"
И... Заработало. Непонятно почему но заработало. (Хотя это и страшно.)
Спасибо вам за помощь.



PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0467 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.