Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. Form Qml e classe in c++
QtWS25 Last Chance

Form Qml e classe in c++

Scheduled Pinned Locked Moved Solved Italian
21 Posts 3 Posters 6.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    GiGa91
    wrote on last edited by
    #11

    Ah giusto non ci avevo pensato.

    Per quanto riguarda l'errore, me lo da a causa del fatto che gli sto dando "players". Precisamente questo:

    error: no matching function for call to ‘QAbstractItemModel::setData(QModelIndex, Player)’
    m_model->setData(m_model->index(newRow,0),Player(nick,name,surname));
    no known conversion for argument 2 from ‘Player’ to ‘const QVariant&’
    ^

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #12

      Giusto, sto dormendo.
      m_model->setData(m_model->index(newRow,0),QVariant::fromValue(Player(nick,name,surname)));

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      0
      • G Offline
        G Offline
        GiGa91
        wrote on last edited by
        #13

        Quasi tutto chiaro.. mi manca un passaggio solo.

        Avendo esportato la classe verso qml:

        Game game;
        engine.rootContext()->setContextProperty("Game", &game);
        

        ho a disposizione i metodi addPlayer e removePlayer che posso usare in modo molto semplice:

        onClicked: Game.addPlayer(qsTr(text_input_name.text), qsTr(text_input_surname.text), qsTr(text_input_nick.text))
        

        tramite la property io dovrei poter leggere il modello su Qml

        Q_PROPERTY(QAbstractItemModel* model READ model)
        

        Pero non riesco. Ad esempio:

        Button {
                    text: "Add"
                    onClicked: {
                        Game.addPlayer(qsTr(text_input_name.text), qsTr(text_input_surname.text), qsTr(text_input_nick.text))
                    }
                }
        
                Button {
                    text: "Rem"
                    onClicked: Game.removePlayer(index)
                }
        
        
        
                ListView {
                    id: listView
                    Layout.fillWidth: true
                    model: Game.model
                    delegate: listDelegate
                }
                Component {
                    id: listDelegate
                    Text {
                        id: name_text
                        text: Game.model.data(0,1)
                    }
                }
        
        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #14
          • qsTr non funziona cosi'. Puo' solo tradurre costanti e, comunque, non vedo il punto di tradurre un nome proprio
          • Il problema e' nel delegate text: Game.model.data(0,1) non funziona cosi'. E' un po' che non uso QML ma se ricordo bene era role.property quindi nel tuo caso qualcosa tipo text: display.nick + " - " + display.name + " " + display.surname

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          0
          • G Offline
            G Offline
            GiGa91
            wrote on last edited by
            #15

            ops ho sbagliato a ricopiare. Questo non centra nulla:

            text: Game.model.data(0,1)
            

            Il punto che non capisco è proprio questo. Per esempio ti riporto un codice di esempio di Qml:

            ListModel {
                id: nameModel
                ListElement { name: "Alice"; team: "Crypto" }
                ListElement { name: "Bob"; team: "Crypto" }
                ListElement { name: "Jane"; team: "QA" }
                ListElement { name: "Victor"; team: "QA" }
                ListElement { name: "Wendy"; team: "Graphics" }
            }
            Component {
                id: nameDelegate
                Text {
                    text: name;
                    font.pixelSize: 24
                    anchors.left: parent.left
                    anchors.leftMargin: 2
                }
            }
            

            Nel delegate dovrebbe bastare mettere "name" e in modo trasparente dovrebbe vedermi la propieta di ListElement (nel caso dell'esempio)
            Usando la Q_PROPERTY sbaglio a pensare di ottenere la stessa cosa verso il modello Game?

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #16

              esatto, name in quel caso e' il role in cui salvi "Alice".
              Quando chiami m_model->setData in realta' i parametri sono 3: indice della cella da cambiare, valore da inserire e role del valore. Siccome noi non mettiamo nulla nel terzo parametro il default e' Qt::EditRole
              In QML non usi Qt::EditRole ma il nome corrispondente (qui trovi la lista dei nomi per i role standard).
              Io uso display invece di edit perche' in QStandardItemModel display e edit sono la stessa cosa (ma questo e' un dettaglio irrilevante)
              Ora display ritorna una QVariant che contiene un Player. Puoi usare . per accedere alle sue proprieta' quindi display.nick (o edit.nick se preferisci)

              quindi:

              Component {
                  id: nameDelegate
                  Text {
                      text: edit.nick
                      font.pixelSize: 24
                      anchors.left: parent.left
                      anchors.leftMargin: 2
                  }
              }
              

              dovrebbe funzionare

              Edit:
              set ti piace di piu' puoi anche modificare il costruttore di Game cosi':

              Game(QObject* parent = nullptr) :QObject(parent){
              m_model=new QStandardItemModel(this);
              m_model->inserColumn(0);
              QHash<int, QByteArray> roleNames = m_model->roleNames();
              roleNames.insert(Qt::UserRole,"player");
              static_cast<QStandardItemModel*>(m_model)->setItemRoleNames(roleNames);
              }
              

              e quando chiami setData aggiungi il terzo parametro: m_model->setData(m_model->index(newRow,0),QVariant::fromValue(Player(nick,name,surname)),Qt::UserRole);

              adesso in QML puoi fare:

              Component {
                  id: nameDelegate
                  Text {
                      text: player.nick
                      font.pixelSize: 24
                      anchors.left: parent.left
                      anchors.leftMargin: 2
                  }
              }
              

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              0
              • G Offline
                G Offline
                GiGa91
                wrote on last edited by
                #17

                Ti riporto l'errore che sicuramente spiega meglio cio che vorrei dirti:

                ReferenceError: edit is not defined
                

                Lo stesso valeva per display

                1 Reply Last reply
                0
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by VRonin
                  #18

                  Strano perche' ha funzionato per me. Avevo praticamente la stessa tua domanda: https://forum.qt.io/topic/71433/best-practice-to-add-dynamic-qml-from-c-data/12

                  Probabilmente devi solo aggiungere Q_DECLARE_METATYPE(Player) in player.h e qmlRegisterType<Player>("com.game", 1, 0, "Player"); nella main()

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    GiGa91
                    wrote on last edited by GiGa91
                    #19

                    Perdona la mia ignoranza, ma io posso esportare la classe player tramite qmlRegistrerType? Non è definita come public Qobject e se devo essere sincero ci avevo gia provato ma ottenevo/ottengo questo errore:

                     error: cannot convert ‘QQmlPrivate::QQmlElement<Player>*’ to ‘QObject*’ for argument ‘1’ to ‘void QQmlPrivate::qdeclarativeelement_destructor(QObject*)’
                                 QQmlPrivate::qdeclarativeelement_destructor(this);
                                                                            ^
                    

                    Ho aggiunto Q_DECLARE_METATYPE(Player) in players.h

                    Considerando che a te il codice funzione e la probabilità che io abbia dimenticato qualcosa è alta riporto i miei quattro file:

                    main.cpp

                    #include <QGuiApplication>
                    #include <QQmlApplicationEngine>
                    #include <QQmlContext>
                    #include <QtQml>
                    
                    #include "Classe_Game/Game.h"
                    #include "Classe_Players/Players.h"
                    
                    int main(int argc, char *argv[])
                    {
                        QGuiApplication app(argc, argv);
                        //qmlRegisterType<Player>("com.helloworld.qmlcomponents",1,0,"Player");
                    
                        QQmlApplicationEngine engine;
                    
                    
                        Game game;
                        engine.rootContext()->setContextProperty("Game", &game);
                    
                        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                        if (engine.rootObjects().isEmpty())
                            return -1;
                    
                    
                        return app.exec();
                    }
                    
                    

                    Players.h

                    #ifndef PLAYERS_H
                    #define PLAYERS_H
                    #include <QObject>
                    
                    class Player
                    {
                        Q_GADGET
                    
                        Q_PROPERTY(QString nick MEMBER m_nick)
                        Q_PROPERTY(QString name MEMBER m_name)
                        Q_PROPERTY(QString surname MEMBER m_surname)
                    public:
                        Player(const QString& nick,const QString& name ,const QString& surname)
                            :m_nick(nick),m_name(name),m_surname(surname){}
                        Player() = default;
                        Player(const Player& other)=default;
                        Player& operator=(const Player& other)=default;
                        QString m_nick;
                        QString m_name;
                        QString m_surname;
                    };
                    Q_DECLARE_METATYPE(Player)
                    #endif // PLAYERS_H
                    

                    Game.h

                    #ifndef GAME_H
                    #define GAME_H
                    #include <QStandardItemModel>
                    #include <QList>
                    
                    #include "Classe_Players/Players.h"
                    
                    class Game : public QObject{
                        Q_OBJECT
                        Q_PROPERTY(QAbstractItemModel* model READ model)
                        Q_PROPERTY(ModeGame modeGame READ modeGame WRITE setModeGame NOTIFY modeGameChanged)
                        Q_DISABLE_COPY(Game)
                    public:
                        enum ModeGame{NS, Static, Projector};
                        Q_ENUM(ModeGame)
                    
                        Game(QObject* parent = nullptr) :QObject(parent){
                        m_model=new QStandardItemModel(this);
                        m_model->insertColumn(0);
                        QHash<int, QByteArray> roleNames = m_model->roleNames();
                        roleNames.insert(Qt::UserRole,"player");
                        static_cast<QStandardItemModel*>(m_model)->setItemRoleNames(roleNames);
                        }
                    
                        Q_SLOT void addPlayer(const QString& nick,const QString& name ,const QString& surname){
                            const int newRow = m_model->rowCount();
                            m_model->insertRow(newRow);
                            m_model->setData(m_model->index(newRow,0),QVariant::fromValue(Player(nick,name,surname)),Qt::UserRole);
                        }
                    
                        Q_SLOT void removePlayer(int index){
                            m_model->removeRow(index);
                        }
                    
                        QAbstractItemModel* model() const {
                            return m_model;
                        }
                    
                        Q_SIGNAL void modeGameChanged(ModeGame modegame);
                    
                        void setModeGame(ModeGame modegame){
                            if(m_modegame==modegame) return;
                            m_modegame=modegame;
                            modeGameChanged(modegame);
                        }
                        ModeGame modeGame() const{return m_modegame;}
                    private:
                        QAbstractItemModel* m_model;
                        ModeGame m_modegame;
                    };
                    #endif // GAME_H
                    
                    

                    main.qml

                    import QtQuick 2.10
                    import QtQuick.Window 2.10
                    import QtQuick.Layouts 1.3
                    import QtQuick.Controls 1.4
                    
                    Window {
                        visible: true
                        width: 640
                        height: 480
                        title: qsTr("Hello World")
                    
                    
                        ColumnLayout {
                            id: rowLayout
                            objectName: "rowLayout"
                            anchors.fill: parent
                    
                            TextInput {
                                id: text_input_name
                                color: "red"
                                text: "name"
                                Layout.fillWidth: true
                                focus: true
                            }
                    
                            TextInput {
                                id: text_input_surname
                                color: "red"
                                text: "surname"
                                Layout.fillWidth: true
                                focus: true
                            }
                    
                            TextInput {
                                id: text_input_nick
                                color: "red"
                                text: "nick"
                                Layout.fillWidth: true
                                focus: true
                            }
                    
                    
                            Button {
                                text: "Add"
                                onClicked: {
                                    Game.addPlayer(text_input_name.text, text_input_surname.text, text_input_nick.text)
                                }
                            }
                    
                            Button {
                                text: "Rem"
                                //onClicked: Game.removePlayer(index)
                            }
                    
                    
                    
                            ListView {
                                width: 200; height: 250
                    
                                model: Game
                                delegate: Text {
                                    text: players.name
                                }
                            }
                        }
                    }
                    
                    
                    1 Reply Last reply
                    0
                    • VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by VRonin
                      #20

                      @GiGa91 said in Form Qml e classe in c++:

                      model: Game

                      il modello non e' Game, e' Game.model

                      text: players.name

                      il role non e' players, e' player

                      Game.addPlayer(text_input_name.text, text_input_surname.text, text_input_nick.text)

                      Hai sbagliato l'ordine degli argomenti: Game.addPlayer(text_input_nick.text, text_input_name.text, text_input_surname.text)

                      Q_DECLARE_METATYPE(Player)

                      Non e' necessario, Q_GADGET fa gia' tutto

                      //onClicked: Game.removePlayer(index)

                      devi dare un id a ListView (per esepio id: playerView) e poi fare onClicked: Game.removePlayer(playerView.currentIndex)

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      0
                      • G Offline
                        G Offline
                        GiGa91
                        wrote on last edited by
                        #21

                        Era superscontato che commettevo errori. Adesso funziona perfettamente.
                        Infinitamente grazie per la pazienza che hai avuto

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved