Python Arcade中实现按钮点击时窗口显示文本的方法及骰子程序优化咨询
Python Arcade中实现按钮点击时窗口显示文本的方法及骰子程序优化咨询
嗨!我来帮你搞定这几个问题,让你的骰子程序更顺手~
一、让骰子结果显示在窗口中
目前你是用print()把结果输出到终端,要在窗口里显示的话,我们可以通过以下几步实现:
- 在
MyWindow的__init__方法里添加一个属性,用来存储当前的骰子结果:self.roll_result = "" - 把每个
on_click_dX方法里的print()改成更新这个属性,比如D20的点击方法:def on_click_d20(self, event): self.roll_result = str(randint(1,20)) - 在
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")
这里把背景图的尺寸改成和窗口一致,这样窗口调整大小时背景也能完美适配~
三、代码简化建议
你的代码里有不少重复的部分,这里给你几个优化方向:
简化按钮样式定义:所有骰子按钮的样式大部分和默认样式重复,我们可以基于默认样式修改差异部分,不用每次都写全所有属性:
# 先定义基础默认样式 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, })这样能砍掉一大段重复代码~
批量创建骰子按钮:把所有骰子的信息(按钮文本、取值范围、样式)做成一个列表,循环创建按钮并绑定事件,不用逐个写按钮创建和点击方法:
# 定义所有骰子的信息列表 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方法啦!简化退出按钮:不用单独写
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
相关产品推荐
相关产品推荐

