2D Game Grid Model from C++ to QML



  • Hello guys, I'm fairly new to Qt/QML and currently try to create a little Snake game. For this, I implemented a C++ model of a game board which has a two-dimensional array containing the states of the respective cell (empty, snake, fruit). I'd like to practice exposing custom models from C++ to QML, please bear that in mind in your answers (as in please no QML-only answers), thank you. ;-)

    The best approach to me seemed to have my game board class subclass QAbstractTableModel, which I did as best as I could.
    My problem now is the next step when it comes to using it in QML. So far I only found examples using role names - but the cells of a row don't have role names, just a state. Also I've seen examples that use a QML TableView with handwritten TableColumns added - but I want QML to display how many columns ever my model has.

    Here is my code so far:

    board.h

    #pragma once
    
    #include <vector>
    
    #include <QAbstractTableModel>
    
    class board : public QAbstractTableModel
    {
      Q_OBJECT
    
    public:
      enum class state
      {
        empty,
        snake,
        fruit
      };
    
      board(int width, int height);
    
      state get_state(int x, int y) const;
      void  set_state(int x, int y, state state);
    
      int rowCount(const QModelIndex& parent = QModelIndex()) const;
      int columnCount(const QModelIndex& parent = QModelIndex()) const;
      QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
    
    private:
      std::vector<std::vector<state>> m_board;
    };
    
    Q_DECLARE_METATYPE(board::state)
    

    board.cpp

    #include "board.h"
    
    board::board(int width, int height) :
      m_board(width, std::vector<state>(height, state::empty))
    {
    }
    
    board::state board::get_state(int x, int y) const
    {
      return m_board.at(x).at(y);
    }
    
    void board::set_state(int x, int y, board::state state)
    {
      m_board.at(x).at(y) = state;
    }
    
    int board::rowCount(const QModelIndex&) const
    {
      return m_board.size();
    }
    
    int board::columnCount(const QModelIndex&) const
    {
      return m_board.at(0).size();
    }
    
    QVariant board::data(const QModelIndex& index, int role) const
    {
      if(!index.isValid())
        return QVariant();
    
      if(role != Qt::DisplayRole)
        return QVariant();
    
      return qVariantFromValue(get_state(index.row(), index.column()));
    }
    
    

    I haven't written anything in QML, yet. Am I on the right path? What would I need to do in QML?

    Thanks a lot!


  • Moderators

    @DenverCoder21

    So far I only found examples using role names - but the cells of a row don't have role names, just a state

    If they dont then there's no way to get data from model to the view. The view will look completely blank.
    Well honestly I cant tell if this is the best idea to use a model. May be you have already thought of the updating the model for eg. how to update each cell when the snake moves.

    Btw. did you look at this Snake game ? Sorry it's QML-only ;). But you can try to fit the logic into model.



  • I found a solution, please see my own answer in here.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.