使用QPainter绘制圆形图
需求:共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; // 遍历所有列c0 为最右列c11 为最左列 //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(); }