Russian Qt Forum
Ноябрь 24, 2024, 12:52 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Помогите разобраться с MVC. Простой пример.  (Прочитано 14511 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« : Январь 12, 2010, 10:10 »

Всем доброго времени!

У меня тут назрела необходимость в представлении каким либо образом данных из массива. Т.е. имеется некий массив с данными (пусть на 10 элементов) и мне необходимо на форме(виджете) показывать что-то вроде таблицы в которой один столбец будет представлять собой номер элемента массива, а другой - значение!
Также необходимо, чтобы по клику на значении какого либо элемента - эта ячейка таблицы переходила в режим редактирования с возможностью изменить значение выбранного элемента массива.

Вопросы:
1. Какой для этих целей выбрать виджет лучше?
2. Необходима ли для этого вообще концепция MVC? Или что-то другое?
3. Посоветуйте примеры где есть что-то аналогичное?

Улыбающийся

спс.

ЗЫ: что-то я в тупике
Записан

ArchLinux x86_64 / Win10 64 bit
Karl-Philipp
Гость
« Ответ #1 : Январь 12, 2010, 11:27 »

Spin Box Delegate Example?
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Январь 12, 2010, 11:42 »

Дадада, именно это! Спс Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Январь 12, 2010, 11:51 »

Бегло просмотрел.. И непонятен момент: а каким образом связать данные моего массива с моделью? Ведь в этом примере данные из ячеек хранятся в самой модели - а у меня они должны хранится в массиве!
Записан

ArchLinux x86_64 / Win10 64 bit
Karl-Philipp
Гость
« Ответ #4 : Январь 12, 2010, 12:07 »

Тогда глянь пример simple tree model - там для хранения данных используется кастомная модель, думаю она тебе подойдёт. Но в этом примере не демонстрируются делегаты.
« Последнее редактирование: Январь 12, 2010, 12:09 от terlan » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #5 : Январь 12, 2010, 12:18 »

спс
Записан

ArchLinux x86_64 / Win10 64 bit
crossly
Гость
« Ответ #6 : Январь 12, 2010, 22:58 »

посмотри QStringListModel.... там в качестве источника данных для модели используется QStringList... может вместо массива тебе можно использовать    QStringList.... если нет.... можешь сделать свою модель по примеру этой (с источником данных в качестве массива)... ничего сложного там нету...
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #7 : Январь 14, 2010, 22:01 »

что-то у меня ничего не получается. мне нужно сделать модель в виде таблицы с размерностью 3 столбца х 10 строк (к примеру).
конструктор модели при ее создании должен брать в расчет (принимать входным параметром) размер некоего массива с данными.

arraymodel.h
Код:
#ifndef ARRAYMODEL_H
#define ARRAYMODEL_H

#include <QAbstractTableModel>
#include <QVector>

class ArrayModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    ArrayModel(const QVector<int> &data, int startAddress, int regType, QObject *parent = 0);
    ~ArrayModel();

    private:
    QVector<int> m_data;
};

#endif
arraymodel.cpp
Код:
#include <QtGui>

#include "arraymodel.h"

ArrayModel::ArrayModel(const QVector<int> &data, int startAddress, int regType, QObject *parent)
    : QAbstractTableModel(parent), m_data(data)
{
    Q_UNUSED(startAddress);
    Q_UNUSED(regType);
   
    //вставляем 3 столбца + 10 строк в модель
    this->insertColumns (0, 3);
    this->insertRows (0, m_data.count());
}

ArrayModel::~ArrayModel()
{
}

main.cpp
Код:
#include <QApplication>
#include <QVector>
#include <QTableView>

#include "arraymodel.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
   
    QVector<int> data(10);  //наш массив из которого/в который должны читаться/писаться данные
   
    for (int i=0;i<10;i++)
        data[i] = i*2;      //тут мы заполнили массив

    ArrayModel model(data, 0, 0);   //должны создать модель типа "таблица
    QTableView tableView;
    tableView.setModel(&model);

    tableView.setWindowTitle(QObject::tr("Example #1"));
    tableView.show();
    return app.exec();
}

