鱼C论坛

 找回密码
 立即注册
查看: 216|回复: 9

[已解决]pygame问题

[复制链接]
发表于 2024-7-12 11:39:22 | 显示全部楼层 |阅读模式
20鱼币
再写代码时发现一个无法理解的错误,麻烦看一下是怎么回事,谢谢
pygame.draw.rect(ascreen, colour, (Button.values[c][0],Button.values[c][1], 375, 114), 10)
报错:TypeError: 'builtin_function_or_method' object is not subscriptable
最佳答案
2024-7-12 11:39:23
哈哈,鱼油您好!看来您遇到一个小顽皮的错误问题了,别着急,让我们一起来看看问题出在什么地方吧。

首先,我们来看这段代码:
pygame.draw.rect(ascreen, colour, (Button.values, Button.values, 375, 114), 10)
报错信息是:`TypeError: 'builtin_function_or_method' object is not subscriptable`,这意味着您的代码试图像访问列表或字典那样去访问一个不可下标的对象,比如函数。

细细品一下,问题就出现在 `Button.values` 上。`values` 是一个常见的方法名称,例如字典的方法 `values()`。所以很有可能您意图访问某个列表或者元组,但误用了方法名。

确保 `Button.values` 实际上是一个**属性**而不是一个**方法**。如果 `Button` 是一个类,`values` 应该是一个实例属性,而不是方法。

如果 `Button` 是一个类似于类如下:
class Button:
    values = (100, 200)  # 假设按钮坐标在 (100, 200)

# 然后可以这么用
print(Button.values[0])
print(Button.values[1])
但是在 `draw.rect` 中,将其改为 `Button.values[0]` 和 `Button.values[1]` 以便提供具体的坐标值,而不是传递方法本身:
pygame.draw.rect(ascreen, colour, (Button.values[0], Button.values[1], 375, 114), 10)

所以修正后的代码大概是这样:
pygame.draw.rect(ascreen, colour, (Button.values[0], Button.values[1], 375, 114), 10)

这样,Python 不会再抱怨您试图像对待列表那样对待一个不可下标的对象了!希望这个回答能帮到您,写代码的路上难免遇上小插曲,继续加油哦!FishC 和我都会在这里支持你的!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

最佳答案

查看完整内容

哈哈,鱼油您好!看来您遇到一个小顽皮的错误问题了,别着急,让我们一起来看看问题出在什么地方吧。 首先,我们来看这段代码: 报错信息是:`TypeError: 'builtin_function_or_method' object is not subscriptable`,这意味着您的代码试图像访问列表或字典那样去访问一个不可下标的对象,比如函数。 细细品一下,问题就出现在 `Button.values` 上。`values` 是一个常见的方法名称,例如字典的方法 `values()`。所以很有 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-7-12 11:39:23 | 显示全部楼层    本楼为最佳答案   
哈哈,鱼油您好!看来您遇到一个小顽皮的错误问题了,别着急,让我们一起来看看问题出在什么地方吧。

首先,我们来看这段代码:
pygame.draw.rect(ascreen, colour, (Button.values, Button.values, 375, 114), 10)
报错信息是:`TypeError: 'builtin_function_or_method' object is not subscriptable`,这意味着您的代码试图像访问列表或字典那样去访问一个不可下标的对象,比如函数。

细细品一下,问题就出现在 `Button.values` 上。`values` 是一个常见的方法名称,例如字典的方法 `values()`。所以很有可能您意图访问某个列表或者元组,但误用了方法名。

确保 `Button.values` 实际上是一个**属性**而不是一个**方法**。如果 `Button` 是一个类,`values` 应该是一个实例属性,而不是方法。

如果 `Button` 是一个类似于类如下:
class Button:
    values = (100, 200)  # 假设按钮坐标在 (100, 200)

# 然后可以这么用
print(Button.values[0])
print(Button.values[1])
但是在 `draw.rect` 中,将其改为 `Button.values[0]` 和 `Button.values[1]` 以便提供具体的坐标值,而不是传递方法本身:
pygame.draw.rect(ascreen, colour, (Button.values[0], Button.values[1], 375, 114), 10)

所以修正后的代码大概是这样:
pygame.draw.rect(ascreen, colour, (Button.values[0], Button.values[1], 375, 114), 10)

