Заполнение tableModel из структуры
Всем привет.
Пытаюсь заполнить таблицу из структуры которую передаю обьекту вектором.
Может я где то ошибаюсь, undefind reference получаю. Но почему непонятно.
Ниже кидаю код класса.
#pragma once #include <QtCore/QAbstractTableModel> #include <sources/structs/wrappers/nvme/Tables.hpp> template <typename T> class TableModel : public QAbstractTableModel { public: explicit TableModel(QVector<T > vec); [[nodiscard]] int rowCount(const QModelIndex &parent) const override; [[nodiscard]] int columnCount(const QModelIndex &parent) const override; [[nodiscard]] QVariant data(const QModelIndex &index, int role) const override; [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: int m_rowCount; int m_columnCount; QVector<T* > m_vec; QVector<QString> m_vecSupPowerState; };
#include <QDebug> #include "TableModel.hpp" template <typename T> TableModel<T>::TableModel(QVector<T > vec) : m_vec(vec) , m_rowCount(vec.size()) , m_columnCount(0) { m_vecSupPowerState.push_back("St"); m_vecSupPowerState.push_back("Op"); m_vecSupPowerState.push_back("Max"); m_vecSupPowerState.push_back("Active"); m_vecSupPowerState.push_back("Idle"); m_vecSupPowerState.push_back("RL"); m_vecSupPowerState.push_back("RT"); m_vecSupPowerState.push_back("WL"); m_vecSupPowerState.push_back("WT"); m_vecSupPowerState.push_back("Ent_Lat"); m_vecSupPowerState.push_back("Ex_lat"); if (m_vec == QVector<SupportedPowerStates>()) { qDebug() << "SupportedPowerStates"; } } template <typename T> int TableModel<T>::rowCount(const QModelIndex &parent) const { return m_vec.size(); } template <typename T> int TableModel<T>::columnCount(const QModelIndex &parent) const { return 0; } template <typename T> QVariant TableModel<T>::data(const QModelIndex &index, int role) const { if(!index.isValid()) { return QVariant(); } int row = index.row(); int col = index.column(); switch (role) { case Qt::DisplayRole: return QString("%1, %2").arg(index.column()).arg(index.row()); default: break; } return QVariant(); } template <typename T> QVariant TableModel<T>::headerData(int section, Qt::Orientation orientation, int role) const { if( role != Qt::DisplayRole ) { return QVariant(); } if( orientation == Qt::Vertical ) { return section; } switch( section ) { case 0: return tr( "St" ); case 1: return tr( "Op" ); case 2: return tr( "Max" ); case 3: return tr( "Active" ); case 4: return tr( "Idle" ); case 5: return tr( "RL" ); case 6: return tr( "RT" ); case 7: return tr( "WL" ); case 8: return tr( "WT" ); case 9: return tr( "Ent_Lat" ); case 10: return tr( "Ex_lat" ); } }
Если видите в конструкторе я просто воткнул проверку, только для теста, то есть обьекту могут прилететь разыне структуры, у них разное колличество строк и столбцов.
Так же в конструкторе заполняется вектор который будет использоватся если прилетит SupportedPowerStates которая как раз в конструкторе и проверяется.
Вопрос такой, не знаю как проверять в случаи если данная структура прилетела и дял нее использовать данные поля.
И приму любые советы если есть какие то ошибки в реализации.
В main.cpp я создаю обьект таким способом
auto tableModel = new TableModel<QVector<SupportedPowerStates> >(nvmeIdCtrl->getSupportedPowerStates()); engine.rootContext()->setContextProperty("tableModel", tableModel);
Как раз данный метод и возвращает вектор такой структуры.
Спасибо.
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.Do you like it? Share on social networks!
- Akiv Doros
- Nov. 11, 2024, 2:58 p.m.
C ++ - Test 004. Pointers, Arrays and Loops
- Result:50points,
- Rating points-4
- molni99
- Oct. 26, 2024, 1:37 a.m.
C ++ - Test 004. Pointers, Arrays and Loops
- Result:80points,
- Rating points4
- molni99
- Oct. 26, 2024, 1:29 a.m.
C ++ - Test 004. Pointers, Arrays and Loops
- Result:20points,
- Rating points-10
Привет.
Зачем использовать таблицу, когда по факту здесь обрабатывается одна строка? Несмотря на то, что по задумке видимо каждый объект должен прдставлять собой именно строку.
При этом в headerData возвращаешь заголовки для горизонтальной ориентации. section в том случае - это номер колонки.
Почему coulmnCount возвращает 0? в данном случае он возвращать должен как минимум 1, если следовать задумке.
Вообще, вместо того, чтобы шаманить шаблоны. Лучше передавать в таблицу указатель на интерфейсный класс, а передаваемые в вектор объекты должны будут реализовывать этот интерфейс.
По поводу передачи одной строки это пока просто был тест, туда будет именно таблица лететь, ну то есть вектор векторов.
В headerData там был просто начальный набросок, и как я написал там будет в зависимости какая структура такая структура с заголовками и будет.
Там я заготовил одну из них. В coulmnCount возвращение 0 это пока дефолтно.
Вместо вектора векторов лучше использовать класс или структуру. Или лучше я говорил интерфейсный класс или базовый абстрактный класс. В большинстве случае можно и без шаблона обойтись.
Полагаю, что undefined reference относится скорее к проблеме внутри main функции, полный текст кода хотелось бы видеть.
Либо проблема может быть в том, что шаблоны и Q_OBJECT не совместимы. То есть либо пишется шаблонная модель, либо модель с макросом Q_OBJECT.
Либо можно написать шаблонную модель, от которой наследуется конкретная реализация с Q_OBJECT. Такое тоже работает. Но одновременно в одном классе нет. Тоже самое и где-то в документации написано.
А конкретно для QML отсутствие макроса Q_OBJECT может быть критично, поскольку не создаётся правильная метаинформация.
Это лишь мысли, проверять нужно. Но скорее всего так. Лучше уже полиморфизм, чем шаблоны в данном случае.
Ты бы мог простой набросок скинуть как бы выглядела реализация с таким интерфейсом для разного рода контейнеров со структурами и как бы они определялись в модели для заполнения таблицы?
Вот пример класса интерфейса и класса потомка
Можешь наследоваться от интефейса и определять стандартизированное поведение, например у тебя есть методы:
А дальше внутри модели хранишь только вектор указатель на интерфейс
Дальше в модель загружаешь через какой-нибудь метод указатели на любые объекты, классы которых наследованы от интерфейса.
А внутри модели уже крутишь всё как хочешь. Смысл тот же, что у тебя и есть.
Если же тебе нужно совсем различное поведение в разных таблицах, то имеешь одну базовую таблицу, наследуешься от неё, и переопределяешь только то, что тебе нужно.
Так, тут в принципе немного ясно становится. Но наследование от QAbstractTableModel идет также на IntModelObject и других потомкой что будут работать со своим типом структур?
Все, по поводу модели понял.
Хотел уточнить с тем что я написал и правильно ли понял:
Правильно ли все в этой реализации и коменты что я подписал?
И вот так уже я в main.cpp передаю один из обьектов с данными
Если в конструктор передавать какую-то структуру, которую должен поддерживать тот класс, то в принципе да. в общем-то правильно будет. Конкретная реализация уже покажет ошибки в процессе.
Что касается метода setObject, то здесь его лучше переименовать в addObject. Поскольку перевоначальное наименование не отражает сути метода. Ты добавляешь объекты, и их может быть много в этой модели. Тогда как setObject априори подразумевает только один объект, который будет находится в классе, в который добавляется данный объект. Ну и совсем явная ошибка, это наличие модификатора const у метода setObject. Данный метод модифицирует состояние модели данных, а значит никак не может быть константным.
Спасибо, вроде немного стало более ясно. С ошибкой тоже.
Получается что
получая обьект уже определяет что это за обьект из наследников и уже у модели внутри что то с каждым делает?
Внутри он просто закидывает в вектор этот объект, и всё
Дальше в методах модели просто вызываешь методы, которые созданы в абстрактном классе IModelObject.
Твоя задача определить рееализацию в классах, которые наследованы от IModelObject. Это класс является интерфейсом.
Он формирует унифицированный интерфейс, а задача остальных классов наследников реализовать эти интерфейсы.
Если сможешь унифицировать поведение тех различных структур, то сможешь обобщить большую часть и использовать меньшее число моделей, чем по модели на каждый вид структуры
Хорошо, понял.
Вообще разница тех контейнеров что несут в себе структуры только в том что разное колличество столбцов, строк, названий столбцой. Ну и данные само собою.
Количество строк роли не играет, поскольку это всего лишь размер контейнера.
А вот количество столбцов - это более сложный вопрос.
Из-за разного количества столбцов скорее всего придётся делать наследованные модели и расширять поведение. Одним унифицированным интерфейсом не обойтись.