如何用Python实现无边界可调整大小的半透明游戏物品栏选择网格
实现可拖拽调整的物品栏选择网格
核心思路拆解
要做这个功能,核心是在游戏窗口上层叠一个半透明、无边框的可交互窗口,用来绘制网格、响应用户的拖拽/调整操作,最后计算选中的单元格坐标。以下是分步实现方案:
1. 基础准备:获取物品栏参数
首先得提前确定游戏物品栏的几个关键参数(可用截图工具或窗口抓取工具获取):
- 物品栏在屏幕上的左上角坐标
(inv_x, inv_y) - 单个单元格的宽/高
cell_size - 物品栏总行列数
total_rows,total_cols
这些是后续计算的基础,必须先明确。
2. 实现半透明可拖拽窗口
用Python的PyQt5做这个窗口很适合新手,先搭基础框架:
import sys from PyQt5.QtWidgets import QWidget, QApplication, QPushButton from PyQt5.QtGui import QPainter, QColor, QPen from PyQt5.QtCore import Qt, QPoint class GridSelector(QWidget): def __init__(self, inv_x, inv_y, cell_size): super().__init__() # 物品栏基础参数 self.inv_x = inv_x self.inv_y = inv_y self.cell_size = cell_size # 网格初始参数 self.grid_rows = 3 self.grid_cols = 3 self.grid_pos = QPoint(inv_x, inv_y) # 窗口设置:无边框、半透明、顶层显示 self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.setAttribute(Qt.WA_TranslucentBackground) self.resize(self.grid_cols * cell_size, self.grid_rows * cell_size) self.move(self.grid_pos) # 添加确认按钮(也可改用快捷键触发) self.confirm_btn = QPushButton("确认选择", self) self.confirm_btn.clicked.connect(self.get_selected_cells) self.confirm_btn.move(10, 10) # 绘制半透明网格 def paintEvent(self, event): painter = QPainter(self) # 半透明蓝色背景 painter.fillRect(self.rect(), QColor(0, 128, 255, 50)) # 白色网格线 pen = QPen(QColor(255, 255, 255), 1) painter.setPen(pen) # 画竖线 for col in range(self.grid_cols + 1): x = col * self.cell_size painter.drawLine(x, 0, x, self.height()) # 画横线 for row in range(self.grid_rows + 1): y = row * self.cell_size painter.drawLine(0, y, self.width(), y) # 拖拽移动逻辑 def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.drag_start_pos = event.globalPos() - self.frameGeometry().topLeft() event.accept() def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: self.move(event.globalPos() - self.drag_start_pos) self.grid_pos = self.pos() event.accept() # 计算并返回选中的单元格坐标 def get_selected_cells(self): # 计算网格相对于物品栏的偏移 offset_x = self.grid_pos.x() - self.inv_x offset_y = self.grid_pos.y() - self.inv_y # 起始单元格的行列 start_col = offset_x // self.cell_size start_row = offset_y // self.cell_size # 生成所有选中单元格的(行,列)坐标 selected_cells = [] for r in range(start_row, start_row + self.grid_rows): for c in range(start_col, start_col + self.grid_cols): selected_cells.append((r, c)) print("选中的单元格坐标:", selected_cells) # 这里可把结果传递给主程序,比如用信号或全局变量 self.close() if __name__ == "__main__": app = QApplication(sys.argv) # 示例参数:物品栏坐标(100,100),单元格大小40x40 selector = GridSelector(100, 100, 40) selector.show() sys.exit(app.exec_())
3. 扩展:调整网格大小
要让用户自定义网格行列数,可添加输入框实现:
# 在__init__中导入并添加以下代码 from PyQt5.QtWidgets import QLineEdit, QLabel # 行数输入区域 self.row_label = QLabel("行数:", self) self.row_label.move(10, 40) self.row_input = QLineEdit(str(self.grid_rows), self) self.row_input.move(50, 40) self.row_input.editingFinished.connect(self.update_grid_size) # 列数输入区域 self.col_label = QLabel("列数:", self) self.col_label.move(10, 70) self.col_input = QLineEdit(str(self.grid_cols), self) self.col_input.move(50, 70) self.col_input.editingFinished.connect(self.update_grid_size) # 添加网格大小更新方法 def update_grid_size(self): try: self.grid_rows = int(self.row_input.text()) self.grid_cols = int(self.col_input.text()) self.resize(self.grid_cols * self.cell_size, self.grid_rows * self.cell_size) self.update() # 触发重绘 except ValueError: # 输入非数字则忽略 pass
关键注意点
- 窗口层级:用
Qt.WindowStaysOnTopHint确保网格窗口始终在游戏窗口上方 - 坐标转换:要区分屏幕坐标和物品栏相对坐标,避免直接把窗口位置当成单元格坐标
- 适配问题:如果游戏是全屏或有缩放,可能需要通过窗口句柄绑定游戏窗口做适配
内容的提问来源于stack exchange,提问作者Anton Logvinov
相关产品推荐
相关产品推荐

