Я не могу заставить метод класса работать; если я скопирую и вставлю код метода, в котором должен быть вызван метод, он работает

#python #python-3.x #class #pygame

#python #python-3.x #класс #pygame

Вопрос:

Я относительно новичок в программировании своих собственных классов на 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)
 

Что происходит, когда я запускаю этот код:
Следующее меню отображается нормально, но его кнопки не реагируют (у меня есть методы, которые подсвечивают его вверх или вниз независимо от того, нажимает ли мышь на кнопку); вместо этого, когда я перемещаю указатель на предыдущее меню, появляются кнопки предыдущего меню, где они были.
Однако, когда я копирую и вставляю инструкции, я хочу, чтобы мой метод .нажмите (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 строк в моем цикле. Но мне интересно узнать, почему я не могу заставить метод работать, чтобы избежать будущих проблем, подобных этой.

Спасибо, что прочитали мой пост!

Уильям

Комментарии:

1. Хорошо, так что именно пошло не так ? Кроме того, вместо того, чтобы пытаться сократить click метод, в котором у вас возникла проблема, можете ли вы попытаться вырезать все остальное , что не связано с проблемой? Оставьте только то, что необходимо, чтобы другие люди могли скопировать и вставить код и воспроизвести проблему. Пожалуйста, смотрите sscce.org за подробностями.

2. Если вы замените break button.click() свой на, то ваш код с вызовом функции будет эквивалентен встроенному коду. В противном случае вы пытаетесь вызвать button.click() в конце for цикла. И в вашем for цикле также есть потенциальная проблема, поскольку вы создаете локальную переменную с именем button , совпадающим с именем вашего класса. Это помогает?

3. @Karl Knetchel Спасибо. Я обновил свой пост, чтобы сделать его, надеюсь, более читаемым и перейти прямо к делу.

4. @Random Davis Ну, вы точно определили мою проблему: два кода, которые я считаю эквивалентными, не выполняются одинаково. И я исправил неправильное написание, на которое вы указываете, заменив «для кнопки в currentMenu.ButtonList» на «для, но в currentMenu.ButtonList». Он по-прежнему не решает мою проблему.

Ответ №1:

Трудно сказать, потому что включенный код не показывает создание экземпляра a button , но, вероятно, вам нужно убедиться, что он ссылается на глобальную область:

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

Ваш класс button был бы лучше, если бы он просто оставался только кнопкой. Итак, это касается местоположения и метки, цветов, независимо от того, нажата ли она, не нажата, наведена и т. Д. Но то, что это не так, также важно. Кнопка — это не меню, она не должна знать о меню и не должна обрабатывать меню (или очищать буфер отображения!).

Объекты создают лучший дизайн и более чистый код, когда они кратко описывают, что они делают.

Комментарии:

1. Спасибо. Я не знал о «глобальном» в Python, но я определил проблему следующим образом: он изменяет currentMenu только локально в методе, но currentMenu принимает его предыдущее значение, как только программа завершит выполнение метода. Итак, это решает мою проблему. Кроме того, что касается моего класса button, его цель — указывать на меню при нажатии и выделять при наведении курсора мыши: вместо написания функций и определения кнопки со списком я счел более практичным определить класс со своими собственными методами. Но не стесняйтесь давать мне советы по улучшению эргономики моей программы.