如何创建动态持久按钮?

huangapple go评论58阅读模式
英文:

How do I make dynamically persistant buttons?

问题

我正在尝试创建动态持久性按钮,但不确定如何操作。我正在制作一个投票机器人。我希望的情况是,如果机器人重置,我希望投票中的按钮仍然可以使用。我尝试查看了一些教程和discord.py文档,但未找到有用或相关的内容。

以下是我的代码:

import discord
from discord.ext import commands
from discord import app_commands

# 我的按钮类是在某人按下按钮时的回调
class MyButton(discord.ui.Button):
    async def callback(self, interaction: discord.Interaction):
        # 为类设置变量
        button_id = self.custom_id
        user_id = interaction.user.id
        timestamp = interaction.created_at
        message_id = interaction.message.id  # 访问消息ID #获取消息ID
        print(f"Received button click: {button_id}") #用于消息ID的打印
        # 按下按钮后的响应消息
        await interaction.response.send_message(f"You clicked {self.label}")

# My View类
class MyView(discord.ui.View):
    def __init__(self, options_and_ids): # options_and_ids变量是从polls类中压缩的列表
        super().__init__(timeout=None)
        
        # 根据列表动态创建消息的按钮。
        for option, button_id in options_and_ids:
            button = MyButton(label=option, custom_id=button_id)
            self.add_item(button)

class polls(commands.Cog):
    def __init__(self, bot: commands.Bot):
        self.bot = bot

    # 用于我尝试使用的非动态按钮的设置钩子。
    async def setup_hook(self) -> None:
        self.add_view(MyView())

    @app_commands.command(name="poll", description="创建一个投票。")
    @app_commands.describe(question="您要为投票提出的问题。")
    @app_commands.describe(choices='使用逗号分隔的选项。例如“一,二,三”。(最多20个)'
                                      '在选项中使用双逗号“,,”分隔逗号。')
    async def create_poll(self, interaction: discord.Interaction, question: str, choices: str):
        # 将字符串按单逗号分割成列表的函数。返回一个字符串列表。
        text_options = split_text(choices) 

        # 创建一个包含大写字母、小写字母和数字的5个字符ID的函数。
        # 返回与选项相同大小的ID列表。
        id_list = make_id(text_options)

        # 将text_options和id_list配对成一个新列表
        names_and_ids = list(zip(text_options, id_list))
        view = MyView(names_and_ids) # 调用MyView类,发送按钮列表和它们的ID。
        await channel.send(embed=embed, view=view)

async def setup(bot:commands.Bot) -> None:
    await bot.add_cog(polls(bot))

[标签:discord.py] [标签:discord] [标签:discord-buttons] [如何在discord.py中创建持久性按钮]

我尝试使用**这个**来帮助我;不过,我无法弄清楚如何使用他们的示例来创建动态的持久性按钮。我还考虑过将按钮ID保存在数据库中,然后在on_ready事件中加载它们,但我找不到这样做的方法,所以我运气不佳。非常感谢您的时间。希望您能帮助我!

英文:

I'm trying to make dynamically persistent buttons and am not sure how to go about it. I'm making a polls bot. What I want to happen is if the bot resets, I want the buttons on the polls to still work. I tried looking at some tutorials and the discord.py documentation but couldn't find anything helpful or relevant.

Below is my code:

import discord
from discord.ext import commands
from discord import app_commands
#My button class is a call for when someone presses a button
class MyButton(discord.ui.Button):
async def callback(self, interaction: discord.Interaction):
#Setting vars for the class.
button_id = self.custom_id
user_id = interaction.user.id
timestamp = interaction.created_at
message_id = interaction.message.id  # Access the message ID #getting message id
print(f"Received button click: {button_id}") #Print for the msg ID
#The response message to clicking a button
await interaction.response.send_message(f"You clicked {self.label}")
#the My View class for 
class MyView(discord.ui.View):
def __init__(self, options_and_ids): #The options_and_ids variable is a list thats ziped from the polls class
super().__init__(timeout=None)
#dynamically creating the Buttons for the message depending in the list.
for option, button_id in options_and_ids:
button = MyButton(label=option, custom_id=button_id)
self.add_item(button)
class polls(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
#setup hook for non-dynamic buttons that I tried to use.
async def setup_hook(self) -> None:
self.add_view(MyView())
@app_commands.command(name = "poll", description="Make a poll.")
@app_commands.describe(question = "The question you want to ask for your poll.")
@app_commands.describe(choices = 'Add choices with commas. ex. "One, Two, Three". (MAX IS 20)
Put commas within a choice using a double coma ",,".')
async def create_poll(self, interaction: discord.Interaction, question: str, choices: str)
#function for putting string into a list separated by single commas. Returns a list of str.
text_options = split_text(choices) 
#Function that creates a 5 char id using Uppercase, lowercase, and digits.
#    Returns a list of IDs the same size as the choices.
id_list = make_id(text_options)
#pairs text_options and id_list into a new list
names_and_ids = list(zip(text_options, id_list))
view = MyView(names_and_ids) #calls the MyView class sending over the list of buttons and their IDs.
await channel.send(embed=embed, view=view)
async def setup(bot:commands.Bot) -> None:
await bot.add_cog(polls(bot))

[tag:discord.py][tag:discord][tag:discord-buttons][How to make persistant buttons in discord.py]

I tried to use this to help me; though, I couldn't figure out how to use their example to make dynamic persistent buttons. I also thought about saving the button IDs in a database and then loading them in an on_ready event but I couldn't find the method to do this so I was out of luck with that. Thank you so much for your time. Hopefully you can help me!

答案1

得分: 0

以下是翻译好的部分:

如何在 discord.py 中存储持久按钮

大家好,经过一些尝试和查看 Discord 如何存储持久按钮,我找到了解决方法。

在 discord.py 中存储动态持久按钮相当简单;但是,它要求您使用数据库来存储按钮名称和按钮 ID。

我也将此操作放入了一个“cog”中,所以这将取决于您如何创建您的机器人...
以下是我的做法...

将按钮保存到数据库中:

def save_buttons(names_and_id): #元组列表 [(name1, id1), (name2, id2), ...] 每个都会有相同数量
    conn = sqlite3.connect('your_SQLite.db')
    cursor = conn.cursor()
    for name, id in names_and_id:
        cursor.execute('INSERT INTO buttons (button_name, button_id) VALUES (?, ?)', (name, id))
        conn.commit()

从数据库中提取按钮:

def get_buttons():
    conn = sqlite3.connect('criticalbot.db')
    cursor = conn.cursor()
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS buttons (
        button_name TEXT,
        button_id TEXT PRIMARY KEY)
    ''')
    conn.commit()

    #从数据库中获取所有按钮。方便地与我用于创建按钮视图时使用的元组格式相同。
    cursor.execute('SELECT * FROM buttons')
    names_and_ids = cursor.fetchall()
    if names_and_ids == None:
        return None

    return names_and_ids

现在,我不需要对我的原始代码进行太多修改就能使其工作...

MyButton 类保持不变,只是摆脱了不需要的冗余部分:

#MyButton 类用于当有人按下按钮时进行调用
class MyButton(discord.ui.Button):
    async def callback(self, interaction: discord.Interaction):
        #为该类设置变量。
        button_id = self.custom_id
        print(f"收到按钮点击:{button_id}") #用于消息 ID 的打印
        #按钮点击的响应消息
        await interaction.response.send_message(f"您点击了 {self.label}")

这是 MyView 类,其中将创建动态按钮视图以及我们用来使按钮持久的调用。

#用于创建视图的 My View 类
class MyView(discord.ui.View):
    def __init__(self, options_and_ids): #options_and_ids 变量是从 polls 类中 zip 而来的列表
        super().__init__(timeout=None)
        
        #根据列表动态创建消息的按钮。
        for option, button_id in options_and_ids:
            button = MyButton(label=option, custom_id=button_id)
            self.add_item(button)

这是我们可以在机器人上线时调用的地方,以使按钮持久。这个“cog”类的好处是,由于它是一个“cog”类,这些变量将在机器人完全上线之前设置,因此它将在机器人启动之前自动运行我们的add_view()方法。

class polls(commands.Cog):
    def __init__(self, bot: commands.Bot):
        self.bot = bot
        
        try: #我们在这里使用这个,以防数据库中没有任何内容
            self.bot.add_view(MyView(get_buttons())) #这就是您需要使按钮持久的内容
        except: #                         ^这是我们调用获取按钮函数以获取我们在创建动态持久视图时所需的元组的地方。
            pass 

这是我使用的主要 app_command

@app_commands.command(name="poll", description="创建一个投票。")
@app_commands.describe(question="您想要为您的投票提出的问题。")
@app_commands.describe(choices='使用逗号添加选项。例如 "One, Two, Three"(最多 20 个)使用双逗号 ",," 在选项中添加逗号。')
async def create_poll(self, interaction: discord.Interaction, question: str, choices: str)
    #将字符串按单逗号分隔为列表的函数。返回一个字符串列表。
    text_options = split_text(choices) 

    #创建一个由大写字母、小写字母和数字组成的 5 个字符的 ID 的函数。
    #    返回与选项相同大小的 ID 列表。
    id_list = make_id(text_options)

    #将 text_options 和 id_list 成对放入新列表中
    names_and_ids = list(zip(text_options, id_list))
    save_buttons(names_and_ids) #<--- 这是我们在创建新动态按钮时保存命令的地方,当创建新的投票时。

    view = MyView(names_and_ids) #调用 MyView 类,发送按钮列表和它们的 ID。
    await channel.send("", view=view)

async def setup(bot:commands.Bot) -> None:
    await bot.add_cog(polls(bot))

希望这些信息对您有所帮助。

英文:

How to store persistent buttons in discord.py

Hi all, after some tinkering and looking at how Discord stores persistent buttons I figured it out.

Storing dynamic persistent button in discord.py is fairly simple; though, it requires you to use a database to store the button_name and button_id.

I also did this in a cog so this will vary depending on how you make your bot...
Here's how I did it...

Saving buttons to the DB:

def save_buttons(names_and_id): #touple list [(name1,id1),(name2,id2),...] will always be the same amount of each
conn = sqlite3.connect(&#39;your_SQLite.db&#39;)
cursor = conn.cursor()
for name, id in names_and_id:
cursor.execute(&#39;INSERT INTO buttons (button_name, button_id) VALUES (?, ?)&#39;, (name,id))
conn.commit()

Fetching buttons from the DB:

def get_buttons():
conn = sqlite3.connect(&#39;criticalbot.db&#39;)
cursor = conn.cursor()
cursor.execute(&#39;&#39;&#39;
CREATE TABLE IF NOT EXISTS buttons (
button_name TEXT,
button_id TEXT PRIMARY KEY)
&#39;&#39;&#39;)
conn.commit()
#getting all buttons from the db. Will conveniently be the same format as the touple that I use to make the View when making buttons.
cursor.execute(&#39;SELECT * FROM buttons&#39;)
names_and_ids = cursor.fetchall()
if names_and_ids == None:
return None
return names_and_ids

Now I didn't have to do much to my original code to make it work...

The MyButton class stays the same except getting rid of unneeded bloat:

#My button class is a call for when someone presses a button
class MyButton(discord.ui.Button):
async def callback(self, interaction: discord.Interaction):
#Setting vars for the class.
button_id = self.custom_id
print(f&quot;Received button click: {button_id}&quot;) #Print for the msg ID
#The response message to clicking a button
await interaction.response.send_message(f&quot;You clicked {self.label}&quot;)

Here is the MyView class where the dynamic buttons view will be made as well as what we call to make the buttons to be persistent.

#the My View class for creating the view
class MyView(discord.ui.View):
def __init__(self, options_and_ids): #The options_and_ids variable is a list thats ziped from the polls class
super().__init__(timeout=None)
#dynamically creating the Buttons for the message depending in the list.
for option, button_id in options_and_ids:
button = MyButton(label=option, custom_id=button_id)
self.add_item(button)

This is where we can make the call when the bot goes online to make the buttons persistent. What's nice about this is because its a cog class, the vars will be set before the bot goes completely online so it will auto-run our add_view() method before the bot starts.


class polls(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
try: #We use this in case there&#39;s nothing in the DB
self.bot.add_view(MyView(get_buttons())) #THIS IS WHAT YOU NEED TO MAKE THE BUTTONS PERSISTANT
except: #                         ^This is where we call the get buttons function to get the touple we need to make the dynamic persistent view.
pass 
#REPLACEING THIS WITH WHATS ABOVE
#setup hook for non-dynamic buttons that I tried to use.
#async def setup_hook(self) -&gt; None:
#    self.add_view(MyView())

Here is my main app_command that i use

    @app_commands.command(name = &quot;poll&quot;, description=&quot;Make a poll.&quot;)
@app_commands.describe(question = &quot;The question you want to ask for your poll.&quot;)
@app_commands.describe(choices = &#39;Add choices with commas. ex. &quot;One, Two, Three&quot;. (MAX IS 20)
Put commas within a choice using a double coma &quot;,,&quot;.&#39;)
async def create_poll(self, interaction: discord.Interaction, question: str, choices: str)
#function for putting string into a list separated by single commas. Returns a list of str.
text_options = split_text(choices) 
#Function that creates a 5 char id using Uppercase, lowercase, and digits.
#    Returns a list of IDs the same size as the choices.
id_list = make_id(text_options)
#pairs text_options and id_list into a new list
names_and_ids = list(zip(text_options, id_list))
save_buttons(names_and_ids) #&lt;--- this is where we save the commands when we create new dynamic buttons when a pole is made.
view = MyView(names_and_ids) #calls the MyView class sending over the list of buttons and their IDs.
await channel.send(&quot;&quot;, view=view)
async def setup(bot:commands.Bot) -&gt; None:
await bot.add_cog(polls(bot))

huangapple
  • 本文由 发表于 2023年5月28日 14:52:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76350295.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定