/
mapmanager.cpp
166 lines (124 loc) · 5.19 KB
/
mapmanager.cpp
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
#include "mapmanager.h"
#include "robotmanager.h"
#include <iostream>
#include <QQmlContext>
#include <QThread>
#include <QApplication>
#include <QPixmap>
#include <QLabel>
#include <QVBoxLayout>
#include <QScrollArea>
// Grandezza della schermata
const int MapManager::WIDTH = 800;
const int MapManager::HEIGHT = 600;
MapManager::MapManager(QObject *parent) :
QObject(parent)
{
}
/**
* @brief MapManager::init si occupa di inizializzare il thread che controlla il robot e di fare il setup della GUI
*/
void MapManager::init()
{
// Creo il thread del robot
setupRobotManagerThread();
// Adesso creo la view QML
QQuickView view;
QQmlContext* rootContext = view.rootContext();
// Espongo al modulo QML questa classe, in modo che possa connettere i suoi signal
rootContext->setContextProperty("window", this);
// Inserisco come proprietà QML delle costanti che corrispondono alla grandezza della finestra
rootContext->setContextProperty("WINDOW_WIDTH", WIDTH);
rootContext->setContextProperty("WINDOW_HEIGHT", HEIGHT);
//Carico il file base
view.setSource(QStringLiteral("main.qml"));
// Finito con i setaggi, mostro la finestra
view.show();
// Creo il widget che mostra le immagini della camera del robot durante la rircerca
QWidget cameraWidget;
QHBoxLayout *hbox = new QHBoxLayout(&cameraWidget);
// Aggiungo alla horizontal box la QLabel che conterrà le immagini della camera
hbox->addWidget(&cameraLabel);
cameraWidget.show();
// Creo il widget che mostra le vittime trovate
QWidget victimsFoundWidget;
QScrollArea *scrollArea = new QScrollArea();
layout = new QVBoxLayout(&victimsFoundWidget);
// setto le proprietà della ScrollArea e la mostro
scrollArea->setWidget(&victimsFoundWidget);
scrollArea->setWidgetResizable(true);
scrollArea->setMinimumWidth(260);
scrollArea->setMinimumHeight(300);
scrollArea->show();
// Avvio il loop della GUI
QApplication::instance()->exec();
}
/**
* @brief MapManager::setupRobotManagerThread esegue il setup del thread su cui gira la parte di controllo del robot
*/
void MapManager::setupRobotManagerThread()
{
//Creo l'istanza del thread secondario
// QThread* robotManagerThread = new QThread(this);
robotManagerThread = new QThread(this);
// Sposto l'oggetto che controlla il robot nell'altro thread
robotManager.moveToThread(robotManagerThread);
//Connetto il signal che dichiara l'inizio dell'esecuzione del thread con lo slot che si occupa dell'inizializzazione della classe
QObject::connect(robotManagerThread, SIGNAL(started()), &robotManager, SLOT(init()));
// Connetto i signal della classe del robot a quelli della GUI, in modo da poterli usare da QML
QObject::connect(&robotManager, SIGNAL(pointFound(QVariant,QVariant)), this, SIGNAL(pointFound(QVariant,QVariant)));
QObject::connect(&robotManager, SIGNAL(victimFound(QVariant)), this, SIGNAL(victimFound(QVariant)));
QObject::connect(&robotManager, SIGNAL(robotTurn(QVariant)), this, SIGNAL(robotTurn(QVariant)));
QObject::connect(&robotManager, SIGNAL(generateStep()), this, SIGNAL(generateStep()));
// Dato che uso signal che passano paremtri Mat di opencv, devo esplori al meta system delle Qt
qRegisterMetaType< cv::Mat >("cv::Mat");
// Connetto i signal che inviano immagini da mostrare ai rispettivi slot
QObject::connect(&robotManager, SIGNAL(newCameraImage(cv::Mat)), this, SLOT(printImage(cv::Mat)));
QObject::connect(&robotManager, SIGNAL(victimImageFound(cv::Mat)), this, SLOT(printVictimImage(cv::Mat)));
// Segnalo di terminare il thread alla chiusura della GUI (anche se non sembra far nulla)
QObject::connect(this, SIGNAL(destroyed()), robotManagerThread, SLOT(quit()));
// Avvio il thread
robotManagerThread->start();
}
/**
* @brief MapManager::printImage slot chiamato quando il robot invia immagini della camera da mostrare
* @param cvImage l'immagine da mostrare
*/
void MapManager::printImage(cv::Mat cvImage)
{
// Converto l'immagine da Mat a QImage
QImage image = Mat2QImage(cvImage);
// Setto l'immagine e aggiorno la grandezza della finestra
cameraLabel.setPixmap(QPixmap::fromImage((image)));
cameraLabel.adjustSize();
}
/**
* @brief MapManager::printVictimImage slot chiamato quando il robot trova una vittima
* @param cvImage l'immagine da mostrare
*/
void MapManager::printVictimImage(cv::Mat cvImage)
{
QImage image = Mat2QImage(cvImage);
QLabel *victimImage = new QLabel();
victimImage->setPixmap(QPixmap::fromImage((image)));
victimImage->adjustSize();
layout->addWidget(victimImage);
}
/**
* @brief MapManager::Mat2QImage converte immagini da Mat a QImage (funzione trovata online su stackoverflow)
* @param src l'immagine
* @return l'immagine convertita
*/
QImage MapManager::Mat2QImage(const cv::Mat3b &src)
{
QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
for (int y = 0; y < src.rows; ++y)
{
const cv::Vec3b *srcrow = src[y];
QRgb *destrow = (QRgb*)dest.scanLine(y);
for (int x = 0; x < src.cols; ++x) {
destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255);
}
}
return dest;
}