【问题标题】:I cannot get a class method working; if I copy-paste the method code where the method should be called, it works我无法让类方法工作;如果我将方法代码复制粘贴到应该调用该方法的位置,它就可以工作
【发布时间】:2021-03-13 20:49:54
【问题描述】:

我在用 Python 编写自己的类方面相对较新。 我在一个程序上工作,其中我已经定义了 3 个类,每个类都有 4/5 个方法,它们都可以正常工作。但是我遇到了一个新问题一个小时,我无法弄清楚我做错了什么。实际上,即使没有弹出错误消息,该方法也不起作用,但是如果我将方法的代码复制粘贴到我的 pygame 循环(调用它的地方)中,它就可以正常工作。 这是我的类的代码(这里的 .click(self) 方法是关键):

class button:
    def __init__(self, window, xpos, ypos, width, height, color = white, text = '', dest = None):
        self.xpos = xpos * r
        self.ypos = ypos * r
        self.width = width * r
        self.height = height * r
        self.color = color
        self.colorBuffer = [color[i] for i in range(3)]
        self.window = window
        self.hovered = False
        self.clicked = False
        self.text = text
        self.dest = dest
        #self.R = color[0]
        #self.G = color[1]
        #self.B = color[2]
    
    def click(self):
        self.clicked = True
        if self.dest == None:
            pass
        else:
            currentMenu = self.dest
            self.dest.disp()
            self.clicked = False

这是调用该方法的代码(当程序检查 event.type == MOUSEBUTTONDOWN 时调用该方法):

loop = False
if loop == False:
    currentMenu = mainMenu
loop = True
boxisinputting = False
boxinputting = None
userisinputting = False

while loop == True:
    pygame.display.flip()
    userisinputting = False
    mousex, mousey = pygame.mouse.get_pos()
    currentMenu.disp()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            loop = False
            pygame.quit()
        if event.type == pygame.KEYDOWN:
            if pygame.key.name(event.key) == 'return':
                boxinputting.inputting = False
                boxisinputting = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                for but in currentMenu.buttonList:
                    if but.hovered == True:
                        but.click()
                if boxisinputting == False:
                    for box in currentMenu.inputBoxList:
                        if box.hovered == True:
                            box.inputting = True
                            boxisinputting = True
                            boxinputting = box
    if userisinputting == True:
        boxinputting.render()
    pygame.time.delay(100)

当我运行这段代码时会发生什么: 下一个菜单显示正常,但它的按钮没有响应(无论鼠标在按钮上,我都有点亮或熄灭它的方法);相反,当我将指针移动到它们所在的位置时,会弹出上一个菜单的按钮。 但是,当我复制粘贴说明时,我希望我的方法 .click(self) 在这里执行:

if event.type == pygame.MOUSEBUTTONDOWN:
    if event.button == 1:
        for but in currentMenu.buttonList:
            if but.hovered == True:
                but.clicked = True
                if but.dest == None:
                    pass
                else:
                    currentMenu = None
                    currentMenu = but.dest
                    but.dest.disp()
                    but.clicked = False

...嗯,它工作得很好:按钮处于活动状态并做出响应,之前的按钮不会突然弹出(这是我愿意做的)。 我可以侥幸逃脱,因为这只会在我的循环中浪费 5 或 6 行。但我很想知道为什么我不能让这个方法起作用,以避免将来出现类似这样的问题。

感谢您阅读我的帖子!

威廉

【问题讨论】:

  • 好的,那么到底出了什么问题?此外,与其尝试缩短您遇到问题的click 方法,不如尝试删除与问题无关的所有其他内容?只留下必要的部分,以便其他人可以复制和粘贴代码并复制问题。详情请见sscce.org
  • 如果您将break 替换为button.click(),那么您的函数调用代码将等同于内联代码。否则,您将尝试在for 循环结束时调用button.click()。你的for 循环也有一个潜在的问题,因为你正在创建一个名为button 的局部变量,与你的类同名。这有帮助吗?
  • @Karl Knetchel 谢谢。我已经更新了我的帖子,希望它更具可读性并直截了当。
  • @Random Davis 好吧,您已经指出了我的问题:我认为等效的两个代码运行不同。而且我已经修复了您指出的错误写作,将“for button in currentMenu.buttonList”替换为“for but in currentMenu.buttonList”。它仍然没有解决我的问题。

标签: python python-3.x class pygame


【解决方案1】:

很难说,因为包含的代码没有显示button 的实例化,但可能您需要确保它引用的是全局范围:

def click(self):
    global currentMenu, gamesMenu
    currentMenu = gamesMenu
    print('click')

如果你的按钮类坚持只是一个按钮,它会更好。这就是关于位置、标签、颜色、是否被点击、未点击、悬停等问题。但它是什么不是也很重要。按钮不是菜单,它不应该知道菜单,也不应该处理菜单(或刷新显示缓冲区!)。

当对象的功能简洁时,它们会产生更好的设计和更简洁的代码。

【讨论】:

  • 谢谢。我不知道 Python 中的“全局”,但我已将问题确定为:它仅在方法中本地修改 currentMenu,但 currentMenu 会在程序完成运行该方法后将其取为先前的值。所以这解决了我的问题。另外,关于我的按钮类,它的目的是在单击时指向菜单,并在悬停时突出显示:而不是编写函数和用列表定义按钮,我发现用自己的方法定义一个类更实用。但请随时给我建议,以改进我的程序的人体工程学。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 2012-06-08
  • 2020-12-30
  • 2017-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多