search-demo 四.键盘事件和帮助、控制信息

本文详细阐述了界面部分的开发工作,包括架构调整、窗口布局优化、块操作逻辑实现等核心内容。通过代码示例展示了如何使用Qt库进行界面元素的绘制、交互事件响应以及算法演示的集成。

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

  

 

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/archive/2012/04/16/2452103.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值