Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Drawing a Chinese Chess Board by Overriding QWidget's paintEvent Method in Qt

Tech 3

Header File

#ifndef CHESSBOARDWIDGET_H
#define CHESSBOARDWIDGET_H

#include <QWidget>
#include <QPainter>

QT_BEGIN_NAMESPACE
namespace Ui { class ChessBoardWidget; }
QT_END_NAMESPACE

class ChessBoardWidget : public QWidget
{
    Q_OBJECT

public:
    explicit ChessBoardWidget(QWidget *parent = nullptr);
    ~ChessBoardWidget();

protected:
    void paintEvent(QPaintEvent *event) override;

private:
    Ui::ChessBoardWidget *ui;
    const int cellSize = 90;
    const int boardWidth = 840;
    const int boardHeight = 920;
    const QPoint boardOrigin = QPoint(60, 55);
};

#endif // CHESSBOARDWIDGET_H

Source File

#include "chessboardwidget.h"
#include "ui_chessboardwidget.h"
#include <QPainterPath>

ChessBoardWidget::ChessBoardWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ChessBoardWidget)
{
    ui->setupUi(this);
    setFixedSize(boardWidth, boardHeight);
}

ChessBoardWidget::~ChessBoardWidget()
{
    delete ui;
}

void ChessBoardWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    // Configure pen for drawing lines
    QPen linePen;
    linePen.setWidth(4);
    linePen.setColor(Qt::black);
    linePen.setStyle(Qt::SolidLine);
    linePen.setCapStyle(Qt::FlatCap);
    linePen.setJoinStyle(Qt::BevelJoin);
    painter.setPen(linePen);

    // Set brush to no fill
    QBrush transparentBrush;
    transparentBrush.setStyle(Qt::NoBrush);
    painter.setBrush(transparentBrush);

    // Draw outer board rectangle
    QRect boardRect(boardOrigin.x(), boardOrigin.y(), cellSize * 8, cellSize * 9);
    painter.drawRect(boardRect);

    // Draw horizontal lines
    for (int row = 1; row < 9; ++row) {
        QLine horizontalLine(
            boardOrigin.x(),
            boardOrigin.y() + row * cellSize,
            boardOrigin.x() + 8 * cellSize,
            boardOrigin.y() + row * cellSize
        );
        painter.drawLine(horizontalLine);
    }

    // Draw vertical lines for upper half
    for (int col = 1; col < 8; ++col) {
        QLine verticalLineUpper(
            boardOrigin.x() + col * cellSize,
            boardOrigin.y(),
            boardOrigin.x() + col * cellSize,
            boardOrigin.y() + 4 * cellSize
        );
        painter.drawLine(verticalLineUpper);
    }

    // Draw vertical lines for lower half
    for (int col = 1; col < 8; ++col) {
        QLine verticalLineLower(
            boardOrigin.x() + col * cellSize,
            boardOrigin.y() + 5 * cellSize,
            boardOrigin.x() + col * cellSize,
            boardOrigin.y() + 9 * cellSize
        );
        painter.drawLine(verticalLineLower);
    }

    // Draw diagonal lines
    painter.drawLine(QLine(
        boardOrigin.x() + 3 * cellSize,
        boardOrigin.y(),
        boardOrigin.x() + 5 * cellSize,
        boardOrigin.y() + 2 * cellSize
    ));
    painter.drawLine(QLine(
        boardOrigin.x() + 3 * cellSize,
        boardOrigin.y() + 7 * cellSize,
        boardOrigin.x() + 5 * cellSize,
        boardOrigin.y() + 9 * cellSize
    ));
    painter.drawLine(QLine(
        boardOrigin.x() + 3 * cellSize,
        boardOrigin.y() + 2 * cellSize,
        boardOrigin.x() + 5 * cellSize,
        boardOrigin.y()
    ));
    painter.drawLine(QLine(
        boardOrigin.x() + 3 * cellSize,
        boardOrigin.y() + 9 * cellSize,
        boardOrigin.x() + 5 * cellSize,
        boardOrigin.y() + 7 * cellSize
    ));

    // Draw "Chu River Han Border" text
    QFont borderFont;
    borderFont.setPointSize(50);
    painter.setFont(borderFont);
    painter.drawText(
        QRect(
            boardOrigin.x(),
            boardOrigin.y() + 4 * cellSize,
            boardOrigin.x() + 8 * cellSize,
            cellSize
        ),
        tr("\t\t\t\t\t\t楚\t河\t\t\t\t\t汉\t界")
    );

    // Draw corner marks for cannon and pawn positions
    const int cornerSize = 15;
    const int cornerSpacing = 5;

    QPoint cornerPoints[] = {
        QPoint(boardOrigin.x() + cornerSize, boardOrigin.y()),
        QPoint(boardOrigin.x(), boardOrigin.y()),
        QPoint(boardOrigin.x(), boardOrigin.y() + cornerSize)
    };

    QPainterPath cornerPath;
    cornerPath.moveTo(cornerPoints[0]);
    cornerPath.lineTo(cornerPoints[1]);
    cornerPath.lineTo(cornerPoints[2]);

    // Draw corner marks using translation and rotation
    painter.save();
    painter.translate(cornerSpacing, 3 * cellSize + cornerSpacing);
    for (int i = 0; i < 4; ++i) {
        painter.drawPath(cornerPath);
        painter.translate(0, 3 * cellSize);
        painter.drawPath(cornerPath);
        painter.translate(0, -3 * cellSize);
        painter.translate(2 * cellSize, 0);
    }
    painter.restore();

    painter.translate(cornerSpacing, cellSize + cornerSize);
    for (int i = 0; i < 4; ++i) {
        painter.rotate(-90);
        painter.drawPath(cornerPath);
        painter.rotate(90);
        painter.translate(0, 3 * cellSize);
        painter.rotate(-90);
        painter.drawPath(cornerPath);
        painter.rotate(90);
        painter.translate(0, -3 * cellSize);
        painter.translate(2 * cellSize, 0);
    }

    // Additional corner drawing sections follow similar patterns
    // (Remaining corner drawing code follows the same restructured approach)
}

Reesult Image

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.