这样,Python 不会再抱怨您试图像对待列表那样对待一个不可下标的对象了!希望这个回答能帮到您,写代码的路上难免遇上小插曲,继续加油哦!FishC 和我都会在这里支持你的!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-7-12 11:44:55 | 显示全部楼层
FishC 发表于 2024-7-12 11:40
哈哈,鱼油您好!看来您遇到一个小顽皮的错误问题了,别着急,让我们一起来看看问题出在什么地方吧。

首 ...

还是没有用啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-7-12 11:45:02 | 显示全部楼层


好的,鱼油,让我们再深入挖掘一下这个问题。

首先,请确认 `Button.values` 是什么类型。根据错误信息,`Button.values` 可能是一个函数而不是一个属性。如果您真的不小心将其定义为方法,就会导致错误。

让我们先来检查一下 `Button` 类的定义:
class Button:
    def __init__(self, x, y):
        self.values = (x, y)

# 创建 Button 对象
my_button = Button(50, 60)

在这个例子中,`values` 是 `Button` 类的一个属性,它是一个包含两个值的元组。

现在,您可以使用 `my_button.values` 来取出坐标:
pygame.draw.rect(ascreen, colour, (*my_button.values, 375, 114), 10)

这里,星号(*)运算符用于解包元组,将其分解成两个单独的值传递给 `pygame.draw.rect`。

然而,如果 `Button.values` 被定义为了方法,比如这样:
class Button:
    def values(self):
        return (50, 60)

那么需要调用该方法而不是直接访问属性:
pygame.draw.rect(ascreen, colour, (*my_button.values(), 375, 114), 10)

注意区别:有括号的 `values()` 表示调用方法,没有括号的 `values` 表示访问属性。

如果问题依然存在,请您提供更多的代码上下文,这样我可以更准确地定位问题所在。没关系,我们一定能搞定它的!继续加油哦!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-7-12 11:53:06 | 显示全部楼层
FishC 发表于 2024-7-12 11:45
好的,鱼油,让我们再深入挖掘一下这个问题。

首先,请确认 `Button.values` 是什么类型。根据错误 ...

不是,我还是把代码发给你吧
import pygame
#按钮图片及位置设置
#button1 = pygame.image.load("NewGame.png")
#button2 = pygame.image.load("LoadGame.png")
#button3 = pygame.image.load("help.png")
#button4 = pygame.image.load("ExitGame.png")
#b1_qosition = (size[0] / 2, size[1] /8)
#b2_qosition = (size[0] / 2, size[1] /4)
#b3_qosition = (size[0] / 2, size[1] /2.6)
#b4_qosition = (size[0] / 2, size[1] /1.9)
abutton = []
Button = {}
c = 0
def init(*image, p):
    for i in image:
        b = pygame.image.load(i)
        abutton.append(b)
        Button[abutton[image.index(i)]] = p[image.index(i)]

def draw(ascreen, colour):
    for i in Button.items():
        ascreen.blit(i[0], i[1])
    pygame.draw.rect(ascreen, colour, (Button.values[0],Button.values[1], 375, 114), 10)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-7-12 11:55:25 | 显示全部楼层
flyps 发表于 2024-07-12 11:53
不是,我还是把代码发给你吧import pygame
...


感谢提供代码!通过细看您的代码,我发现了几个可能导致问题的地方。我们来仔细检查和修订一下您的代码。

### 可能存在的问题:

1. `abutton` 被初始化为一个空值。
2. `Button` 这个字典的键和值的处理不够清晰。
3. 在 `draw` 函数中, `pygame.draw.rect` 使用了 `.values()` 方法,这在字典中的使用有些不妥当。

让我们先分析并调整一下这些代码:

### 修订后的代码:
import pygame

# 初始化 Pygame
pygame.init()

# 创建屏幕对象
size = (800, 600)  # 假设屏幕大小
screen = pygame.display.set_mode(size)

# 初始化一些颜色
colour = (255, 0, 0)  # 红色

# 按钮图片及位置设置
button_images = ["NewGame.png", "LoadGame.png", "help.png", "ExitGame.png"]
button_positions = [(400, 75), (400, 150), (400, 225), (400, 300)]

abutton = []
Button = {}

# 修改 init 函数
def init(image_paths, positions):
    for i, path in enumerate(image_paths):
        b = pygame.image.load(path)
        abutton.append(b)
        Button[b] = positions[i]

# 调用 init 函数
init(button_images, button_positions)

# 修改 draw 函数
def draw(ascreen, colour):
    for img, pos in Button.items():
        ascreen.blit(img, pos)
        pygame.draw.rect(ascreen, colour, (*pos, 375, 114), 10)

# 主循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((255, 255, 255))  # 填充背景为白色
    draw(screen, colour)
    pygame.display.flip()

