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

Python Arcade中实现按钮点击时窗口显示文本的方法及骰子程序优化咨询

Python Arcade中实现按钮点击时窗口显示文本的方法及骰子程序优化咨询

嗨!我来帮你搞定这几个问题,让你的骰子程序更顺手~

一、让骰子结果显示在窗口中

目前你是用print()把结果输出到终端,要在窗口里显示的话,我们可以通过以下几步实现:

  1. 在MyWindow的__init__方法里添加一个属性,用来存储当前的骰子结果:
    self.roll_result = ""
    
  2. 把每个on_click_dX方法里的print()改成更新这个属性,比如D20的点击方法:
    def on_click_d20(self, event):
        self.roll_result = str(randint(1,20))
    
  3. 在on_draw方法中,画完背景和UI组件后,用arcade.draw_text把结果画在窗口显眼的位置(比如顶部中间):
    arcade.draw_text(self.roll_result, self.width/2, self.height - 50,
                    arcade.color.WHITE, 40, anchor_x="center",
                    font_name="Kenney Mini Square")
    

二、背景绘制的正确性

看你的代码,on_draw方法里的缩进有点小问题(arcade.start_render()前面多了不必要的缩进),不过整体逻辑是对的:先渲染背景,再画UI管理器的内容,这样UI会显示在背景上方。调整后的正确on_draw逻辑如下:

def on_draw(self):
    arcade.start_render()
    # 绘制自适应窗口大小的背景图
    arcade.draw_texture_rectangle(self.width/2, self.height/2, 
                                 self.width, self.height, self.background)
    self.manager.draw()
    # 绘制骰子结果
    arcade.draw_text(self.roll_result, self.width/2, self.height - 50,
                    arcade.color.WHITE, 40, anchor_x="center",
                    font_name="Kenney Mini Square")

这里把背景图的尺寸改成和窗口一致,这样窗口调整大小时背景也能完美适配~

三、代码简化建议

你的代码里有不少重复的部分,这里给你几个优化方向:

  1. 简化按钮样式定义:所有骰子按钮的样式大部分和默认样式重复,我们可以基于默认样式修改差异部分,不用每次都写全所有属性:

    # 先定义基础默认样式
    default_style = {
        "font_name": "Kenney Mini Square",
        "font_size": 15,
        "font_color": arcade.color.WHITE,
        "border_width": 4,
        "border_color": None,
        "bg_color": (21, 19, 21),
        "bg_color_pressed": arcade.color.WHITE,
        "border_color_pressed": arcade.color.WHITE,
        "font_color_pressed": arcade.color.BLACK,
    }
    # 粉色按钮样式基于默认样式修改
    pink_style = default_style.copy()
    pink_style.update({
        "font_size": 23,
        "font_color": arcade.color.CHERRY_BLOSSOM_PINK,
        "bg_color": arcade.color.BLACK,
        "bg_color_pressed": arcade.color.CHERRY_BLOSSOM_PINK,
        "border_color_pressed": arcade.color.CHERRY_BLOSSOM_PINK,
        "font_color_pressed": arcade.color.BLACK,
    })
    

    这样能砍掉一大段重复代码~

  2. 批量创建骰子按钮:把所有骰子的信息(按钮文本、取值范围、样式)做成一个列表,循环创建按钮并绑定事件,不用逐个写按钮创建和点击方法:

    # 定义所有骰子的信息列表
    dice_list = [
        ("D20", 1, 20, blue_style),
        ("D12", 1, 12, pink_style),
        ("D10", 1, 10, green_style),
        ("D8", 1, 8, purple_style),
        ("D6", 1, 6, yellow_style),
        ("D4", 1, 4, orange_style),
    ]
    # 循环创建左侧3个按钮
    for text, min_val, max_val, style in dice_list[:3]:
        button = arcade.gui.UIFlatButton(text=text, width=200, style=style)
        # 用lambda绑定点击事件,捕获当前骰子的取值范围
        button.on_click = lambda e, m=min_val, mx=max_val: setattr(self, "roll_result", str(randint(m, mx)))
        self.v_box.add(button.with_space_around(bottom=20))
    

    这样就不用单独写6个on_click_dX方法啦!

  3. 简化退出按钮:不用单独写QuitButton类,直接把arcade.exit绑定到按钮的点击事件即可:

    quit_button = arcade.gui.UIFlatButton(text="Quit", width=200, style=default_style)
    quit_button.on_click = lambda e: arcade.exit()
    self.v3_box.add(quit_button)
    

修改后的完整代码

import arcade
import arcade.gui
from random import randint

