当我将鼠标悬停在 pygame 上时,为什么我的按钮不会改变颜色?

2023-12-13

我是 pygame 的新手,一直在尝试创建一个带有一些按钮的简单界面。当鼠标悬停在按钮上时,我无法让按钮改变颜色。

我已经成功创建了按钮,但无法让它与我的鼠标交互。 该代码创建一个按钮对象,其中包含一个绿色按钮的实例。 当鼠标悬停在上面时,它应该将按钮从绿色更改为红色。

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()

StartScreen.fill(white)

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, (float(self.x-2), float(self.y-2), float(self.w+4), float(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):
        if pos[0] > self.x and pos[0] < self.x + self.w:
            if pos[1] > self.y and pos[1] < self.y + self.h:
                return True

        return False

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

run = True

GrnBut = Buttons(green, 150, 200, 90, 100, 'Press')
while run:
    redrawWindow()
    pygame.display.update()

    for event in pygame.event.get():
        pos = pygame.mouse.get_pos()

        Exit = False
        while not Exit:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    print(event)
                    pygame.quit()
                    quit()

        if event.type == pygame.MOUSEBUTTONDOWN:
            if GrnBut.MouseOver(pos):
                print("Clicked")

        if event.type == pygame.MOUSEMOTION:
            if GrnBut.MouseOver(pos):
                GrnBut.color = red
            else:
                GrnBut.color = green



您的主要问题是您的事件循环内有一个嵌套的事件循环:

while run:         # outer loop
    redrawWindow()
    pygame.display.update()

    for event in pygame.event.get():
        pos = pygame.mouse.get_pos()

        Exit = False
        while not Exit:       # inner loop
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    print(event)
                    pygame.quit()
                    quit()

当执行到达这个内循环时,两者都没有redrawWindow() or GrnBut.MouseOver(pos)再次被调用。

只需摆脱它即可:

while run:
    redrawWindow()
    pygame.display.update()

    for event in pygame.event.get():
        pos = pygame.mouse.get_pos()

        if event.type == pygame.QUIT:
            print(event)
            pygame.quit()
            quit()

可以通过使用 pygame 的一些功能来改进您的代码,例如Sprite and Rect类。

以下是如何创建更“pygamy”版本的示例Button支持多个不同按钮的类:

import pygame

pygame.init()

display_width = 1200
display_height = 600

# use python style variable names (lowercase)
screen = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Log In')
clock = pygame.time.Clock()

# load the font only once instead of every frame
font = pygame.font.SysFont('comicsans', 20)

# class name should be singular
class Button(pygame.sprite.Sprite):
    # 1) no need to have 4 parameters for position and size, use pygame.Rect instead
    # 2) let the Button itself handle which color it is
    # 3) give a callback function to the button so it can handle the click itself 
    def __init__(self, color, color_hover, rect, callback, text='', outline=None):
        super().__init__()
        self.text = text
        # a temporary Rect to store the size of the button
        tmp_rect = pygame.Rect(0, 0, *rect.size)

        # create two Surfaces here, one the normal state, and one for the hovering state
        # we create the Surfaces here once, so we can simple blit them and dont have
        # to render the text and outline again every frame
        self.org = self._create_image(color, outline, text, tmp_rect)
        self.hov = self._create_image(color_hover, outline, text, tmp_rect)

        # in Sprites, the image attribute holds the Surface to be displayed...
        self.image = self.org
        # ...and the rect holds the Rect that defines it position
        self.rect = rect
        self.callback = callback

    def _create_image(self, color, outline, text, rect):
        # function to create the actual surface
        # see how we can make use of Rect's virtual attributes like 'size'
        img = pygame.Surface(rect.size)
        if outline:
            # here we can make good use of Rect's functions again
            # first, fill the Surface in the outline color
            # then fill a rectangular area in the actual color
            # 'inflate' is used to 'shrink' the rect
            img.fill(outline)
            img.fill(color, rect.inflate(-4, -4))
        else:
            img.fill(color)

        # render the text once here instead of every frame
        if text != '':
            text_surf = font.render(text, 1, pygame.Color('black'))
            # again, see how easy it is to center stuff using Rect's attributes like 'center'
            text_rect = text_surf.get_rect(center=rect.center)
            img.blit(text_surf, text_rect)
        return img

    def update(self, events):
        # here we handle all the logic of the Button
        pos = pygame.mouse.get_pos()
        hit = self.rect.collidepoint(pos)
        # if the mouse in inside the Rect (again, see how the Rect class
        # does all the calculation for use), use the 'hov' image instead of 'org'
        self.image = self.hov if hit else self.org
        for event in events:
            # the Button checks for events itself.
            # if this Button is clicked, it runs the callback function
            if event.type == pygame.MOUSEBUTTONDOWN and hit:
                self.callback(self)

run = True

# we store all Sprites in a Group, so we can easily
# call the 'update' and 'draw' functions of the Buttons
# in the main loop
sprites = pygame.sprite.Group()
sprites.add(Button(pygame.Color('green'), 
                   pygame.Color('red'), 
                   pygame.Rect(150, 200, 90, 100), 
                   lambda b: print(f"Button '{b.text}' was clicked"),
                   'Press',
                   pygame.Color('black')))

sprites.add(Button(pygame.Color('dodgerblue'), 
                   pygame.Color('lightgreen'), 
                   pygame.Rect(300, 200, 90, 100), 
                   lambda b: print(f"Click me again!"),
                   'Another'))

while run:
    events = pygame.event.get()
    for event in events:
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()

    # update all sprites
    # it now doesn't matter if we have one or 200 Buttons
    sprites.update(events)
    # clear the screen
    screen.fill(pygame.Color('white'))
    # draw all sprites/Buttons
    sprites.draw(screen)
    pygame.display.update()
    # limit framerate to 60 FPS
    clock.tick(60)

enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当我将鼠标悬停在 pygame 上时,为什么我的按钮不会改变颜色? 的相关文章

  • Python 中的 Lanczos 插值与 2D 图像

    我尝试重新缩放 2D 图像 灰度 图像大小为 256x256 所需输出为 224x224 像素值范围从 0 到 1300 我尝试了两种使用 Lanczos 插值来重新调整它们的方法 首先使用PIL图像 import numpy as np
  • 在 python 程序中合并第三方库的最佳实践是什么?

    下午好 我正在为我的工作编写一个中小型Python程序 该任务需要我使用 Excel 库xlwt and xlrd 以及一个用于查询 Oracle 数据库的库 称为CX Oracle 我正在通过版本控制系统 即CVS 开发该项目 我想知道围
  • 将 saxon 与 python 结合使用

    我需要使用 python 处理 XSLT 目前我正在使用仅支持 XSLT 1 的 lxml 现在我需要处理 XSLT 2 有没有办法将 saxon XSLT 处理器与 python 一起使用 有两种可能的方法 设置一个 HTTP 服务 接受
  • 将数据从 python pandas 数据框导出或写入 MS Access 表

    我正在尝试将数据从 python pandas 数据框导出到现有的 MS Access 表 我想用已更新的数据替换 MS Access 表 在 python 中 我尝试使用 pandas to sql 但收到错误消息 我觉得很奇怪 使用 p
  • 将 Matplotlib 误差线放置在不位于条形中心的位置

    我正在 Matplotlib 中生成带有错误栏的堆积条形图 不幸的是 某些层相对较小且数据多样 因此多个层的错误条可能重叠 从而使它们难以或无法读取 Example 有没有办法设置每个误差条的位置 即沿 x 轴移动它 以便重叠的线显示在彼此
  • OpenCV Python cv2.mixChannels()

    我试图将其从 C 转换为 Python 但它给出了不同的色调结果 In C Transform it to HSV cvtColor src hsv CV BGR2HSV Use only the Hue value hue create
  • Python(Selenium):如何通过登录重定向/组织登录登录网站

    我不是专业程序员 所以请原谅任何愚蠢的错误 我正在做一些研究 我正在尝试使用 Selenium 登录数据库来搜索大约 1000 个术语 我有两个问题 1 重定向到组织登录页面后如何使用 Selenium 登录 2 如何检索数据库 在我解决
  • Python - StatsModels、OLS 置信区间

    在 Statsmodels 中 我可以使用以下方法拟合我的模型 import statsmodels api as sm X np array 22000 13400 47600 7400 12000 32000 28000 31000 6
  • Flask 会话变量

    我正在用 Flask 编写一个小型网络应用程序 当两个用户 在同一网络下 尝试使用应用程序时 我遇到会话变量问题 这是代码 import os from flask import Flask request render template
  • 从字符串中删除识别的日期

    作为输入 我有几个包含不同格式日期的字符串 例如 彼得在16 45 我的生日是1990年7月8日 On 7 月 11 日星期六我会回家 I use dateutil parser parse识别字符串中的日期 在下一步中 我想从字符串中删除
  • PyUSB 1.0:NotImplementedError:此平台不支持或未实现操作

    我刚刚开始使用 pyusb 基本上我正在玩示例代码here https github com walac pyusb blob master docs tutorial rst 我使用的是 Windows 7 64 位 并从以下地址下载 z
  • 基于代理的模拟:性能问题:Python vs NetLogo & Repast

    我正在 Python 3 中复制一小段 Sugarscape 代理模拟模型 我发现我的代码的性能比 NetLogo 慢约 3 倍 这可能是我的代码的问题 还是Python的固有限制 显然 这只是代码的一个片段 但 Python 却花费了三分
  • AWS EMR Spark Python 日志记录

    我正在 AWS EMR 上运行一个非常简单的 Spark 作业 但似乎无法从我的脚本中获取任何日志输出 我尝试过打印到 stderr from pyspark import SparkContext import sys if name m
  • 在Python中获取文件描述符的位置

    比如说 我有一个原始数字文件描述符 我需要根据它获取文件中的当前位置 import os psutil some code that works with file lp lib open path to file p psutil Pro
  • 如何在 Python 中追加到 JSON 文件?

    我有一个 JSON 文件 其中包含 67790 1 kwh 319 4 现在我创建一个字典a dict我需要将其附加到 JSON 文件中 我尝试了这段代码 with open DATA FILENAME a as f json obj js
  • 如何计算 pandas 数据帧上的连续有序值

    我试图从给定的数据帧中获取连续 0 值的最大计数 其中包含来自 pandas 数据帧的 id date value 列 如下所示 id date value 354 2019 03 01 0 354 2019 03 02 0 354 201
  • Python 类继承 - 诡异的动作

    我观察到类继承有一个奇怪的效果 对于我正在处理的项目 我正在创建一个类来充当另一个模块的类的包装器 我正在使用第 3 方 aeidon 模块 用于操作字幕文件 但问题可能不太具体 以下是您通常如何使用该模块 project aeidon P
  • 导入错误:没有名为 site 的模块 - mac

    我已经有这个问题几个月了 每次我想获取一个新的 python 包并使用它时 我都会在终端中收到此错误 ImportError No module named site 我不知道为什么会出现这个错误 实际上 我无法使用任何新软件包 因为每次我
  • 如何使用 Pycharm 安装 tkinter? [复制]

    这个问题在这里已经有答案了 I used sudo apt get install python3 6 tk而且效果很好 如果我在终端中打开 python Tkinter 就可以工作 但我无法将其安装在我的 Pycharm 项目上 pip
  • 如何将输入读取为数字?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 Why are x and y下面的代码中使用字符串而不是整数 注意 在Python 2

随机推荐

  • 使用 WCF 接口

    我已经用谷歌搜索并阅读了几个小时 但找不到任何人可以处理我的具体情况 我想在 WCF 服务契约中使用接口来将服务与线路两端使用的类松散耦合 这将使我们能够拥有一个低级程序集 其中仅包含我们可以交给顾问的服务和数据契约 仅接口 在网络的一端
  • ggplot2 热图 2 种不同的配色方案 - 混淆矩阵:与错误分类不同的配色方案中的匹配

    我改编了混淆矩阵的热图这个答案 不过我想扭转它 在对角线中 从左上到右下 是匹配项 正确的分类 我的目标是在黄色调色板中绘制这条对角线 红色调色板中的不匹配 因此除了对角线中的瓷砖之外的所有瓷砖 In my plot cm函数我可以得到对角
  • sails:如何将数组的数组转换为json对象

    我正在尝试读取我上传的 xlsx find 并尝试将数组数组转换为 json 键值对对象 所以我正在尝试下面的代码片段 var fs uploadedFiles 0 fd var xlsxRows require xlsx rows var
  • ONVIF #PasswordDigest 的公式是什么

    我正在研究发送 GetDeviceInformation 的 ONVIF 这是必需的 wsse UsernameToken 经过查资料权威 有两个公式 1 通过 ONVIF Core Specification v241 pdf 5 12
  • 在Python中用连字符分割单词时创建两个新列

    我有一个数据集 df 其中有一列包含两个由连字符分隔的单词 我想为每个分割值创建两个新列 Value Type ABC California Low DEF New York Low 期望的输出 Value1 Value2 Type ABC
  • 如何解决错误“System.InvalidCastException - 列包含 NULL 数据”

    当我运行应用程序并搜索时出现此错误 System InvalidCastException 列包含 NULL 数据 在 Oracle ManagedDataAccess Client OracleDataReader GetDecimal
  • 如何自动重新加载我的gunicorn服务器?

    我想知道如何自动重新启动我的gunicorn 服务器 我的 django 项目代码更改后 目前 我在进行更改后正在手动重新启动 只需终止进程并重新加载即可 但这不是一个好方法 所以我想知道如何在代码更改后自动执行相同的操作 我也在使用ngi
  • 在 IntelliJ 15 中运行临时文件时出错

    Code 运行时我得到以下信息 参考 https www youtube com watch v AmeDNZ 86ig 设置 此处没有更改任何内容 找到了解决方案 请参阅此处的记录 Eugene Zhuravlev 2016 年 2 月
  • 从另一个运行空间向表单添加元素

    我有一个表单 一旦准备好 就会添加几个元素 例如 列表 添加它们可能需要一些时间 从几分之一秒到几分钟 因此 我想将处理添加到单独的线程 子线程 中 元素的数量事先未知 例如 文件夹中有多少个文件 因此它们是在子流中创建的 当子流中的处理结
  • Matplotlib 垂直拉伸 histogram2d

    我正在使用这段代码 fig plt figure num 2 figsize 8 8 dpi 80 facecolor w edgecolor k x y xy for xy in zip self pulse time distance
  • 两个单词之间的正则表达式 - 或者到行尾?

    简单的正则表达式问题 我有一个非常基本的表达式 用于在两个单词之间提取文本 BEGN DETAIL 当两个单词都存在时 效果很好 但在某些情况下 没有 DETAIL 所以在这些情况下 我只想捕获到文本的末尾 这可以用单个表达式实现吗 还是我
  • 包含美国货币的正则表达式/grep 字符串

    我有一个字符串列表 其中一些包含美元数字 例如 34232 foo n bar 有没有一个 r 只能返回包含美元金额的字符串的命令 谢谢你 Use 以保护 否则意味着 字符串结尾 grep 0 9 c 123 567 abc 57 abc
  • 错误:scalac:错误的符号引用。 SQLContext.class 中的签名引用包 org.apache.spark 中不可用的 Logging 类型

    当我使用 IntelliJ IDEA 编译 scala 文件时 显示以下错误 错误 scalac 错误的符号引用 SQLContext class 中的签名引用包 org apache spark 中不可用的 Logging 类型 当前类路
  • 如何使用 JavaScript 创建包含文件和发布数据的 AJAX 请求

    如何使用 JavaScript 创建一个 HTTP 请求来发送一个文件和一些可由 PHP 服务器接收的发布数据 我找到了以下建议 但似乎并不完整 xhr open POST upload php var boundary boundary
  • WCF 服务的 REST/SOAP 端点

    我有一个 WCF 服务 我想将其公开为 RESTful 服务和 SOAP 服务 以前有人做过类似的事情吗 您可以在两个不同的端点中公开该服务 SOAP 可以使用支持 SOAP 的绑定 例如basicHttpBinding RESTful可以
  • ArrayList 作为全局变量

    我创建了这样扩展应用程序的类 package com appnetics import java util ArrayList import android app Application public class GlobalVariab
  • 如何使用opencv copyTo()函数?

    我已通读copyTo 的文档但我仍然对如何将此函数应用于以下代码感到困惑 这个答案指出我们可以使用 copyTo 函数代替 255 x 在这种情况下如何应用这个功能 我希望有一个代码片段 Compute the gradient map o
  • 修改exe资源中的字符串

    我该如何修改buffer在下面的代码中然后保存可执行文件资源中的更改 我正在寻找类似的东西SetString handle index buffer size var hExe Cardinal buffer array 0 4097 of
  • Polymer 1.x:从铁列表中删除项目

    我正在尝试从中删除一个项目iron list使用以下代码 my element html
  • 当我将鼠标悬停在 pygame 上时,为什么我的按钮不会改变颜色?

    我是 pygame 的新手 一直在尝试创建一个带有一些按钮的简单界面 当鼠标悬停在按钮上时 我无法让按钮改变颜色 我已经成功创建了按钮 但无法让它与我的鼠标交互 该代码创建一个按钮对象 其中包含一个绿色按钮的实例 当鼠标悬停在上面时 它应该