pygame.quit()

### 解释:
1. **初始化屏幕**:我们假设了一个屏幕大小,并创建了一个 `screen` 对象。
2. **按钮图片和位置信息**:为了简化处理,将按钮图片路径和位置信息分开存储。
3. **`init` 函数**:修改了 `init` 函数,使其接受两个参数 `image_paths` 和 `positions`,并将图像加载到 `abutton` 列表中,同时将图像和位置存储在 `Button` 字典中。
4. **`draw` 函数**:修改了 `draw` 函数,遍历 `Button` 字典,用图像和位置绘制按钮,并绘制矩形框。
5. **主循环**:加入了一个简单的事件循环,确保窗口能够正常关闭。

希望这些修改能解决这个问题!如果还有任何疑问,请随时告诉我。继续加油,我们一起搞定它!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-7-12 12:27:43 | 显示全部楼层
FishC 发表于 2024-7-12 11:55
感谢提供代码!通过细看您的代码,我发现了几个可能导致问题的地方。我们来仔细检查和修订一下您的代码 ...

我尝试将图片与位置分为两个列表(元组)可是却报错“TypeError: 'dict_values' object is not subscriptable”这又是为什么呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-7-12 12:27:59 | 显示全部楼层
flyps 发表于 2024-07-12 12:27
我尝试将图片与位置分为两个列表(元组)可是却报错“ ...


好的,鱼油,让我们再深入分析一下具体情况。您遇到的 `TypeError: 'dict_values' object is not subscriptable` 报错,通常是因为尝试在字典的值视图(`dict_values` 对象)上使用下标,而这类对象不支持下标操作。

让我们重新整理一下代码,确保图像和位置的处理逻辑清晰,并解决这个问题:

### 代码修订和解释:
import pygame

# 初始化 Pygame
pygame.init()

# 设置屏幕大小
size = (800, 600)
screen = pygame.display.set_mode(size)

# 颜色设置
colour = (255, 0, 0)  # 红色

