BlinCT
BlinCT24 октября 2019 г. 12:42

Заполнение 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);

Как раз данный метод и возвращает вектор такой структуры.

Спасибо.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

13
Evgenii Legotckoi
  • 25 октября 2019 г. 3:06
  • (ред.)

Привет.
Зачем использовать таблицу, когда по факту здесь обрабатывается одна строка? Несмотря на то, что по задумке видимо каждый объект должен прдставлять собой именно строку.
При этом в headerData возвращаешь заголовки для горизонтальной ориентации. section в том случае - это номер колонки.
Почему coulmnCount возвращает 0? в данном случае он возвращать должен как минимум 1, если следовать задумке.

Вообще, вместо того, чтобы шаманить шаблоны. Лучше передавать в таблицу указатель на интерфейсный класс, а передаваемые в вектор объекты должны будут реализовывать этот интерфейс.

    BlinCT
    • 25 октября 2019 г. 6:33

    По поводу передачи одной строки это пока просто был тест, туда будет именно таблица лететь, ну то есть вектор векторов.
    В headerData там был просто начальный набросок, и как я написал там будет в зависимости какая структура такая структура с заголовками и будет.
    Там я заготовил одну из них. В coulmnCount возвращение 0 это пока дефолтно.

      Evgenii Legotckoi
      • 25 октября 2019 г. 6:43

      Вместо вектора векторов лучше использовать класс или структуру. Или лучше я говорил интерфейсный класс или базовый абстрактный класс. В большинстве случае можно и без шаблона обойтись.

      Полагаю, что undefined reference относится скорее к проблеме внутри main функции, полный текст кода хотелось бы видеть.

      Либо проблема может быть в том, что шаблоны и Q_OBJECT не совместимы. То есть либо пишется шаблонная модель, либо модель с макросом Q_OBJECT.
      Либо можно написать шаблонную модель, от которой наследуется конкретная реализация с Q_OBJECT. Такое тоже работает. Но одновременно в одном классе нет. Тоже самое и где-то в документации написано.

      А конкретно для QML отсутствие макроса Q_OBJECT может быть критично, поскольку не создаётся правильная метаинформация.

      Это лишь мысли, проверять нужно. Но скорее всего так. Лучше уже полиморфизм, чем шаблоны в данном случае.

        BlinCT
        • 25 октября 2019 г. 12:36

        Ты бы мог простой набросок скинуть как бы выглядела реализация с таким интерфейсом для разного рода контейнеров со структурами и как бы они определялись в модели для заполнения таблицы?

          Evgenii Legotckoi
          • 25 октября 2019 г. 13:45

          Вот пример класса интерфейса и класса потомка

          #ifndef MODELOBJECT_H
          #define MODELOBJECT_H
          
          #include <QVariant>
          
          class IModelObject
          {
          public:
              virtual ~IModelObject() {};
              virtual QVariant getMainInfo() const = 0;
              virtual QString getName() const = 0;
              virtual QVariant getValue() const = 0;
          };
          
          class IntModelObject : public IModelObject
          {
          public:
              IntModelObject() : IModelObject() {}
              virtual ~IntModelObject() {}
          
              virtual QVariant getMainInfo() const override { return QString("IntModelObject %1 %2").arg(m_name).arg(m_value); }
              virtual QString getName() const override { return QString("IntModelObject %1").arg(m_name); }
              virtual QVariant getValue() const override { return m_value; }
          
          private:
              int m_value;
              QString m_name;
          };
          
          #endif // MODELOBJECT_H
          

          Можешь наследоваться от интефейса и определять стандартизированное поведение, например у тебя есть методы:

          • получения основной информации
          • получения имени
          • получения значения в виде QVariant

          А дальше внутри модели хранишь только вектор указатель на интерфейс

          QVector<IModelObject*> m_objects;
          

          Дальше в модель загружаешь через какой-нибудь метод указатели на любые объекты, классы которых наследованы от интерфейса.

          А внутри модели уже крутишь всё как хочешь. Смысл тот же, что у тебя и есть.

          Если же тебе нужно совсем различное поведение в разных таблицах, то имеешь одну базовую таблицу, наследуешься от неё, и переопределяешь только то, что тебе нужно.

            BlinCT
            • 25 октября 2019 г. 14:29

            Так, тут в принципе немного ясно становится. Но наследование от QAbstractTableModel идет также на IntModelObject и других потомкой что будут работать со своим типом структур?

              BlinCT
              • 25 октября 2019 г. 15:11

              Все, по поводу модели понял.

                BlinCT
                • 26 октября 2019 г. 7:54

                Хотел уточнить с тем что я написал и правильно ли понял:

                #pragma once
                
                #include <QVariant>
                
                class IModelObject
                {
                public:
                    virtual ~IModelObject() = default;
                    virtual QVariant getMainInfo() const = 0;
                    virtual QVariant getName() const = 0;
                    virtual QVariant getValue() const = 0;
                };
                
                /////////////////////////////
                
                #pragma once
                
                #include "IModelObject.hpp"
                
                class SupPowerStatesModelObject : public IModelObject
                {
                public:
                    explicit SupPowerStatesModelObject();   // как понимаю туда в конструктор должна прилетать уже готовая структура которая потом станет таблицей
                    ~SupPowerStatesModelObject() override = default;
                
                    QVariant getMainInfo() const override;
                
                    QVariant getName() const override;
                
                    QVariant getValue() const override;
                };
                
                ///////////////////////////////////
                
                #pragma once
                
                #include <QtCore/QAbstractTableModel>
                #include <sources/structs/wrappers/nvme/Tables.hpp>
                #include "IModelObject.hpp"
                
                class TableModel : public QAbstractTableModel
                {
                public:
                    explicit TableModel();
                
                    [[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;
                
                    void setObject(IModelObject* object) const; // метод через который сюда передаются обьекты со структурами
                
                private:
                    int m_rowCount;
                    int m_columnCount;
                
                    QVector<IModelObject* > m_object;
                };
                

                Правильно ли все в этой реализации и коменты что я подписал?

                И вот так уже я в main.cpp передаю один из обьектов с данными

                    SupPowerStatesModelObject sub;
                    auto tableModel = new TableModel();
                    tableModel->setObject(sub);
                
                  Evgenii Legotckoi
                  • 26 октября 2019 г. 14:03

                  Если в конструктор передавать какую-то структуру, которую должен поддерживать тот класс, то в принципе да. в общем-то правильно будет. Конкретная реализация уже покажет ошибки в процессе.

                  Что касается метода setObject, то здесь его лучше переименовать в addObject. Поскольку перевоначальное наименование не отражает сути метода. Ты добавляешь объекты, и их может быть много в этой модели. Тогда как setObject априори подразумевает только один объект, который будет находится в классе, в который добавляется данный объект. Ну и совсем явная ошибка, это наличие модификатора const у метода setObject. Данный метод модифицирует состояние модели данных, а значит никак не может быть константным.

                    BlinCT
                    • 26 октября 2019 г. 14:53

                    Спасибо, вроде немного стало более ясно. С ошибкой тоже.
                    Получается что

                    void setObject(IModelObject* object);
                    

                    получая обьект уже определяет что это за обьект из наследников и уже у модели внутри что то с каждым делает?

                      Evgenii Legotckoi
                      • 26 октября 2019 г. 15:08

                      Внутри он просто закидывает в вектор этот объект, и всё

                      void aadObject(IModelObject* object)
                      {
                          m_objects.push_back(object);
                      }
                      

                      Дальше в методах модели просто вызываешь методы, которые созданы в абстрактном классе IModelObject.
                      Твоя задача определить рееализацию в классах, которые наследованы от IModelObject. Это класс является интерфейсом.
                      Он формирует унифицированный интерфейс, а задача остальных классов наследников реализовать эти интерфейсы.
                      Если сможешь унифицировать поведение тех различных структур, то сможешь обобщить большую часть и использовать меньшее число моделей, чем по модели на каждый вид структуры

                        BlinCT
                        • 26 октября 2019 г. 15:12

                        Хорошо, понял.
                        Вообще разница тех контейнеров что несут в себе структуры только в том что разное колличество столбцов, строк, названий столбцой. Ну и данные само собою.

                          Evgenii Legotckoi
                          • 26 октября 2019 г. 15:16
                          • (ред.)

                          Количество строк роли не играет, поскольку это всего лишь размер контейнера.
                          А вот количество столбцов - это более сложный вопрос.
                          Из-за разного количества столбцов скорее всего придётся делать наследованные модели и расширять поведение. Одним унифицированным интерфейсом не обойтись.

                            Комментарии

                            Только авторизованные пользователи могут публиковать комментарии.
                            Пожалуйста, авторизуйтесь или зарегистрируйтесь
                            AD

                            C++ - Тест 004. Указатели, Массивы и Циклы

                            • Результат:50баллов,
                            • Очки рейтинга-4
                            m
                            • molni99
                            • 26 октября 2024 г. 1:37

                            C++ - Тест 004. Указатели, Массивы и Циклы

                            • Результат:80баллов,
                            • Очки рейтинга4
                            m
                            • molni99
                            • 26 октября 2024 г. 1:29

                            C++ - Тест 004. Указатели, Массивы и Циклы

                            • Результат:20баллов,
                            • Очки рейтинга-10
                            Последние комментарии
                            i
                            innorwall14 ноября 2024 г. 21:26
                            Qt/C++ - Урок 031. QCustomPlot - строим график по времени buy generic priligy We can just chat, and we will not lose too much time anyway
                            i
                            innorwall14 ноября 2024 г. 19:03
                            Qt/C++ - Урок 060. Настройка внешнего вида приложения в рантайме I didnt have an issue work colors priligy dapoxetine 60mg revia cost uk August 3, 2022 Reply
                            i
                            innorwall14 ноября 2024 г. 11:42
                            Как Копировать Файлы в Linux If only females relatives with DZ offspring were considered these percentages were 23 order priligy online uk
                            i
                            innorwall14 ноября 2024 г. 9:09
                            Qt/C++ - Урок 068. Hello World с использованием системы сборки CMAKE в CLion ditropan pristiq dosing With the Yankees leading, 4 3, Rivera jogged in from the bullpen to a standing ovation as he prepared for his final appearance in Chicago buy priligy pakistan
                            Сейчас обсуждают на форуме
                            i
                            innorwall14 ноября 2024 г. 3:39
                            добавить qlineseries в функции priligy amazon canada 93 GREB1 protein GREB1 AB011147 6
                            i
                            innorwall11 ноября 2024 г. 10:55
                            Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
                            9
                            9Anonim25 октября 2024 г. 9:10
                            Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
                            ИМ
                            Игорь Максимов3 октября 2024 г. 4:05
                            Реализация навигации по разделам Спасибо Евгений!

                            Следите за нами в социальных сетях