searchdemo 四.键盘事件和帮助、控制信息

  界面部分基本完成。程序的架构实在是恶心到不行,明天从头再来。

  

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 }

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

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 }
原文地址:https://www.cnblogs.com/invisible/p/2452103.html