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

Discord打卡机器人按钮与文本显示顺序异常求助

Discord Bot 按钮与文本顺序调整方案

问题原因

Discord平台的消息UI布局有固定规则:消息内容(文本)始终显示在组件(按钮、选择菜单等)的上方,这是平台原生设计,无法直接修改该显示顺序。你的代码直接将文本内容与按钮视图绑定发送/编辑,自然会呈现文本在前、按钮在后的效果。

解决方案

如果你需要实现视觉上“按钮在前、文本在后”的效果,可以采用以下两种可行方案:


方案1:分离为两条独立消息(推荐)

发送两条消息:第一条仅包含按钮,第二条显示打卡日志文本,视觉上按钮在前、文本在后,同时在按钮回调中更新文本消息内容。

修改后的核心代码如下:

import discord
from datetime import datetime
import settings

texto1 = []
texto2 = []
bot = discord.Client(intents=discord.Intents.all())
# 新增全局变量存储按钮消息和日志消息
button_message = None
log_message = None

class MyView(discord.ui.View):
    @discord.ui.button(label="Entrar", style=discord.ButtonStyle.green, custom_id="entrar")
    async def entrar_button_callback(self, interaction: discord.Interaction, button: discord.ui.Button):
        if interaction.user.display_name not in texto1:
            texto1.append(interaction.user.display_name)
            texto2.append(f"{interaction.user.display_name} entrou às {datetime.now().strftime('%H:%M:%S')}")
            # 更新日志消息内容
            await log_message.edit(content=get_text())
        await interaction.response.defer()

    @discord.ui.button(label="Sair", style=discord.ButtonStyle.red, custom_id="sair")
    async def sair_button_callback(self, interaction: discord.Interaction, button: discord.ui.Button):
        if interaction.user.display_name in texto1:
            texto1.remove(interaction.user.display_name)
            texto2.append(f"{interaction.user.display_name} saiu às {datetime.now().strftime('%H:%M:%S')}")
            # 更新日志消息内容
            await log_message.edit(content=get_text())
        await interaction.response.defer()

async def update_message(channel):
    global button_message, log_message
    # 先发送仅含按钮的消息(内容为空)
    view = MyView()
    button_message = await channel.send(content="", view=view)
    # 发送打卡日志文本消息
    text = get_text()
    log_message = await channel.send(text)

def get_text():
    text1 = '\n'.join(texto1) if texto1 else 'Ninguém'
    text2 = '\n'.join(texto2) if texto2 else 'Nenhum registro ainda'
    text = f"**Quem está trabalhando:**\n{text1}\n\n**Log de chegada e saída:**\n{text2}"
    return text

@bot.event
async def on_ready():
    print('Bot está online')
    channel = bot.get_channel(1105561415038812311)
    await update_message(channel)

bot.run(settings.DISCORD_API_SECRET)

方案2:嵌入消息排版优化(同一消息内)

由于组件始终在消息底部,可将日志文本放入嵌入式消息中,消息内容仅保留简短提示,视觉上弱化文本在前的感知。示例代码调整如下:

修改get_text为生成Embed的函数:

def get_embed():
    text1 = '\n'.join(texto1) if texto1 else 'Ninguém'
    text2 = '\n'.join(texto2) if texto2 else 'Nenhum registro ainda'
    embed = discord.Embed(title="Registro de Trabalho", color=discord.Color.blue())
    embed.add_field(name="Quem está trabalhando:", value=text1, inline=False)
    embed.add_field(name="Log de chegada e saída:", value=text2, inline=False)
    return embed

然后修改update_message和回调函数:

async def update_message(channel):
    view = MyView()
    embed = get_embed()
    # 消息内容留空,仅发送Embed和按钮
    message = await channel.send(embed=embed, view=view)

# 按钮回调中修改为更新Embed
async def entrar_button_callback(self, interaction: discord.Interaction, button: discord.ui.Button):
    if interaction.user.display_name not in texto1:
        texto1.append(interaction.user.display_name)
        texto2.append(f"{interaction.user.display_name} entrou às {datetime.now().strftime('%H:%M:%S')}")
        await interaction.message.edit(embed=get_embed(), view=self)
    await interaction.response.defer()

此方案中按钮会显示在Embed下方,但通过Embed的结构化排版,可让整体视觉更接近你想要的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:12:39