需求:共16行,12列。
那么共有192个项。
我希望按照这种格式进行排布。
一列共16个项,实际上我的一列又被拆分为了2小列
第1小列为1-8
第2小列为9-16
项9的位置在项1的左上角45°
依此类推
#include <QApplication> #include <QWidget> #include <QPainter> #include <QFontMetrics> #include <QDebug> class CircleGrid : public QWidget { public: CircleGrid(QWidget *parent = nullptr) : QWidget(parent) { setWindowTitle("斜向双列空心圆网格 (16x12)"); resize(1000, 800); } protected: void paintEvent(QPaintEvent *) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); const int rows = 16; // 每列行数 const int cols = 12; // 总列数 const int margin = 30; int w = width(), h = height(); // 单元格的理论宽度,单元格的理论高度 int cellWidth = (w - 2 * margin) / cols; int cellHeight = (h - 2 * margin) / rows * 2; qDebug() << __FILE__ << __LINE__ << "单元格理论宽度:" << cellWidth; qDebug() << __FILE__ << __LINE__ << "单元格的理论高度:" << cellHeight; int cellSize = qMin(cellWidth,cellHeight); if (cellSize < 10) cellSize = 10; int gridWidth = cellSize * cols; int gridHeight = cellSize * rows / 2; int offsetX = (w - gridWidth) / 2; int offsetY = (h - gridHeight) / 2; qDebug() << __FILE__ << __LINE__ << "cellSize:" << cellSize; qDebug() << __FILE__ << __LINE__ << "gridWidth:" << gridWidth; qDebug() << __FILE__ << __LINE__ << "gridHeight:" << gridHeight; qDebug() << __FILE__ << __LINE__ << offsetX << offsetY; QPen pen(Qt::black, 2); painter.setPen(pen); painter.setBrush(Qt::NoBrush); /* painter.drawRect(offsetX,offsetY,gridWidth,gridHeight); */ // 固定小字号,也可改为动态调整(如 qMin(cellSize/4, 12)) int fontSize = 10; QFont font("Arial", fontSize, QFont::Bold); painter.setFont(font); int dMargin = 0; // 遍历所有列(c=0 为最右列,c=11 为最左列) //for (int c = 0; c < cols; ++c) { for (int c = 0; c < cols; ++c) { // 该列的基础 X 坐标(第一子列的 X 中心) int baseX = offsetX + c * cellSize + cellSize / 2 + c * dMargin; // 基础 Y 坐标(第一子列的第一个数字的 Y 中心) int baseY = offsetY + cellSize / 2; // 该列内的数字顺序 r = 0 ~ 15 for (int r = 0; r < rows; ++r) { // 计算全局编号(从右往左,从上到下) int number = (cols - 1 - c) * rows + r + 1; //qDebug() << __FILE__ << __LINE__ << number; // 划分组:前半(0~7)为第一子列,后半(8~15)为第二子列 int group = r / 8; // 0 或 1 int index = r % 8; // 0 ~ 7 // 偏移量:第二子列向左上方偏移半个单元格(45°方向) int dis = (cellSize + dMargin)/ 2; int dx = (group == 0) ? 0 : -dis; int dy = (group == 0) ? 0 : -dis; // 最终圆心坐标 int cx = baseX + dx; int cy = baseY + index * (cellSize + dMargin) + dy; int radius = cellSize * 0.30; // 圆半径稍小 qDebug() << __FILE__ << __LINE__ << cx << cy << number; // 绘制空心圆 painter.drawEllipse(QPoint(cx, cy), radius, radius); // 绘制数字(精确居中) QString numStr = QString::number(number); QFontMetrics fm(painter.font()); int tw = fm.horizontalAdvance(numStr); int th = fm.height(); QRect textRect(cx - tw / 2, cy - th / 2, tw, th); painter.drawText(textRect, Qt::AlignCenter, numStr); } } } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); CircleGrid window; window.show(); return app.exec(); }