You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:23:22