Bonjour à tous,

Je dois charger une liste d'item personnalisé à partir d'un fichier côté C++. Chaque élément sera contenu dans une struct ou une class peu importe et ceux-ci seront conservé dans une collection.

Donc, pour l'exemple j'ai utilisé une class (MenuButtonInfo) qui est l'item et MenuButtonList qui est la collection contenant les éléments.

Cette liste devra servir de data modèle pour un élément QML.

Voici ce que j'ai jusqu'ici :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
 
class MenuButtonInfo
{
public:
    explicit MenuButtonInfo()
        : m_Name("")
        , m_Text("")
    {}
 
    MenuButtonInfo(const QString& name, const QString& text)
        : m_Name(name)
        , m_Text(text)
    {}
 
    QString name()
    {
        return m_Name;
    }
 
    QString text()
    {
        return m_Text;
    }
 
private:
    QString  m_Name;
    QString  m_Text;
};
Q_DECLARE_METATYPE(MenuButtonInfo)
 
 
class MenuButtonList : public QAbstractListModel
{
    Q_OBJECT
 
public:
    explicit MenuButtonList(QObject *parent = 0)
        : QAbstractListModel(parent)
    {}
 
    MenuButtonList(const QList<MenuButtonInfo>& menuButtonList, QObject *parent = 0)
        : QAbstractListModel(parent), m_MenuButtonList(menuButtonList)
    {}
 
    MenuButtonList(const MenuButtonList& copy)
    {
        m_MenuButtonList = QList<MenuButtonInfo>(copy.m_MenuButtonList);
    }
 
    int rowCount(const QModelIndex &parent = QModelIndex()) const
    {
        Q_UNUSED(parent)
        return m_MenuButtonList.count();
    }
 
    QVariant data(const QModelIndex &index, int role) const
    {
        if (index.isValid() == false)
        {
            return QVariant();
        }
 
        if (index.row() < 0 || index.row() >= m_MenuButtonList.count())
        {
            return QVariant();
        }
 
        if (role == Qt::DisplayRole)
        {
            return QVariant().fromValue(m_MenuButtonList.at(index.row()));
        }
        else
        {
            return QVariant();
        }
    }
 
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const
    {
        if (role != Qt::DisplayRole)
        {
            return QVariant();
        }
 
        if (orientation == Qt::Horizontal)
        {
            return QString("Column %1").arg(section);
        }
        else
        {
            return QString("Row %1").arg(section);
        }
    }
 
    Qt::ItemFlags flags(const QModelIndex &index) const
    {
        if (!index.isValid())
        {
            return Qt::ItemIsEnabled;
        }
 
        return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
    }
 
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
    {
        if (index.isValid() && role == Qt::EditRole && value.canConvert<MenuButtonInfo>() == true) {
 
            m_MenuButtonList.replace(index.row(), value.value<MenuButtonInfo>());
            emit dataChanged(index, index);
            return true;
        }
 
        return false;
    }
 
    bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex())
    {
        Q_UNUSED(index)
 
        beginInsertRows(QModelIndex(), position, position + rows - 1);
 
        for (int row = 0; row < rows; ++row)
        {
            m_MenuButtonList.insert(position, MenuButtonInfo());
        }
 
        endInsertRows();
        return true;
    }
 
    bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex())
    {
        Q_UNUSED(index)
 
        beginRemoveRows(QModelIndex(), position, position+rows-1);
 
        for (int row = 0; row < rows; ++row) {
            m_MenuButtonList.removeAt(position);
        }
 
        endRemoveRows();
        return true;
    }
 
   private:
       QList<MenuButtonInfo> m_MenuButtonList;
};
Q_DECLARE_METATYPE(MenuButtonList)
 
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
 
    QList<MenuButtonInfo> list;
    for (int i = 0; i < 10; ++i)
    {
        QString sName = QString("Name %1").arg(i);
        QString sText = QString("Text %1").arg(i);
        list.append(MenuButtonInfo(sName, sText));
    }
 
    MenuButtonList menuButtonList(list);
 
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
 
    engine.rootContext()->setContextProperty("menuButtonItemModel", QVariant::fromValue(list));
 
    return app.exec();
}
Le problème c'est que j'obtiens l'erreur de compilation suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl MenuButtonList::metaObject(void)const " (?metaObject@MenuButtonList@@UEBAPEBUQMetaObject@@XZ)
main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __cdecl MenuButtonList::qt_metacast(char const *)" (?qt_metacast@MenuButtonList@@UEAAPEAXPEBD@Z)
main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __cdecl MenuButtonList::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@MenuButtonList@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
debug\QtSonarTest.exe:-1: error: LNK1120: 3 unresolved externals
Je n'arrive pas à comprendre pourquoi ?

J'avais une autre question par rapport à cette liste, j'ai vu pas mal partout que la façon de faire est de créer une liste d'abord et d'ensuite la passer en paramètre au constructeur de la classe MenuButtonList. N'y a-t-il pas moyen de tout encapsuler cela dans la MenuButtonList directement ? Donc, avoir des méthode add, insert, delete, etc... ?

Merci