Qt_Demo3:实现棋盘

1  简介

参考视频://www.bilibili.com/video/BV1XW411x7NU?p=53

说明:实现一个8*8的棋盘,点击棋盘的任意位置显示一个表情,并打印出当前的坐标(相对棋盘)。界面如下:

 2  实现过程

(1)画棋盘的线

我们把当前窗口均分为10份,得到一个棋盘方格的横纵线的大小,记为gridX,gridY,另外记横轴起始坐标为startX=gridX,纵轴起始坐标为startY=gridY。

先画出横线,一共9条,第一条横线的起始坐标为(startX, startY),终点坐标为(startX+8*gridX, startY);

第二条横线的起始坐标为(startX, startY+gridY),终点坐标为(startX+8*gridX, startY+gridY);

以此类推,可得出全部的横线的起始和终点坐标。

同理,画竖线也是一样的道理:

第一条竖线的起始坐标为(startX, startY),终点坐标为(startX, startY+8*gridY);

第二条竖线的起始坐标为(startX+gridX, startY),终点坐标为(startX+gridX, startY+8*grid);

(2)画棋子

我们先获取当前坐标,通过event->x(),event->y获得;

接着需要判断坐标是否在棋盘范围内:x >= startX && x <= startX+8*gridX && y >= startY && y <= startX+8*gridY;

接着算出x和y的坐标:chessX = (x – startX) / gridX;    chessY = (y – startY) / gridY;

然后进行绘制:p.drawPixmap(startX+chessX*gridX, startY+chessY*gridY, gridX, gridY, QPixmap(“../image/face.png”));

3  代码及测试

下面给出完整代码:

widget.cpp

 1 #include "widget.h"
 2 #include "ui_widget.h"
 3 #include <QPaintEvent>
 4 #include <QMouseEvent>
 5 #include <QPainter>
 6 #include <QPen>
 7 #include <QDebug>
 8 
 9 Widget::Widget(QWidget *parent) :
10     QWidget(parent),
11     ui(new Ui::Widget)
12 {
13     ui->setupUi(this);
14 
15     chessX = -1;
16     chessY = -1;
17 }
18 
19 Widget::~Widget()
20 {
21     delete ui;
22 }
23 
24 void Widget::paintEvent(QPaintEvent *event)
25 {
26     gridX = width()/10;
27     gridY = height()/10;
28     startX = gridX;
29     startY = gridY;
30 
31     QPainter p(this);
32     QPen pen;
33     pen.setWidth(3);
34     p.setPen(pen);
35 
36     //画棋盘
37     for (int i = 0; i <= 8; i++) {
38         //画横线
39         p.drawLine(startX, startY+gridY*i, startX+8*gridX, startY+gridY*i);
40         //画竖线
41         p.drawLine(startX+i*gridX, startY, startX+i*gridX, startY+gridY*8);
42     }
43     //画棋子
44     if(chessX != -1 && chessY != -1) {
45         p.drawPixmap(startX+chessX*gridX, startY+chessY*gridY, gridX, gridY, QPixmap("../image/face.png"));
46     }
47 
48 }
49 
50 void Widget::mousePressEvent(QMouseEvent *event)
51 {
52     //获取点击的坐标
53     int x = event->x();
54     int y = event->y();
55     // 要保证点击点在棋盘范围里面
56     if(x >= startX && x <= startX+8*gridX
57        && y >= startY && y <= startX+8*gridY) {
58         // 棋盘的位置转换转换为坐标下标值
59         // 类似于a[i][j]的i和j
60         chessX = (x - startX) / gridX;
61         chessY = (y - startY) / gridY;
62         qDebug() << chessX << chessY;
63         //更新窗口,间接调用paintEvent()
64         update();
65     }
66 }

View Code

widget.h

 1 #ifndef WIDGET_H
 2 #define WIDGET_H
 3 
 4 #include <QWidget>
 5 
 6 namespace Ui {
 7 class Widget;
 8 }
 9 
10 class Widget : public QWidget
11 {
12     Q_OBJECT
13 
14 public:
15     explicit Widget(QWidget *parent = 0);
16     ~Widget();
17 
18     void paintEvent(QPaintEvent *event);
19     void mousePressEvent(QMouseEvent *event);
20 
21 private:
22     Ui::Widget *ui;
23 
24     int startX;
25     int startY;
26     int gridX;
27     int gridY;
28     int chessX;
29     int chessY;
30 
31 };
32 
33 #endif // WIDGET_H

View Code

运行测试:

注意看左下角打印的坐标,就是我们当前棋子所在棋盘的坐标。