search-demo 四.键盘事件和帮助、控制信息
界面部分基本完成。程序的架构实在是恶心到不行,明天从头再来。
main.cpp:
C++语言: Codee#26094
01 #include <QtGui>
02 #include <QtCore>
03 #include "pathfinding.h"
04
05 int main(int argc, char *argv[])
06 {
07 QApplication a(argc, argv);
08 Widget* window=new Widget;
09
10 QRect frect = window->frameGeometry();
11 frect.moveCenter(QDesktopWidget().availableGeometry().center());
12 window->move(frect.topLeft());
13 window->show();
14
15 return a.exec();
16 }
02 #include <QtCore>
03 #include "pathfinding.h"
04
05 int main(int argc, char *argv[])
06 {
07 QApplication a(argc, argv);
08 Widget* window=new Widget;
09
10 QRect frect = window->frameGeometry();
11 frect.moveCenter(QDesktopWidget().availableGeometry().center());
12 window->move(frect.topLeft());
13 window->show();
14
15 return a.exec();
16 }
path-finding.h:
C++语言: Codee#26095
01 #ifndef PATHFINDING_H
02 #define PATHFINDING_H
03
04 #include <QtGui>
05 #include <QtCore>
06
07 #include "control.h"
08
09 class Widget : public QWidget
10 {
11 Q_OBJECT
12
13 public:
14 Widget(QWidget* parent = 0);
15 void paintEvent(QPaintEvent* event);
16 void mousePressEvent(QMouseEvent* event);
17 void mouseMoveEvent(QMouseEvent* event);
18 void keyPressEvent(QKeyEvent *event);
19 void setWindowPixel(const QPoint& pos, bool opaque);
20
21 private:
22 enum {LENGTH = 910};
23 enum {WIDTH = 700};
24 enum {BLOCKSIZE = 35};
25 enum {MES_Y_OFFSET=16};
26
27 bool blocks[LENGTH/BLOCKSIZE][WIDTH/BLOCKSIZE];
28 bool onDrag;
29 QPoint helpImagePos;
30 QPoint helpMessagePos;
31 QPoint controlImagePos;
32 QPoint controlMessagePos;
33 QPoint cursorpos;
34 QPoint startBlock;
35 QPoint endBlock;
36 Control controlMessage[5];
37 bool checkPosition(const QPoint& pos);
38 int controlSelection;
39 int speed;
40 };
41
42 #endif // PATHFINDING_H
02 #define PATHFINDING_H
03
04 #include <QtGui>
05 #include <QtCore>
06
07 #include "control.h"
08
09 class Widget : public QWidget
10 {
11 Q_OBJECT
12
13 public:
14 Widget(QWidget* parent = 0);
15 void paintEvent(QPaintEvent* event);
16 void mousePressEvent(QMouseEvent* event);
17 void mouseMoveEvent(QMouseEvent* event);
18 void keyPressEvent(QKeyEvent *event);
19 void setWindowPixel(const QPoint& pos, bool opaque);
20
21 private:
22 enum {LENGTH = 910};
23 enum {WIDTH = 700};
24 enum {BLOCKSIZE = 35};
25 enum {MES_Y_OFFSET=16};
26
27 bool blocks[LENGTH/BLOCKSIZE][WIDTH/BLOCKSIZE];
28 bool onDrag;
29 QPoint helpImagePos;
30 QPoint helpMessagePos;
31 QPoint controlImagePos;
32 QPoint controlMessagePos;
33 QPoint cursorpos;
34 QPoint startBlock;
35 QPoint endBlock;
36 Control controlMessage[5];
37 bool checkPosition(const QPoint& pos);
38 int controlSelection;
39 int speed;
40 };
41
42 #endif // PATHFINDING_H
path-finding.cpp:
C++语言: Codee#26096
001 #include "pathfinding.h"
002
003 Widget::Widget(QWidget* parent)
004 : QWidget(parent)
005 {
006 for (int i = 0; i < LENGTH / BLOCKSIZE; ++i)
007 for (int j = 0; j < WIDTH / BLOCKSIZE; ++j)
008 blocks[i][j] = true;
009 startBlock = QPoint(0, 0);
010 blocks[0][0] = false;
011
012 endBlock = QPoint(10, 10);
013 blocks[10][10] = false;
014 onDrag = false;
015
016 controlMessage[0] = Control(QString("Dijkstra"),
017 QColor(Qt::darkGreen));
018 controlMessage[1] = Control(QString("Bi-Directional BFS"),
019 QColor(Qt::darkGreen));
020
021
022 helpImagePos = QPoint(5, 5);
023 helpMessagePos = QPoint(10, 10);
024 controlImagePos = QPoint(790, 5);
025 controlMessagePos = QPoint(795, 10);
026 controlSelection = 0;
027 speed = 1;
028
029 setAttribute(Qt::WA_StaticContents);
030 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
031 this->setMouseTracking(true);
032 this->setFixedSize(LENGTH, WIDTH);
033
034 /*
035 QImage* image=new QImage;
036 image->load(":/image/layer2.png");
037
038 QImage fixedImage(image->size(), QImage::Format_ARGB32_Premultiplied);
039 QPainter imagePainter(&fixedImage);
040 imagePainter.setCompositionMode(QPainter::CompositionMode_Source);
041 imagePainter.fillRect(fixedImage.rect(), Qt::transparent);
042 imagePainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
043 imagePainter.drawImage(QPoint(10,10), *image);
044 imagePainter.end();
045 */
046
047 //QImage pic(":/image/test.jpg");
048 /*
049 I try to use QLabel to show the help message
050 but failed,picture and text can't show at the
051 same time
052 label->setPixmap(QPixmap::convertFromImage(pic));
053 */
054 /*
055 button->setText(controlMessage[0].GetString() + "\n" +
056 controlMessage[1].GetString());
057 label->setPixmap(QPixmap::fromImage(pic));
058 label->show();
059 */
060 /*
061 QHBoxLayout* layout = new QHBoxLayout;
062 layout->addWidget(label);
063 this->setLayout(layout);
064 */
065 }
066
067 void Widget::paintEvent(QPaintEvent* event)
068 {
069 QPainter painter(this);
070 painter.setOpacity(0.8);
071 QColor color = Qt::red;
072
073 /* draw the start block */
074 /*
075 painter.fillRect(QRect(BLOCKSIZE*startBlock.x(), BLOCKSIZE*startBlock.y(),
076 BLOCKSIZE, BLOCKSIZE), color);
077 */
078
079 //qDebug("The startblock pos:%d,%d", startBlock.x(), startBlock.y());
080 /* draw the simple blocks */
081 for (int i = 0; i < LENGTH / BLOCKSIZE; ++i)
082 for (int j = 0; j < WIDTH / BLOCKSIZE; ++j)
083 {
084 QPoint cur(i, j);
085 if (cur == startBlock)
086 color = Qt::red;
087 else if (cur == endBlock)
088 color = Qt::green;
089
090 else if (!blocks[i][j])
091 color = Qt::gray;
092 else
093 color = Qt::white;
094 painter.fillRect(QRect(BLOCKSIZE * i, BLOCKSIZE * j,
095 BLOCKSIZE, BLOCKSIZE), color);
096 }
097
098 painter.setPen(QPen(Qt::gray));
099 /* draw the grids */
100 for (int i = 0; i < LENGTH; i += BLOCKSIZE)
101 painter.drawLine(i, 0,
102 i, WIDTH);
103 for (int j = 0; j <= WIDTH; j += BLOCKSIZE)
104 painter.drawLine(0, j,
105 LENGTH, j);
106
107 painter.setFont(QFont("Arial", 50));
108 painter.drawText(rect(), Qt::AlignCenter, "path-finding demo");
109
110 QImage* image = new QImage;
111 image->load(":/image/layer1.png");
112 /*
113 qDebug("imagesize:\t%d,%d", image->size().width(),
114 image->size().height());
115 */
116 *image = image->scaled(330, 100);
117
118
119 //QImage fixedImage(image->size(), QImage::Format_ARGB32_Premultiplied);
120
121 QPainter imagePainter(this);
122 //imagePainter.setCompositionMode(QPainter::CompositionMode_Source);
123 imagePainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
124 imagePainter.drawImage(helpImagePos, *image);
125
126
127 QPainter textPainter(this);
128 QFont font("Arial", 8);
129 font.setWeight(QFont::Bold);
130 //font.setStretch(1);
131 QString string[] =
132 {
133 "Drag Green and Red block to set source and target",
134 "Hold down mouse button to draw maze",
135 "Press <W> and <S> to select algorithm",
136 "Press <A> and <D> to set demo speed",
137 "Press <SPACE> to start or stop demo",
138 "Press <R> to reset"
139 };
140
141 textPainter.setFont(font);
142 textPainter.setPen(QPen(Qt::white));
143 for (int i = 0; i < 6; ++i)
144 textPainter.drawText(10, 20 + MES_Y_OFFSET * i, string[i]);
145
146 QString controlstr[] =
147 {
148 "A* (Manhattan)",
149 "A* (Euclidean)",
150 "A* (Chebyshev)",
151 "Dijkstra",
152 "Bi-Directional BFS",
153 };
154 image->load(":/image/layer1.png");
155 imagePainter.drawImage(controlImagePos, *image);
156 for (int i = 0; i < 5; ++i)
157 {
158 if (i == controlSelection)
159 textPainter.setPen(QPen(Qt::red));
160 else
161 textPainter.setPen(QPen(Qt::white));
162 textPainter.drawText(795, 20 + MES_Y_OFFSET * i, controlstr[i]);
163 }
164 textPainter.drawText(795, 20 + MES_Y_OFFSET * 5,
165 QString("Speed:") + QString::number(8 * speed) + QString("X"));
166
167
168 /*
169 qDebug("helpimagepos:%d,%d\nmes:%d,%d",helpImagePos.x(),
170 helpImagePos.y(),
171 helpMessagePos.x(),
172 helpMessagePos.y());
173 */
174 /*
175 painter.drawText(rect(),Qt::AlignRight &Qt::AlignTop,
176 controlMessage[1].GetString());
177 */
178
179
180 }
181
182 /* 1. check the cursor's position,if on the start blocks,go to 2,
183 * else go to 3;
184 * 2. drag the start block,set onDrag=true
185 * 3. just draw the current block
186 */
187 void Widget::mousePressEvent(QMouseEvent* event)
188 {
189 cursorpos = QPoint(event->pos().x() / BLOCKSIZE,
190 event->pos().y() / BLOCKSIZE);
191 if (cursorpos == startBlock)
192 onDrag = true;
193 else
194 {
195 setWindowPixel(event->pos(), false);
196 onDrag = false;
197 }
198 }
199
200 void Widget::mouseMoveEvent(QMouseEvent* event)
201 {
202 /*
203 * check the cursor's position
204 * if out of the main window
205 * the application will faile
206 */
207 if (checkPosition(event->pos()))
208 {
209 QPoint tmppos = QPoint(event->pos().x() / BLOCKSIZE,
210 event->pos().y() / BLOCKSIZE);
211 if (cursorpos != tmppos &&
212 (event->buttons() & Qt::LeftButton) ||
213 (event->buttons() & Qt::RightButton))
214 // event->buttons() & Qt::RightButton)
215 {
216 //qDebug("Time elapsed: %d ms", time.msecsTo(curTime));
217 //setWindowPixel(event->pos(), true);
218 /* is on drag ,use this to change the start
219 * block's position,clear the old pos
220 * then take the new pos
221 */
222 if (onDrag)
223 {
224 //qDebug("tmppos:%d,%d", tmppos.x(), tmppos.y());
225 blocks[startBlock.x()][startBlock.y()] = true;
226 startBlock = tmppos;
227 blocks[tmppos.x()][tmppos.y()] = false;
228 }
229 setWindowPixel(event->pos(), onDrag);
230 }
231 }
232 //cursorpos=tmppos;
233 }
234
235 void Widget::setWindowPixel(const QPoint& pos, bool opaque)
236 {
237 int x = pos.x() / BLOCKSIZE;
238 int y = pos.y() / BLOCKSIZE;
239 cursorpos = QPoint(x, y);
240
241 if (!opaque)
242 blocks[x][y] = !blocks[x][y];
243 update();
244 }
245
246 bool Widget::checkPosition(const QPoint& pos)
247 {
248 QRect rect(0, 0, LENGTH, WIDTH);
249 return rect.contains(pos);
250 }
251
252 void Widget::keyPressEvent(QKeyEvent* event)
253 {
254 int keyPressed = toupper(event->key());
255 switch (keyPressed)
256 {
257 case 'W':
258 if (--controlSelection < 0)
259 controlSelection = 4;
260 break;
261 case 'S':
262 if (++controlSelection > 4)
263 controlSelection = 0;
264 break;
265 case 'A':
266 if (--speed < 0)
267 speed = 0;
268 break;
269 case 'D':
270 if (++speed > 5)
271 speed = 5;
272 break;
273 case 'R':
274 for (int i = 0; i < LENGTH / BLOCKSIZE; ++i)
275 for (int j = 0; j < WIDTH / BLOCKSIZE; ++j)
276 blocks[i][j] = true;
277 blocks[startBlock.x()][startBlock.y()] = false;
278 blocks[endBlock.x()][endBlock.y()] = false;
279 break;
280 case ' ':
281 break;
282 default:
283 return ;
284
285 }
286
287 if (keyPressed == 'W' || keyPressed == 'S' ||
288 keyPressed == 'A' || keyPressed == 'D' ||
289 keyPressed == 'R' || keyPressed == ' ')
290 {
291 qDebug("keypressed: %c;sel: %d", keyPressed, controlSelection);
292 repaint();
293 }
294 }
002
003 Widget::Widget(QWidget* parent)
004 : QWidget(parent)
005 {
006 for (int i = 0; i < LENGTH / BLOCKSIZE; ++i)
007 for (int j = 0; j < WIDTH / BLOCKSIZE; ++j)
008 blocks[i][j] = true;
009 startBlock = QPoint(0, 0);
010 blocks[0][0] = false;
011
012 endBlock = QPoint(10, 10);
013 blocks[10][10] = false;
014 onDrag = false;
015
016 controlMessage[0] = Control(QString("Dijkstra"),
017 QColor(Qt::darkGreen));
018 controlMessage[1] = Control(QString("Bi-Directional BFS"),
019 QColor(Qt::darkGreen));
020
021
022 helpImagePos = QPoint(5, 5);
023 helpMessagePos = QPoint(10, 10);
024 controlImagePos = QPoint(790, 5);
025 controlMessagePos = QPoint(795, 10);
026 controlSelection = 0;
027 speed = 1;
028
029 setAttribute(Qt::WA_StaticContents);
030 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
031 this->setMouseTracking(true);
032 this->setFixedSize(LENGTH, WIDTH);
033
034 /*
035 QImage* image=new QImage;
036 image->load(":/image/layer2.png");
037
038 QImage fixedImage(image->size(), QImage::Format_ARGB32_Premultiplied);
039 QPainter imagePainter(&fixedImage);
040 imagePainter.setCompositionMode(QPainter::CompositionMode_Source);
041 imagePainter.fillRect(fixedImage.rect(), Qt::transparent);
042 imagePainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
043 imagePainter.drawImage(QPoint(10,10), *image);
044 imagePainter.end();
045 */
046
047 //QImage pic(":/image/test.jpg");
048 /*
049 I try to use QLabel to show the help message
050 but failed,picture and text can't show at the
051 same time
052 label->setPixmap(QPixmap::convertFromImage(pic));
053 */
054 /*
055 button->setText(controlMessage[0].GetString() + "\n" +
056 controlMessage[1].GetString());
057 label->setPixmap(QPixmap::fromImage(pic));
058 label->show();
059 */
060 /*
061 QHBoxLayout* layout = new QHBoxLayout;
062 layout->addWidget(label);
063 this->setLayout(layout);
064 */
065 }
066
067 void Widget::paintEvent(QPaintEvent* event)
068 {
069 QPainter painter(this);
070 painter.setOpacity(0.8);
071 QColor color = Qt::red;
072
073 /* draw the start block */
074 /*
075 painter.fillRect(QRect(BLOCKSIZE*startBlock.x(), BLOCKSIZE*startBlock.y(),
076 BLOCKSIZE, BLOCKSIZE), color);
077 */
078
079 //qDebug("The startblock pos:%d,%d", startBlock.x(), startBlock.y());
080 /* draw the simple blocks */
081 for (int i = 0; i < LENGTH / BLOCKSIZE; ++i)
082 for (int j = 0; j < WIDTH / BLOCKSIZE; ++j)
083 {
084 QPoint cur(i, j);
085 if (cur == startBlock)
086 color = Qt::red;
087 else if (cur == endBlock)
088 color = Qt::green;
089
090 else if (!blocks[i][j])
091 color = Qt::gray;
092 else
093 color = Qt::white;
094 painter.fillRect(QRect(BLOCKSIZE * i, BLOCKSIZE * j,
095 BLOCKSIZE, BLOCKSIZE), color);
096 }
097
098 painter.setPen(QPen(Qt::gray));
099 /* draw the grids */
100 for (int i = 0; i < LENGTH; i += BLOCKSIZE)
101 painter.drawLine(i, 0,
102 i, WIDTH);
103 for (int j = 0; j <= WIDTH; j += BLOCKSIZE)
104 painter.drawLine(0, j,
105 LENGTH, j);
106
107 painter.setFont(QFont("Arial", 50));
108 painter.drawText(rect(), Qt::AlignCenter, "path-finding demo");
109
110 QImage* image = new QImage;
111 image->load(":/image/layer1.png");
112 /*
113 qDebug("imagesize:\t%d,%d", image->size().width(),
114 image->size().height());
115 */
116 *image = image->scaled(330, 100);
117
118
119 //QImage fixedImage(image->size(), QImage::Format_ARGB32_Premultiplied);
120
121 QPainter imagePainter(this);
122 //imagePainter.setCompositionMode(QPainter::CompositionMode_Source);
123 imagePainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
124 imagePainter.drawImage(helpImagePos, *image);
125
126
127 QPainter textPainter(this);
128 QFont font("Arial", 8);
129 font.setWeight(QFont::Bold);
130 //font.setStretch(1);
131 QString string[] =
132 {
133 "Drag Green and Red block to set source and target",
134 "Hold down mouse button to draw maze",
135 "Press <W> and <S> to select algorithm",
136 "Press <A> and <D> to set demo speed",
137 "Press <SPACE> to start or stop demo",
138 "Press <R> to reset"
139 };
140
141 textPainter.setFont(font);
142 textPainter.setPen(QPen(Qt::white));
143 for (int i = 0; i < 6; ++i)
144 textPainter.drawText(10, 20 + MES_Y_OFFSET * i, string[i]);
145
146 QString controlstr[] =
147 {
148 "A* (Manhattan)",
149 "A* (Euclidean)",
150 "A* (Chebyshev)",
151 "Dijkstra",
152 "Bi-Directional BFS",
153 };
154 image->load(":/image/layer1.png");
155 imagePainter.drawImage(controlImagePos, *image);
156 for (int i = 0; i < 5; ++i)
157 {
158 if (i == controlSelection)
159 textPainter.setPen(QPen(Qt::red));
160 else
161 textPainter.setPen(QPen(Qt::white));
162 textPainter.drawText(795, 20 + MES_Y_OFFSET * i, controlstr[i]);
163 }
164 textPainter.drawText(795, 20 + MES_Y_OFFSET * 5,
165 QString("Speed:") + QString::number(8 * speed) + QString("X"));
166
167
168 /*
169 qDebug("helpimagepos:%d,%d\nmes:%d,%d",helpImagePos.x(),
170 helpImagePos.y(),
171 helpMessagePos.x(),
172 helpMessagePos.y());
173 */
174 /*
175 painter.drawText(rect(),Qt::AlignRight &Qt::AlignTop,
176 controlMessage[1].GetString());
177 */
178
179
180 }
181
182 /* 1. check the cursor's position,if on the start blocks,go to 2,
183 * else go to 3;
184 * 2. drag the start block,set onDrag=true
185 * 3. just draw the current block
186 */
187 void Widget::mousePressEvent(QMouseEvent* event)
188 {
189 cursorpos = QPoint(event->pos().x() / BLOCKSIZE,
190 event->pos().y() / BLOCKSIZE);
191 if (cursorpos == startBlock)
192 onDrag = true;
193 else
194 {
195 setWindowPixel(event->pos(), false);
196 onDrag = false;
197 }
198 }
199
200 void Widget::mouseMoveEvent(QMouseEvent* event)
201 {
202 /*
203 * check the cursor's position
204 * if out of the main window
205 * the application will faile
206 */
207 if (checkPosition(event->pos()))
208 {
209 QPoint tmppos = QPoint(event->pos().x() / BLOCKSIZE,
210 event->pos().y() / BLOCKSIZE);
211 if (cursorpos != tmppos &&
212 (event->buttons() & Qt::LeftButton) ||
213 (event->buttons() & Qt::RightButton))
214 // event->buttons() & Qt::RightButton)
215 {
216 //qDebug("Time elapsed: %d ms", time.msecsTo(curTime));
217 //setWindowPixel(event->pos(), true);
218 /* is on drag ,use this to change the start
219 * block's position,clear the old pos
220 * then take the new pos
221 */
222 if (onDrag)
223 {
224 //qDebug("tmppos:%d,%d", tmppos.x(), tmppos.y());
225 blocks[startBlock.x()][startBlock.y()] = true;
226 startBlock = tmppos;
227 blocks[tmppos.x()][tmppos.y()] = false;
228 }
229 setWindowPixel(event->pos(), onDrag);
230 }
231 }
232 //cursorpos=tmppos;
233 }
234
235 void Widget::setWindowPixel(const QPoint& pos, bool opaque)
236 {
237 int x = pos.x() / BLOCKSIZE;
238 int y = pos.y() / BLOCKSIZE;
239 cursorpos = QPoint(x, y);
240
241 if (!opaque)
242 blocks[x][y] = !blocks[x][y];
243 update();
244 }
245
246 bool Widget::checkPosition(const QPoint& pos)
247 {
248 QRect rect(0, 0, LENGTH, WIDTH);
249 return rect.contains(pos);
250 }
251
252 void Widget::keyPressEvent(QKeyEvent* event)
253 {
254 int keyPressed = toupper(event->key());
255 switch (keyPressed)
256 {
257 case 'W':
258 if (--controlSelection < 0)
259 controlSelection = 4;
260 break;
261 case 'S':
262 if (++controlSelection > 4)
263 controlSelection = 0;
264 break;
265 case 'A':
266 if (--speed < 0)
267 speed = 0;
268 break;
269 case 'D':
270 if (++speed > 5)
271 speed = 5;
272 break;
273 case 'R':
274 for (int i = 0; i < LENGTH / BLOCKSIZE; ++i)
275 for (int j = 0; j < WIDTH / BLOCKSIZE; ++j)
276 blocks[i][j] = true;
277 blocks[startBlock.x()][startBlock.y()] = false;
278 blocks[endBlock.x()][endBlock.y()] = false;
279 break;
280 case ' ':
281 break;
282 default:
283 return ;
284
285 }
286
287 if (keyPressed == 'W' || keyPressed == 'S' ||
288 keyPressed == 'A' || keyPressed == 'D' ||
289 keyPressed == 'R' || keyPressed == ' ')
290 {
291 qDebug("keypressed: %c;sel: %d", keyPressed, controlSelection);
292 repaint();
293 }
294 }