компилятор пишет это:
Цитировать
[kuzulis@kuzulis test1]$ make
g++ -c -m64 -pipe -march=x86-64 -mtune=generic -O2 -pipe -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt/mkspecs/linux-g++-64 -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -o arraymodel.o arraymodel.cpp
g++ -c -m64 -pipe -march=x86-64 -mtune=generic -O2 -pipe -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt/mkspecs/linux-g++-64 -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -o main.o main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:17: ошибка: cannot declare variable ‘model’ to be of abstract type ‘ArrayModel’
arraymodel.h:9: замечание:   because the following virtual functions are pure within ‘ArrayModel’:
/usr/include/QtCore/qabstractitemmodel.h:178: замечание:        virtual int QAbstractItemModel::rowCount(const QModelIndex&) const
/usr/include/QtCore/qabstractitemmodel.h:179: замечание:        virtual int QAbstractItemModel::columnCount(const QModelIndex&) const
/usr/include/QtCore/qabstractitemmodel.h:182: замечание:        virtual QVariant QAbstractItemModel::data(const QModelIndex&, int) const
make: *** [main.o] Ошибка 1
[kuzulis@kuzulis test1]$

Помогите разобраться в чем дело Грустный
ЗЫ: что-то я не понял в чем суть
ЗЫЗЫ: прикрепляю проект
Записан

ArchLinux x86_64 / Win10 64 bit
MoPDoBoPoT
Гость
« Ответ #8 : Январь 14, 2010, 22:27 »

Хех, QAbstractTableModel - не спроста он абстрактный. Надо реализовать хотябы минимальный интерфейс - только для чтения: flags(), data(), headerData(), rowCount(), columnCount().
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #9 : Январь 14, 2010, 23:27 »

спасибо, вроде получилось.

Но теперь возникает вопрос: как сделать так, чтобы модель отслеживала изменение данных в массиве data(10) который в main.cpp ?
Код:
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
   
    QVector<int> data(10);  //наш массив из которого/в который должны читаться/писаться данные
....
}
?

PS: прилагаю проект
Записан

ArchLinux x86_64 / Win10 64 bit
Dendy
Гость
« Ответ #10 : Январь 14, 2010, 23:32 »

Прятать массив внутрь самой модели и изменять его не напрямую, а с помощью торчащих наружу из модели методов.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #11 : Январь 14, 2010, 23:46 »

Цитировать
Прятать массив внутрь самой модели и изменять его не напрямую, а с помощью торчащих наружу из модели методов.
'эмм... так внутри модели есть копия этого массива - т.е. переменная:
Код:
....
 private:
    QVector<int> m_data;
....
вот если менять элементы этого "внутреннего" массива m_data - то модель отследит?
Записан

ArchLinux x86_64 / Win10 64 bit
Dendy
Гость
« Ответ #12 : Январь 14, 2010, 23:53 »

Чудес не бывает, это C++. Чтобы отследить нужно делать обёртку. Снаружи никто даже не должен догадываться в каком виде хранятся данные. Кроме того внутри обёртки перед изменением самих данных модель обязана сигнализировать, что вот сейчас данные ещё старые, но я их сейчас поменяю QAbstractItemModel::beginInsertRows()/QAbstractItemModel::endInsertRows() + сопутствующие методы, в документации всё подробно расписано.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #13 : Январь 15, 2010, 00:18 »

не понятно все-равно...
Я у себя предполагал что оно будет работать так:
1. Имеется класс А - в котором находится массив с данными.
2. При запуске приложения - должен начать работать некий алгоритм (процесс работы), который меняет (обновляет) данные в этом массиве в течении всего периода работы приложения.
3. Имеется класс Б - это типа модель, которая должна чисто для GUI показывать (отображать) изменения этих данных в процессе работы приложения...

Так вот, теперь я опять запутался:
Цитировать
Кроме того внутри обёртки перед изменением самих данных модель обязана сигнализировать, что вот сейчас данные ещё старые, но я их сейчас поменяю QAbstractItemModel::beginInsertRows()/QAbstractItemModel::endInsertRows() + сопутствующие методы
у меня модель (допустим для простоты) не меняет данные - она их только отображает... т.е. это класс А (источник данных) должен сигнализировать классу Б (модели) о том. что данные поменялись и следовательно модель должна обновить значения в QTableView.

т.е. путаница и нестыковка получается или я недопонял ничего Грустный


« Последнее редактирование: Январь 15, 2010, 00:21 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
Dendy
Гость
« Ответ #14 : Январь 15, 2010, 00:55 »

Модель не просто отображает данные, она их полностью контролирует. Неважно, прямо или косвенно. Класс А не может просто сигнализировать, что данные уже изменились, он должен предварительно указать что данные сейчас поменяются, а после изменений сказать готово. Простого изменения данных недостаточно - нужно задейстовать весь функционал модели. Выше я показал пример с добавлением строк. В документации всё расписано.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.054 секунд. Запросов: 23.