class MyWindow(arcade.Window):
    def __init__(self):
        super().__init__(800, 600, "DICE ROLLER", resizable=True)

        self.background = arcade.load_texture("galaxy.jpg")
        # 存储当前骰子结果
        self.roll_result = ""

        # --- UI管理器初始化
        self.manager = arcade.gui.UIManager()
        self.manager.enable()

        # 定义基础按钮样式
        default_style = {
            "font_name": "Kenney Mini Square",
            "font_size": 15,
            "font_color": arcade.color.WHITE,
            "border_width": 4,
            "border_color": None,
            "bg_color": (21, 19, 21),
            "bg_color_pressed": arcade.color.WHITE,
            "border_color_pressed": arcade.color.WHITE,
            "font_color_pressed": arcade.color.BLACK,
        }

        # 基于基础样式创建其他按钮样式
        pink_style = default_style.copy()
        pink_style.update({
            "font_size": 23,
            "font_color": arcade.color.CHERRY_BLOSSOM_PINK,
            "bg_color": arcade.color.BLACK,
            "bg_color_pressed": arcade.color.CHERRY_BLOSSOM_PINK,
            "border_color_pressed": arcade.color.CHERRY_BLOSSOM_PINK,
            "font_color_pressed": arcade.color.BLACK,
        })

        blue_style = default_style.copy()
        blue_style.update({
            "font_size": 23,
            "font_color": arcade.color.BABY_BLUE_EYES,
            "bg_color": arcade.color.BLACK,
            "bg_color_pressed": arcade.color.BABY_BLUE_EYES,
            "border_color_pressed": arcade.color.BABY_BLUE_EYES,
            "font_color_pressed": arcade.color.BLACK,
        })

        green_style = default_style.copy()
        green_style.update({
            "font_size": 23,
            "font_color": arcade.color.LIGHT_MOSS_GREEN,
            "bg_color": arcade.color.BLACK,
            "bg_color_pressed": arcade.color.LIGHT_MOSS_GREEN,
            "border_color_pressed": arcade.color.LIGHT_MOSS_GREEN,
            "font_color_pressed": arcade.color.BLACK,
        })

        purple_style = default_style.copy()
        purple_style.update({
            "font_size": 23,
            "font_color": arcade.color.BRIGHT_UBE,
            "bg_color": arcade.color.BLACK,
            "bg_color_pressed": arcade.color.BRIGHT_UBE,
            "border_color_pressed": arcade.color.BRIGHT_UBE,
            "font_color_pressed": arcade.color.BLACK,
        })

        yellow_style = default_style.copy()
        yellow_style.update({
            "font_size": 23,
            "font_color": arcade.color.LEMON_CHIFFON,
            "bg_color": arcade.color.BLACK,
            "bg_color_pressed": arcade.color.LEMON_CHIFFON,
            "border_color_pressed": arcade.color.LEMON_CHIFFON,
            "font_color_pressed": arcade.color.BLACK,
        })

        orange_style = default_style.copy()
        orange_style.update({
            "font_size": 23,
            "font_color": arcade.color.RAJAH,
            "bg_color": arcade.color.BLACK,
            "bg_color_pressed": arcade.color.RAJAH,
            "border_color_pressed": arcade.color.RAJAH,
            "font_color_pressed": arcade.color.BLACK,
        })

        # 创建按钮布局容器
        self.v_box = arcade.gui.UIBoxLayout(x=200,y=200)
        self.v2_box = arcade.gui.UIBoxLayout()
        self.v3_box = arcade.gui.UIBoxLayout()

        # 批量创建骰子按钮
        dice_list = [
            ("D20", 1, 20, blue_style),
            ("D12", 1, 12, pink_style),
            ("D10", 1, 10, green_style),
            ("D8", 1, 8, purple_style),
            ("D6", 1, 6, yellow_style),
            ("D4", 1, 4, orange_style),
        ]

        # 左侧按钮组
        for text, min_val, max_val, style in dice_list[:3]:
            button = arcade.gui.UIFlatButton(text=text, width=200, style=style)
            button.on_click = lambda e, m=min_val, mx=max_val: setattr(self, "roll_result", str(randint(m, mx)))
            self.v_box.add(button.with_space_around(bottom=20))

        # 右侧按钮组
        for text, min_val, max_val, style in dice_list[3:]:
            button = arcade.gui.UIFlatButton(text=text, width=200, style=style)
            button.on_click = lambda e, m=min_val, mx=max_val: setattr(self, "roll_result", str(randint(m, mx)))
            self.v2_box.add(button.with_space_around(bottom=20))

        # 退出按钮
        quit_button = arcade.gui.UIFlatButton(text="Quit", width=200, style=default_style)
        quit_button.on_click = lambda e: arcade.exit()
        self.v3_box.add(quit_button)

        # 将布局添加到UI管理器
        self.manager.add(
            arcade.gui.UIAnchorWidget(
                anchor_x="left",
                align_x=185,
                anchor_y="center_y",
                align_y=25,
                child=self.v_box)
        )
        self.manager.add(
            arcade.gui.UIAnchorWidget(
                anchor_x="right",
                align_x=-185,
                anchor_y="center_y",
                align_y=25,
                child=self.v2_box)
        )

        self.manager.add(
            arcade.gui.UIAnchorWidget(
                anchor_x="center_x",
                anchor_y="center_y",
                align_y=-150,
                child=self.v3_box)
        )

    def on_draw(self):
        arcade.start_render()
        # 绘制自适应窗口的背景
        arcade.draw_texture_rectangle(self.width/2, self.height/2, 
                                     self.width, self.height, self.background)
        self.manager.draw()
        # 绘制骰子结果
        if self.roll_result:
            arcade.draw_text(self.roll_result, self.width/2, self.height - 50,
                            arcade.color.WHITE, 40, anchor_x="center",
                            font_name="Kenney Mini Square")

window = MyWindow()
arcade.run()

你的程序界面截图

骰子程序界面截图

备注:内容来源于stack exchange,提问作者Emily A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:38:08