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 р. 03:06
  • (відредаговано)

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

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

    BlinCT
    • 25 жовтня 2019 р. 06:33

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

      Evgenii Legotckoi
      • 25 жовтня 2019 р. 06: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 р. 07: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
                          • (відредаговано)

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

                            Коментарі

                            Only authorized users can post comments.
                            Please, Log in or Sign up
                            AD

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

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

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

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

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

                            • Результат:20бали,
                            • Рейтинг балів-10
                            Останні коментарі
                            ИМ
                            Игорь Максимов22 листопада 2024 р. 11:51
                            Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                            Evgenii Legotckoi
                            Evgenii Legotckoi31 жовтня 2024 р. 14:37
                            Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                            A
                            ALO1ZE19 жовтня 2024 р. 08:19
                            Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                            ИМ
                            Игорь Максимов05 жовтня 2024 р. 07:51
                            Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                            d
                            dblas505 липня 2024 р. 11:02
                            QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                            Тепер обговоріть на форумі
                            Evgenii Legotckoi
                            Evgenii Legotckoi24 червня 2024 р. 15:11
                            добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                            t
                            tonypeachey115 листопада 2024 р. 06:04
                            google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                            NSProject
                            NSProject04 червня 2022 р. 03:49
                            Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                            9
                            9Anonim25 жовтня 2024 р. 09:10
                            Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                            Слідкуйте за нами в соціальних мережах