Как выбрать ячейку из QGraphicView щелчком мыши и запустить мой алгоритм с этой точки?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как выбрать ячейку из QGraphicView щелчком мыши и запустить мой алгоритм с этой точки?

Сообщение Anonymous »

Я написал реализацию алгоритма Прима, который создает лабиринт в QT (использовал C++, QGraphicView + QGraphicScene, мой лабиринт представляет собой матрицу 0 и 1), и следующим шагом моего проекта является - пользователь может щелкнуть любую ячейку лабиринта и выбрать начало и конец для алгоритмов поиска проходов.
Изображение

У кого-нибудь есть идеи реализации установки позиций начала/финиша с помощью мыши?
мой код создания лабиринта -
#include "mazegenerator.h"

#include
#include

#include
#include
#include
#include

Mazegenerator::Mazegenerator(Maze *maze,QObject* parent):QObject(parent)
{
m_maze = maze;
}

void Mazegenerator::primsAlgorithm()
{
std::vector borders; // масив крайових клітин
std::vector passes; // масив клітин-проходів

// лямда для пошуку та занесення крайових клітин в вектор borders
// лямда виконує такі дії:
// 1. Перевіряє чи координати точки не виходять за межі лабіринту
// 2. Перевіряє чи координати точки не є межами(кордонами) лабіринту
// 3. Перевіряє унікальність даної точки для уникнення повторного занесення
// 4. Якщо умови пройдені - додає координати точки до borders
auto isBorder = [this,&borders](int x,int y)
{
if(x+2 > 0 && x+2 < m_maze->getColumns()-1 && y > 0 && y < m_maze->getRows()-1 && m_maze->getValue(x+2,y) == 1)
{

bool alreadyExists = false;
for(int i = 0; i < borders.size(); i++)
{
if(borders.first == x+2 && borders.second == y)
{
alreadyExists = true;
break;
}
}

if(!alreadyExists)
{
borders.push_back({x+2,y});
emit cellChanged(x+2,y,2);
}

}
if(x-2 > 0 && x-2 < m_maze->getColumns()-1 && y >0 && y < m_maze->getRows()-1 && m_maze->getValue(x-2,y) == 1)
{

bool alreadyExists = false;
for(int i = 0; i < borders.size(); i++)
{
if(borders.first == x-2 && borders.second == y)
{
alreadyExists = true;
break;
}
}

if(!alreadyExists)
{
borders.push_back({x-2,y});
emit cellChanged(x-2,y,2);
}

}
if( x > 0 && x < m_maze->getColumns()-1 && y+2 > 0 && y+2 < m_maze->getRows()-1 && m_maze->getValue(x,y+2) == 1)
{

bool alreadyExists = false;
for(int i = 0; i < borders.size(); i++)
{
if(borders.first == x && borders.second == y+2)
{
alreadyExists = true;
break;
}
}

if(!alreadyExists)
{
borders.push_back({x,y+2});
emit cellChanged(x,y+2,2);
}

}

if(x > 0 && x < m_maze->getColumns()-1 && y-2 >0 && y-2 < m_maze->getRows()-1 && m_maze->getValue(x,y-2) == 1)
{
if(x == 0 || x == m_maze->getColumns() - 1 || y-2 == 0 || y-2 == m_maze->getRows() - 1)
{
// нічого не робимо — це край
}
else
{
bool alreadyExists = false;
for (int i = 0; i < borders.size(); i++)
{
if (borders.first == x && borders.second == y-2)
{
alreadyExists = true;
break;
}
}

if(!alreadyExists)
{
borders.push_back({x,y-2});
emit cellChanged(x,y-2,2);
}
}

}
};

// лямда для пошуку та занесення клітин-проходів в вектор borders
// лямда виконує такі дії:
// 1. Перевіряє чи координати точки не виходять за межі лабіринту
// 2. Якщо умови пройдені - додає координати точки до passes

auto isPass = [this,&passes](int x,int y)
{
if( x+2 < m_maze->getColumns() && y >=0 && y < m_maze->getRows() && m_maze->getValue(x+2,y) == 0)
{
passes.push_back({x+2,y});
}
if( x-2>=0 && x-2 < m_maze->getColumns() && y >=0 && y < m_maze->getRows() && m_maze->getValue(x-2,y) == 0)
{
passes.push_back({x-2,y});
}
if( x >= 0 && x < m_maze->getColumns() && y+2 < m_maze->getRows() && m_maze->getValue(x,y+2) == 0)
{
passes.push_back({x,y+2});
}
if( x >= 0 && x < m_maze->getColumns() && y-2 >=0 && y-2 < m_maze->getRows() && m_maze->getValue(x,y-2) == 0)
{
passes.push_back({x,y-2});
}
};

// 1.Генеруємо випадкову не парну клітинку і перетворюємо її на прохід
QRandomGenerator generator;
int x = generator.bounded(1,(m_maze->getColumns()-2) );
if(x % 2 == 0)
{
x -= 1;
}
int y = generator.bounded(1,(m_maze->getRows()-2) );
if(y % 2 == 0)
{
y -= 1;
}
m_maze->setValue(x,y,0);
emit cellChanged(x,y,0);
// 2. Шукаємо крайові клітинки і заносимо їх до вектора borders
isBorder(x,y);

while(borders.size() != 0)
{
int randBord = generator.bounded(0,static_cast(borders.size()));
int xBord = borders[randBord].first;
int yBord = borders[randBord].second;
borders.erase(borders.begin() + randBord);
m_maze->setValue(xBord,yBord,0);
emit cellChanged(xBord,yBord,0);
isBorder(xBord,yBord);

isPass(xBord,yBord);

bool ok = true;
if (!passes.empty())
{
while(ok)
{
int randPas = generator.bounded(0,static_cast(passes.size()) );
if( (passes[randPas].first + xBord)%2 == 0 && (passes[randPas].second + yBord)%2 == 0)
{
int betweenX = (passes[randPas].first + xBord)/2;
int betweenY = (passes[randPas].second + yBord)/2;

m_maze->setValue(betweenX,betweenY,0);
emit cellChanged(betweenX,betweenY,0);
ok = false;
break;
}

}
}
passes.clear();
}
}

  • функция инициализации и раскраски прямоугольника:

void Mazerenderer::mazeInitalization(int rows, int columns)
{
for(int y = 0; y < rows; y++)
{
for(int x = 0; x < columns; x++)
{

auto* item = m_scene->addRect(x * m_cellSize , y * m_cellSize, m_cellSize, m_cellSize, QPen(Qt::darkYellow), QBrush(wallColor));
rec_matrix[y][x] = item;
}
}
}
void Mazerenderer::changeCell(int x, int y, int signal)// responds to a signal from Mazegenerator::primsAlgorithm()
{
if(signal == 0)
{
rec_matrix[x][y]->setBrush(QBrush(passColor));
}
else if(signal == 2)
{
rec_matrix[x][y]->setBrush(QBrush(borderColor));
}
}



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

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

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

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

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

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