# 按钮图片路径列表和位置信息列表
button_images = ["NewGame.png", "LoadGame.png", "help.png", "ExitGame.png"]
button_positions = [
    (size[0] // 2, size[1] // 8),
    (size[0] // 2, size[1] // 4),
    (size[0] // 2, size[1] // 2.6),
    (size[0] // 2, size[1] // 1.9)
]

# 初始化按钮和其位置的结构
abutton = []
Button = {}

# 修改 init 函数
def init(image_paths, positions):
    for path, pos in zip(image_paths, positions):
        b = pygame.image.load(path)
        abutton.append(b)
        Button[b] = pos

# 调用 init 函数进行初始加载
init(button_images, button_positions)

# 修改 draw 函数
def draw(ascreen, colour):
    for img, pos in Button.items():
        ascreen.blit(img, pos)
        pygame.draw.rect(ascreen, colour, (*pos, 375, 114), 10)

# 主循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((255, 255, 255))  # 填充背景为白色
    draw(screen, colour)
    pygame.display.flip()

pygame.quit()

### 解释:

1. **初始化 Pygame**:调用 `pygame.init()` 来初始化所有的 Pygame 模块。
2. **设置屏幕大小**:创建一个尺寸为 `800x600` 的窗口。
3. **颜色设置**:定义一个红色的颜色元组。
4. **按钮图片路径和位置信息**:分别将按钮图像路径和对应的位置存储在两个列表中。
5. **初始化按钮和位置的结构**:创建 `abutton` 列表来存放按钮图像,并使用 `Button` 字典将按钮图像与对应的位置关联起来。
6. **`init` 函数**:通过 `zip` 函数并行迭代图像路径和位置,将每个图像加载到 `abutton` 列表中,同时将图像和位置存储到 `Button` 字典中。
7. **`draw` 函数**:遍历 `Button` 字典,对于每个图像和位置,用 `blit` 方法绘制图像,并用 `pygame.draw.rect` 绘制矩形框。
8. **主循环**:加入一个事件循环,确保窗口能够正常响应关闭事件,并使画面不断刷新。

这样修改后,您的程序应该能正确运行了,没有了之前的错误。如果还有任何问题,请随时告诉我!我们一定能搞定它的!继续加油!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-7-12 12:29:58 | 显示全部楼层
FishC 发表于 2024-7-12 11:55
感谢提供代码!通过细看您的代码,我发现了几个可能导致问题的地方。我们来仔细检查和修订一下您的代码 ...

是这样的
import pygame
#按钮图片及位置设置
#button1 = pygame.image.load("NewGame.png")
#button2 = pygame.image.load("LoadGame.png")
#button3 = pygame.image.load("help.png")
#button4 = pygame.image.load("ExitGame.png")
#b1_qosition = (size[0] / 2, size[1] /8)
#b2_qosition = (size[0] / 2, size[1] /4)
#b3_qosition = (size[0] / 2, size[1] /2.6)
#b4_qosition = (size[0] / 2, size[1] /1.9)
abutton = []
Button = {}
c = 0
button_i = []
button_p = []
def init(*image, p):
    global button_i
    global button_p
    for i in image:
        b = pygame.image.load(i)
        abutton.append(b)
        Button[abutton[image.index(i)]] = p[image.index(i)]
    button_i = Button.keys()
    button_p = Button.values()
def draw(ascreen, colour):
    for i in Button.items():
        ascreen.blit(i[0], i[1])
    pygame.draw.rect(ascreen, colour, (button_p[0][c][0], button_p[c][1], 375, 114), 10)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-7-12 12:30:14 | 显示全部楼层
flyps 发表于 2024-07-12 12:29
是这样的import pygame
#按钮图片及位置设置
#butto ...


好的,让我们分析一下您的代码,然后进行修正。首先,我们需要明确以下几点:

1. `abutton` 被初始化为空列表。
2. `Button` 作为一个字典,用于存储按钮及其对应的位置。
3. `button_i` 和 `button_p` 是从 `Button` 字典中提取的键和值。
4. 在 `draw` 函数中,您尝试将 `button_p` 传递给 `pygame.draw.rect`,但是这会导致错误,因为 `button_p` 是一个字典视图,而不是数值类型。

### 代码修正和解释:

1. 使用列表存储图像和位置。
2. 修改 `init` 函数,以确保正确加载图像和位置,并将它们存储在字典中。
3. 修改 `draw` 函数,以正确绘制图像和矩形。

### 修订后的代码:
import pygame

# 初始化 Pygame
pygame.init()

# 设置屏幕大小
size = (800, 600)
screen = pygame.display.set_mode(size)

# 颜色设置
colour = (255, 0, 0)  # 红色

# 创建空列表和字典
abutton = []
Button = {}
button_i = []
button_p = []

def init(image_paths, positions):
    global button_i
    global button_p
    
    for i, pos in zip(image_paths, positions):
        b = pygame.image.load(i)  # 加载图像
        abutton.append(b)  # 添加到 abutton 列表
        Button[b] = pos  # 将图像和位置添加到 Button 字典
    
    button_i = list(Button.keys())
    button_p = list(Button.values())

# 示例图片和位置
button_images = ["NewGame.png", "LoadGame.png", "help.png", "ExitGame.png"]
button_positions = [
    (size[0] // 2, size[1] // 8),
    (size[0] // 2, size[1] // 4),
    (size[0] // 2, size[1] // 2.6),
    (size[0] // 2, size[1] // 1.9)
]

# 调用 init 函数
init(button_images, button_positions)

def draw(ascreen, colour):
    for img, pos in Button.items():
        ascreen.blit(img, pos)
        pygame.draw.rect(ascreen, colour, (*pos, 375, 114), 10)

# 主循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((255, 255, 255))  # 填充背景为白色
    draw(screen, colour)
    pygame.display.flip()

pygame.quit()

### 解释:

1. **初始化 Pygame**:通过 `pygame.init()` 来初始化所有 Pygame 模块。
2. **设置屏幕大小**:创建一个尺寸为 `800x600` 的窗口。
3. **颜色设置**:定义一个红色的颜色元组。
4. **创建空列表和字典**:用于存储按钮图像和对应位置。
5. **`init` 函数**:该函数接收图像路径和位置的列表,加载图像并将图像和位置存储在字典中。同时将字典的键和值分别存储在 `button_i` 和 `button_p` 中。
6. **示例图片和位置**:假设一些图片文件名和对应的位置。
7. **调用 `init` 函数**:初始化按钮图像和位置。
8. **`draw` 函数**:遍历 `Button` 字典,用 `blit` 将图像绘制到指定位置,并用 `pygame.draw.rect` 绘制矩形框。
9. **主循环**:加入一个事件循环,确保窗口能够正常响应关闭事件,并使画面不断刷新。

通过以上调整,您的代码应该能正确运行了。如果还有任何问题,请随时告诉我!我们一定能搞定它的!继续加油!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 01:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表