QML: Как использовать пользовательскую модель с параметрами конструктора, определенными во время выполнения?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 QML: Как использовать пользовательскую модель с параметрами конструктора, определенными во время выполнения?

Сообщение Anonymous »

У меня есть настольная игра с пронумерованными плитками, расположенными в квадратной сетке. Доска использует GridView с пользовательской моделью GameBoard (GameBoardModel, экспортированной в QML), унаследованной от QAbstractListModel. В стандартной форме игра использует сетку плиток 4x4, потому что именно столько (16) плиток создает конструктор модели по умолчанию. Однако я подумал сделать что-то вроде выпадающего списка, который бы позволял выбирать размер доски, который затем будет сгенерирован и игра начнется.
Теперь проблема в том, что я не вижу очевидный способ отправить число (или вызвать функцию) из QML, который приступит к созданию модели с желаемыми параметрами, загрузит ее в QML и обновит представление.
Я пробовал создать отдельную кнопку и используя свойство dimension моей модели, чтобы установить для размера новое значение с помощью onClicked MouseArea и написать _gameboard .model.dimension = 5 (где _gameboard — это id типа GameBoard QML, который использует GameBoardModel), но я так и не смог понять, как правильно обновить свою модель. Я попытался создать своего рода метод reloadModel, который по сути создает новый список плиток с новыми номерами и который будет вызываться после каждого обновления размера, но даже после вызова dataChanged отображалось только старое количество элементов, равное 16, а не 25 (не считая одного, намеренно скрытого).
C++< /p>
part of gameboard.h

class GameBoard : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int dimension READ dimension WRITE setDimension NOTIFY dimensionChanged)
Q_PROPERTY(int hiddenElementValue READ boardSize NOTIFY hiddenElementChanged)

public:
static constexpr size_t defaultPuzzleDimension = 4;
GameBoard(QObject* parent = nullptr, const size_t boardDimension = defaultPuzzleDimension);

size_t dimension() const;
void setDimension(size_t newDimension);
size_t boardSize() const;

signals:
void dimensionChanged(const size_t newDimension);
void hiddenElementChanged(int newHiddenElementValue);

private:
std::vector m_rawBoard;
size_t m_dimension;
size_t m_boardSize;
void reloadModel();

}

part of gameboard.cpp

size_t GameBoard::dimension() const
{
return m_dimension;
}

void GameBoard::setDimension(size_t newDimension)
{
m_dimension = newDimension;
reloadModel();
emit dimensionChanged(m_dimension);
emit hiddenElementChanged(m_boardSize);
}

size_t GameBoard::boardSize() const
{
return m_boardSize;
}

void GameBoard::reloadModel()
{
m_rawBoard.clear();

m_boardSize = m_dimension * m_dimension;
m_rawBoard.resize(m_boardSize);
std::iota(m_rawBoard.begin(),m_rawBoard.end(),1);
shuffle();

dataChanged(createIndex(0,0),createIndex(m_boardSize,0));

}

QML
main.qml

import QtQuick 2.15
import QtQuick.Window 2.15

Window {
id: root
width: 680
height: 440
visible: true
title: qsTr("Hello World")

Item {
id: _firstTile
width: 0.5 * root.width
height: 0.1 * root.height
anchors.horizontalCenter: parent.horizontalCenter
Tile {
radius: 30
anchors.fill: parent
anchors.topMargin: 0.05 * parent.height
anchors.bottomMargin: 0.05 * parent.height
MouseArea {
anchors.fill: parent
onClicked: {
_gameboard.model.dimension = 5;
}
}
}
}
Item {
width: root.width
height: 0.9 * root.height
anchors.top: _firstTile.bottom
GameBoard {
id: _gameboard
anchors.fill: parent
}
}

}

GameBoard.qml

import QtQuick 2.0
import Game 1.0

GridView {
id: root
model: GameBoardModel {

}

cellHeight: height / root.model.dimension
cellWidth: width / root.model.dimension

delegate: Item {
id: _backgroundDelegate
width: root.cellWidth
height: root.cellHeight
visible: display != root.model.hiddenElementValue
Tile {
displayText: display
anchors.fill: _backgroundDelegate
anchors.margins: 3
MouseArea {
anchors.fill: parent
onClicked: {
root.model.move(index);
}
}
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/784 ... parameters
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»