1 簡介
參考視頻:https://www.bilibili.com/video/BV1XW411x7NU?p=53
Github:https://github.com/zhengcixi/Qt_Demo/tree/master/chess
說明:實現一個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 }
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
運行測試:
注意看左下角打印的坐標,就是我們當前棋子所在棋盤的坐標。