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

Pygame按钮鼠标悬停不改变颜色问题求助

解决Pygame按钮鼠标悬停变色问题

嘿,我看了你的代码,问题出在嵌套的事件循环和鼠标位置获取的时机上,这两个点导致你的按钮没法正确响应鼠标移动。让我给你拆解一下问题,再给你修正后的代码:

问题分析

  • 嵌套循环卡死事件处理:你在主while run循环里又加了一个while not Exit循环,这会让程序卡在内部循环里,主循环的界面刷新和事件响应逻辑完全失效,鼠标移动的事件根本没法被正确处理。
  • 鼠标位置没有实时更新:你把pos = pygame.mouse.get_pos()放在了外层事件遍历的外面,而且在内部循环里完全没更新这个变量,程序一直用的是最开始的鼠标位置,自然没法判断当前鼠标是不是在按钮上。

修正后的代码

import pygame
pygame.init()

display_width = 1200
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)

StartScreen = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Log In')
clock = pygame.time.Clock()

class Buttons():
    def __init__(self, color, x, y, width, height, text=''):
        self.color = color
        self.x = int(x)
        self.y = int(y)
        self.w = int(width)
        self.h = int(height)
        self.text = text

    def Draw(self, StartScreen, outline=None):
        if outline:
            pygame.draw.rect(StartScreen, outline, (self.x-2, self.y-2, self.w+4, self.h+4), 0)
        pygame.draw.rect(StartScreen, self.color, (self.x, self.y, self.w, self.h), 0)
        if self.text != '':
            font = pygame.font.SysFont('comicsans', 20)
            text = font.render(self.text, 1, black)
            StartScreen.blit(text, (self.x + (self.w/2 - text.get_width()/2), self.y + (self.h/2 - text.get_height()/2)))

    def MouseOver(self, pos):
        # 简化边界判断逻辑,更易读
        return self.x < pos[0] < self.x + self.w and self.y < pos[1] < self.y + self.h

def redrawWindow():
    StartScreen.fill(white)
    GrnBut.Draw(StartScreen, black)

run = True
GrnBut = Buttons(green, 150, 200, 90, 100, 'Press')

while run:
    # 控制帧率,避免占用过多系统资源
    clock.tick(60)
    redrawWindow()
    pygame.display.update()

    # 每次循环都更新当前鼠标位置
    pos = pygame.mouse.get_pos()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
            pygame.quit()
            quit()
        
        # 处理鼠标点击事件
        if event.type == pygame.MOUSEBUTTONDOWN:
            if GrnBut.MouseOver(pos):
                print("Clicked")
        
        # 处理鼠标移动事件,直接用事件自带的pos更准确
        if event.type == pygame.MOUSEMOTION:
            if GrnBut.MouseOver(event.pos):
                GrnBut.color = red
            else:
                GrnBut.color = green

关键修改点

  1. 移除了嵌套的while not Exit循环,所有事件处理都统一放在主循环中,确保程序能正常响应所有输入事件。
  2. 每次主循环迭代都更新鼠标位置,或者在MOUSEMOTION事件里直接用event.pos获取当前鼠标位置(这个方式更精准,因为事件本身就携带了触发时的坐标)。
  3. 简化了MouseOver方法的判断逻辑,让代码更简洁易读。
  4. 添加了clock.tick(60)控制帧率,让程序运行更稳定,不会过度占用CPU资源。

这样修改后,你的按钮就能在鼠标悬停时从绿色变成红色,点击也能正常响应啦!

内容的提问来源于stack exchange,提问作者Wispaman8

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:00:31