您可以通過以下操作安裝庫的最新PYPI版本:
$ pip install reactionmenu
或開發版本:
$ pip install git+https://github.com/Defxult/reactionmenu
最低意圖
bot = commands . Bot (..., intents = discord . Intents ( messages = True , guilds = True , reactions = True , members = True )) class reactionmenu.ReactionMenu(method: Union[Context, discord.Interaction], /, *, menu_type: MenuType, **kwargs)
ReactionMenu是使用表情符號的菜單,它是自定義行會表情符號或普通表情符號來控制分頁過程的菜單。如果您不在尋找任何精美的功能,而只是想要簡單的東西,那麼這就是要使用的功能。
from reactionmenu import ReactionMenu , ReactionButton該庫帶有幾種方法和選項,以使Discord Reaction菜單變得簡單。一旦導入適當的類,您將像這樣初始化構造函數:
menu = ReactionMenu ( method , menu_type = ReactionMenu . TypeEmbed )method ( Union[discord.ext.commands.Context, discord.Interaction] )上下文或交互對象menu_type ( MenuType )菜單的配置ReactionMenu.TypeEmbed ,正常的嵌入分頁菜單ReactionMenu.TypeEmbedDynamic ,一個帶有動態數據的嵌入分頁菜單ReactionMenu.TypeText ,僅文本分頁菜單| 姓名 | 類型 | 預設值 | 用於 | 資訊 |
|---|---|---|---|---|
wrap_in_codeblock | str | None | ReactionMenu.TypeEmbedDynamic | 將您的數據包裝在包裝中的Discord CodeBlock語言標識符。示例: ReactionMenu(ctx, ..., wrap_in_codeblock='py') |
custom_embed | discord.Embed | None | ReactionMenu.TypeEmbedDynamic | 嵌入對像在添加ReactionMenu.add_row()的數據時使用。用於造型目的 |
delete_on_timeout | bool | False | All menu types | 刪除菜單時 |
clear_reactions_after | bool | True | All menu types | 菜單時刪除所有反應 |
navigation_speed | str | ReactionMenu.NORMAL | All menu types | 設置如果用戶需要等待在“轉動”頁面之前通過機器人刪除反應。設置速度到ReactionMenu.FAST使它無需等待(在每次壓力上都不會刪除反應),並且可以更快地導航longy菜單 |
only_roles | List[discord.Role] | None | All menu types | 如果設置,則僅允許具有任何給定角色的成員控制菜單。菜單所有者總是可以控制菜單 |
timeout | Union[int, float, None] | 60.0 | All menu types | 菜單時的計時器。可以None超時 |
show_page_director | bool | True | All menu types | 顯示在每個嵌入頁面的底部。 “第1/20頁” |
name | str | None | All menu types | 您可以為菜單設置的名稱 |
style | str | "Page $/&" | All menu types | 您可以選擇的自定義頁面導演樣式。 “ $”代表當前頁面,”&”表示頁面的總量。示例: ReactionMenu(ctx, ..., style='On $ out of &') |
all_can_click | bool | False | All menu types | 設置如果允許每個人在單擊按鈕時“轉動”頁面時控制頁面 |
delete_interactions | bool | True | All menu types | 當被問及使用ReactionButton.Type.GO_TO_PAGE時,用戶通過機器人和響應消息刪除提示消息和響應消息 |
rows_requested | int | None | ReactionMenu.TypeEmbedDynamic | 您希望將每個嵌入頁面應用於每個ReactionMenu.add_row()的信息量 |
remove_extra_emojis | bool | False | All menu types | 如果為True ,則將所有最初添加到菜單的表情符號(反應)添加到菜單消息中 |
根據menu_type files content頁面可以是str , discord.Embed 。
menu_type是ReactionMenu.TypeEmbed ,請使用嵌入menu_type是ReactionMenu.TypeText (僅文本菜單)或ReactionMenu.TypeEmbedDynamic (僅嵌入菜單),請使用字符串。ReactionMenu.add_page(embed: discord.Embed=MISSING, content: Optional[str]=None, files: Optional[Sequence[discord.File]]=None)ReactionMenu.add_pages(pages: Sequence[Union[discord.Embed, str]])ReactionMenu.add_row(data: str)ReactionMenu.remove_all_pages()ReactionMenu.clear_all_row_data()ReactionMenu.remove_page(page_number: int)ReactionMenu.set_main_pages(*embeds: Embed)ReactionMenu.set_last_pages(*embeds: Embed) # ReactionMenu.TypeEmbed
menu = ReactionMenu ( method , menu_type = ReactionMenu . TypeEmbed )
menu . add_page ( summer_embed )
menu . add_page ( winter_embed )
# ReactionMenu.TypeText
menu = ReactionMenu ( method , menu_type = ReactionMenu . TypeText )
menu . add_page ( content = 'Its so hot!' )
menu . add_page ( content = 'Its so cold!' ) TypeText菜單是基於文本的分頁菜單。分頁過程中不涉及嵌入,只使用純文本。
使用v3.1.0+ ,您可以使用不僅僅是嵌入或文本的詞。您可以組合文本,嵌入以及文件。但是根據menu_type不同,可以限制組合。這是一個菜單的示例,其中包含菜單的menu_type TypeEmbed 。
# You can use regular commands as well
@ bot . tree . command ( description = "These are stacked pages" , guild = discord . Object ( id = ...))
async def stacked ( interaction : discord . Interaction ):
menu = ReactionMenu ( interaction , menu_type = ReactionMenu . TypeEmbed )
menu . add_page ( discord . Embed ( title = "My Embed" ), content = "This content is stacked on top of a file" , files = [ discord . File ( "stacked.py" )])
menu . add_page ( discord . Embed ( title = "Hey Wumpos, can you say hi to the person reading this? ?" ))
menu . add_page ( discord . Embed ( title = "Hi, I'm Wumpos!" ), files = [ discord . File ( "wumpos.gif" )])
menu . add_button ( ReactionButton . back ())
menu . add_button ( ReactionButton . next ())
await menu . start ()由於menu_type type已TypeEmbed ,因此每個頁面上總是必須嵌入一個。如果menu_type是TypeText ,則不允許嵌入,您將僅限於使用files參數。
當您不知道將向菜單應用多少信息時,請使用動態菜單。例如,如果您要從數據庫請求信息,則該信息始終可以更改。您可以查詢一些內容,然後您可能會獲得1,500個結果,而接下來只有800個。一個動態菜單為您添加了所有這些信息,並將其添加到嵌入頁面中,然後通過大量數據添加。 ReactionMenu.add_row()最好在某種覺得可以循環遍歷的某種Iterable中,但僅將您想要的數據添加到菜單頁面中。
注意:在動態菜單中,所有添加的數據都放在嵌入的描述部分中。如果您選擇使用
custom_embed,則描述中的所有文本都將用您添加的數據覆蓋
ReactionMenu.add_row(data: str)ReactionMenu.clear_all_row_data()ReactionMenu.set_main_pages(*embeds: Embed)ReactionMenu.set_last_pages(*embeds: Embed)rows_requested製作新頁面之前,每個嵌入頁面上想要的行量ReactionMenu(..., rows_requested=5)custom_embed您創建的嵌入式用作嵌入頁面。用於您的菜單美學ReactionMenu(..., custom_embed=red_embed)wrap_in_codeblock將數據包裹在不和諧代碼塊中時的語言標識符。ReactionMenu(..., wrap_in_codeblock='py') menu = ReactionMenu ( ctx , menu_type = ReactionMenu . TypeEmbedDynamic , rows_requested = 5 )
for data in database . request ( 'SELECT * FROM customers' ):
menu . add_row ( data )您可以使用menu.clear_all_row_data()
使用動態菜單時,您看到的唯一嵌入頁面是從您添加的數據中。但是,如果您想顯示更多的頁面,則可以使用方法ReactionMenu.set_main_pages()和ReactionMenu.set_last_pages() 。設置主頁,設置的嵌入將是菜單啟動時顯示的第一個嵌入。設置最後一頁是顯示的最後一個嵌入
menu . set_main_pages ( welcome_embed , announcement_embed )
for data in get_information ():
menu . add_row ( data )
menu . set_last_pages ( additional_info_embed )
# NOTE: setting main/last pages can be set in any order當您想向執行某個功能的菜單添加反應時,使用按鈕/按鈕類型。按鈕和按鈕類型共同使用所需的動作。
class reactionmenu.ReactionButton(*, emoji: str, linked_to: ButtonType, **kwargs)
emoji ( str )您想用作反應的表情符號linked_to ( ReactionButton.Type )按下反應時,這就是決定其要做什麼的原因| 姓名 | 類型 | 預設值 | 用於 |
|---|---|---|---|
embed | discord.Embed | None | 按下反應時,轉到指定的嵌入 |
name | str | None | 按鈕的名稱 |
details | 下面的信息 | None | 分配函數,當用ReactionButton.Type.CALLER ReactionButton被按下時,要調用該函數 |
event | ReactionButton.Event | None | 根據按下多少次,確定何時應刪除按鈕 |
skip | ReactionButton.Skip | None | 使用ReactionButton.Type.SKIP的linked_to時,設置動作和跳過的頁面。例如,使用此按鈕類型,將操作設置為“+”和金額3。 |
| 財產 | 返回類型 | 資訊 |
|---|---|---|
clicked_by | Set[discord.Member] | 單擊按鈕的成員 |
total_clicks | int | 按鈕的點擊量 |
last_clicked | Optional[datetime.datetime] | UTC的時間上一次點擊按鈕的時間 |
menu | Optional[ReactionMenu] | 按鈕附加到菜單 |
ReactionMenu.add_button(button: ReactionButton)ReactionMenu.remove_all_buttons()ReactionMenu.remove_button(button: ReactionButton)ReactionMenu.get_button(identity: Union[str, int], *, search_by='name')ReactionButton.set_caller_details(func: Callable[..., None], *args, **kwargs)| 類型 | 資訊 |
|---|---|
ReactionButton.Type.NEXT_PAGE | 轉到菜單會話中的下一頁 |
ReactionButton.Type.PREVIOUS_PAGE | 轉到菜單會話中的上一頁 |
ReactionButton.Type.GO_TO_FIRST_PAGE | 轉到菜單會話中的第一頁 |
ReactionButton.Type.GO_TO_LAST_PAGE | 轉到菜單會話中的最後一頁 |
ReactionButton.Type.GO_TO_PAGE | 提示您要輸入您想轉到的頁面 |
ReactionButton.Type.END_SESSION | 停止會話並刪除菜單消息 |
ReactionButton.Type.CUSTOM_EMBED | 與導航按鈕分開使用。按下後,轉到指定的嵌入 |
ReactionButton.Type.CALLER | 指定要調用的函數時使用的是按鈕按鈕時的參數 |
ReactionButton.Type.SKIP | 用於通過單個按鈕中的多個頁面劃分 |
您可以使用ReactionButton將按鈕(反應)添加到菜單中。以下是如何使用每個ButtonType的示例。
注意:與
ReactionButton.Type.CALLER的ReactionButtons有些不同,因此有一個專用部分解釋它們的工作方式以及如何進一步實施它們
menu = ReactionMenu (...)
# first and last pages
fpb = ReactionButton ( emoji = '⏪' , linked_to = ReactionButton . Type . GO_TO_FIRST_PAGE )
lpb = ReactionButton ( emoji = '⏩' , linked_to = ReactionButton . Type . GO_TO_LAST_PAGE )
# go to page
gtpb = ReactionButton ( emoji = '?' , linked_to = ReactionButton . Type . GO_TO_PAGE )
# end session
esb = ReactionButton ( emoji = '⏹️' , linked_to = ReactionButton . Type . END_SESSION )
# custom embed
ceb = ReactionButton ( emoji = '?' , linked_to = ReactionButton . Type . CUSTOM_EMBED , embed = discord . Embed ( title = 'Hello' ))
# skip button
sb = ReactionButton ( emoji = '5️⃣' , linked_to = ReactionButton . Type . SKIP , skip = ReactionButton . Skip ( action = '+' , amount = 5 ))
menu . add_button ( fpb )
...用menu.remove_all_buttons() 。您還可以使用其名稱刪除單獨的按鈕,如果您設置了該按鈕,或使用menu.remove_button()
ReactionButton.Type.CALLER按鈕用於在菜單中實現自己的功能。也許您想添加一個創建文本通道,發送消息或在數據庫中添加的按鈕,無論它可能是什麼。為了與ReactionButton.Type.CALLER一起使用,請使用下面的類方法。
ReactionButton.set_caller_details(func: Callable[..., None], *args, **kwargs)此類方法用於設置一個函數,並且在按下按鈕時將調用該函數。 ReactionButton構造函數具有Kwarg的details ,這就是您將使用.set_caller_details()來分配所需值。下面有一些示例有關如何正確實現ReactionButton.Type.CALLER
@ bot . command ()
async def user ( ctx , name , * , message ):
await ctx . send ( f"Hi { name } ! { message } . We're glad you're here!" )
def car ( year , make , model ):
print ( f"I have a { year } { make } { model } " )
ub = ReactionButton ( emoji = '' , linked_to = ReactionButton . Type . CALLER , details = ReactionButton . set_caller_details ( user , ctx , 'Defxult' , message = 'Welcome to the server' ))
cb = ReactionButton ( emoji = '?' , linked_to = ReactionButton . Type . CALLER , details = ReactionButton . set_caller_details ( car , 2021 , 'Ford' , 'Mustang' ))注意:您傳遞的功能不應返回任何內容。使用
ReactionButton.Type.CALLER調用功能不存儲或處理該功能返回的任何內容
ReactionButton類帶有設定的工廠方法(類方法),該方法將根據其linked_to設置的參數返回ReactionButton 。
ReactionButton.back()emoji :”linked_to : ReactionButton.Type.PREVIOUS_PAGEReactionButton.next()emoji :”linked_to : ReactionButton.Type.NEXT_PAGEReactionButton.go_to_first_page()emoji :“⏪”linked_to : ReactionButton.Type.GO_TO_FIRST_PAGEReactionButton.go_to_last_page()emoji :“⏩”linked_to : ReactionButton.Type.GO_TO_LAST_PAGEReactionButton.go_to_page()emoji :“?”linked_to : ReactionButton.Type.GO_TO_PAGEReactionButton.end_session()emoji :“⏹️”linked_to : ReactionButton.Type.END_SESSIONReactionButton.all()ReactionButton list.go_to_first_page()ReactionButton.generate_skip(emoji: str, action: str, amount: int)emoji : <emoji>linked_to : ReactionButton.Type.SKIPskip : ReactionButton.Skip(<action>, <amount>)如果您願意,可以限制每個“行會”,“成員”或“渠道”的反應菜單量
ReactionMenu.set_sessions_limit(limit: int, per='guild', message='Too many active menus. Wait for other menus to be finished.')ReactionMenu.remove_limit()例子:
@ bot . command ()
async def limit ( ctx ):
ReactionMenu . set_sessions_limit ( 3 , per = 'member' , message = 'Sessions are limited to 3 per member' )在上面的示例中,每個成員只能一次活躍3個菜單,如果他們嘗試在另一個菜單完成之前創建更多菜單,他們將收到一條錯誤消息,說“會話限制為每個成員3個”。
您可以設置一個ReactionButton ,以便將其按下一定次
class ReactionButton.Event(event_type: str, value: int)
event_type ( str )要採取的動作。唯一可用的選項是“刪除”value ( int )指定事件的設置。必須為> = 1。如果值是<= 0,則隱式設置為1例子:
menu = ReactionMenu ( ctx , ...)
# remove a button after 10 clicks
button = ReactionButton (..., event = ReactionButton . Event ( 'remove' , 10 ))
menu . add_button ( button )注意:對具有
linked_to按鈕不理想,ReactionButton.Type.END_SESSION
菜單繼電器是函數,隨時可以按下菜單中的按鈕。它被認為是與ReactionButton.Type.CALLER linked_to的ReactionButton的擴展。與呼叫者按鈕不同,該按鈕沒有提供有關菜單上交互的詳細信息,繼電器可以。
ReactionMenu.set_relay(func: Callable[[NamedTuple], None], *, only: Optional[List[ReactionButton]]=None)ReactionMenu.remove_relay()為繼電器創建函數時,該功能必須包含一個位置參數。按下按鈕時, RelayPayload對象(命名元組)將傳遞給該功能。 RelayPayload的屬性是:
member ( discord.Member )按下按鈕的人button ( ReactionButton )按下按鈕例子:
async def enter_giveaway ( payload ):
member = payload . member
channel = payload . button . menu . message . channel
await channel . send ( f" { member . mention } , you've entered the giveaway!" )
menu = ReactionMenu ( ctx , ...)
menu . set_relay ( enter_giveaway ) set_relay方法帶有only參數。如果該參數None ,則所有按下的按鈕都將中繼。您可以提供該參數的按鈕list ,因此只有從指定按鈕的按鈕按下將中繼的按鈕。
def example ( payload ):
...
menu = ReactionMenu ( ctx , ...)
back_button = ReactionButton . back ()
next_button = ReactionButton . next ()
menu . set_relay ( example , only = [ back_button ])await ReactionMenu.start(*, send_to=None, reply=False)await ReactionMenu.stop(*, delete_menu_message=False, clear_reactions=False)啟動菜單時,您可以選擇將菜單發送到某個頻道。參數send_to是您要將菜單發送到的頻道。您可以將send_to設置為頻道名稱( str ),通道ID( int )或通道對象( discord.TextChannel / discord.Thread )。例子:
menu = ReactionMenu (...)
# channel name
await menu . start ( send_to = 'bot-commands' )
# channel ID
await menu . start ( send_to = 1234567890123456 )
# channel object
channel = guild . get_channel ( 1234567890123456 )
await menu . start ( send_to = channel )
# there's no need to specify send_to unless you want the menu to be sent to a different channel
# from the one you're sending the initial message/using the command in. the menu can be started
# in the current channel by omitting the send_to parameter
await menu . start ()注意:如果DM的菜單啟動了菜單,則
send_to無效
這是ReactionMenu的基本實現,您可以復制和粘貼以進行快速演示。
import asyncio
import discord
from discord . ext import commands
from reactionmenu import ReactionMenu , ReactionButton
bot = commands . Bot ( command_prefix = '!' , intents = discord . Intents . all ())
async def start_bot ():
async with bot :
await bot . start ( '...' )
@ bot . command ()
async def example ( ctx ):
menu = ReactionMenu ( ctx , menu_type = ReactionMenu . TypeEmbed )
for member in ctx . guild . members :
if member . avatar :
embed = discord . Embed ( description = f'Joined { member . joined_at . strftime ( "%b. %d, %Y" ) } ' )
embed . set_author ( name = member . name , icon_url = member . avatar . url )
menu . add_page ( embed )
menu . add_button ( ReactionButton . back ())
menu . add_button ( ReactionButton . next ())
menu . add_button ( ReactionButton . end_session ())
await menu . start ()
asyncio . run ( start_bot ()) class reactionmenu.ViewMenu(method: Union[Context, discord.Interaction], /, *, menu_type: MenuType, **kwargs)
ViewMenu是使用Discords按鈕功能的菜單。使用按鈕,您可以啟用和禁用它們,用表情符號為它們設置某些顏色,具有發送隱藏消息的按鈕並添加超鏈接。該庫提供了更廣泛的功能,例如誰按下了按鈕,按下了多少次以及更多的次數。它使用視圖( discord.ui.View )來實現按鈕功能,但是使用其一些自己的方法來簡單地使按鈕分頁菜單。
from reactionmenu import ViewMenu , ViewButtonmethod ( Union[discord.ext.commands.Context, discord.Interaction] )上下文或交互對象menu_type ( MenuType )菜單的配置ViewMenu.TypeEmbed ,一個普通的嵌入分頁菜單ViewMenu.TypeEmbedDynamic ,帶有動態數據的嵌入分頁菜單ViewMenu.TypeText ,僅文本分頁菜單| 姓名 | 類型 | 預設值 | 用於 | 資訊 |
|---|---|---|---|---|
wrap_in_codeblock | str | None | ViewMenu.TypeEmbedDynamic | 將您的數據包裝在中的Discord CodeBlock語言標識符。示例: ViewMenu(ctx, ..., wrap_in_codeblock='py') |
custom_embed | discord.Embed | None | ViewMenu.TypeEmbedDynamic | 嵌入對象使用ViewMenu.add_row()添加數據時使用的對象。用於造型目的 |
delete_on_timeout | bool | False | All menu types | 刪除菜單時 |
disable_items_on_timeout | bool | True | All menu types | 菜單限制菜單上的項目 |
remove_items_on_timeout | bool | False | All menu types | 菜單時間刪除菜單上的項目 |
only_roles | List[discord.Role] | None | All menu types | 如果設置,則僅允許具有任何給定角色的成員控制菜單。菜單所有者總是可以控制菜單 |
timeout | Union[int, float, None] | 60.0 | All menu types | 菜單時的計時器。可以None超時 |
show_page_director | bool | True | All menu types | 顯示在每個嵌入頁面的底部。 “第1/20頁” |
name | str | None | All menu types | 您可以為菜單設置的名稱 |
style | str | "Page $/&" | All menu types | 您可以選擇的自定義頁面導演樣式。 “ $”代表當前頁面,”&”表示頁面的總量。示例: ViewMenu(ctx, ..., style='On $ out of &') |
all_can_click | bool | False | All menu types | 設置如果允許每個人在單擊按鈕時“轉動”頁面時控制頁面 |
delete_interactions | bool | True | All menu types | 當詢問使用ViewButton.ID_GO_TO_PAGE時,用戶通過機器人和響應消息刪除提示消息和響應消息 |
rows_requested | int | None | ViewMenu.TypeEmbedDynamic | 您要應用於每個嵌入頁面的每個ViewMenu.add_row() |
根據menu_type不同,頁面可以是str , discord.Embed ,或content或files組合(下面的示例)
menu_type是ViewMenu.TypeEmbed ,請使用嵌入menu_type是ViewMenu.TypeText (僅文本菜單)或ViewMenu.TypeEmbedDynamic (僅嵌入菜單),請使用字符串。ViewMenu.add_page(embed: discord.Embed=MISSING, content: Optional[str]=None, files: Optional[Sequence[discord.File]]=None)ViewMenu.add_pages(pages: Sequence[Union[discord.Embed, str]])ViewMenu.add_row(data: str)ViewMenu.remove_all_pages()ViewMenu.clear_all_row_data()ViewMenu.remove_page(page_number: int)ViewMenu.set_main_pages(*embeds: Embed)ViewMenu.set_last_pages(*embeds: Embed) # ViewMenu.TypeEmbed
menu = ViewMenu ( method , menu_type = ViewMenu . TypeEmbed )
menu . add_page ( summer_embed )
menu . add_page ( winter_embed )
# ViewMenu.TypeText
menu = ViewMenu ( method , menu_type = ViewMenu . TypeText )
menu . add_page ( content = 'Its so hot!' )
menu . add_page ( content = 'Its so cold!' ) TypeText菜單是基於文本的分頁菜單。分頁過程中不涉及嵌入,只使用純文本。
使用v3.1.0+ ,您可以使用不僅僅是嵌入或文本的詞。您可以組合文本,嵌入以及文件。但是根據menu_type不同,可以限制組合。這是一個菜單的示例,其中包含菜單的menu_type TypeEmbed 。
# You can use regular commands as well
@ bot . tree . command ( description = "These are stacked pages" , guild = discord . Object ( id = ...))
async def stacked ( interaction : discord . Interaction ):
menu = ViewMenu ( interaction , menu_type = ViewMenu . TypeEmbed )
menu . add_page ( discord . Embed ( title = "My Embed" ), content = "This content is stacked on top of a file" , files = [ discord . File ( "stacked.py" )])
menu . add_page ( discord . Embed ( title = "Hey Wumpos, can you say hi to the person reading this? ?" ))
menu . add_page ( discord . Embed ( title = "Hi, I'm Wumpos!" ), files = [ discord . File ( "wumpos.gif" )])
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
await menu . start ()由於menu_type type已TypeEmbed ,因此每個頁面上總是必須嵌入一個。如果menu_type是TypeText ,則不允許嵌入,您將僅限於使用files參數。
當您不知道將向菜單應用多少信息時,請使用動態菜單。例如,如果您要從數據庫請求信息,則該信息始終可以更改。您可以查詢一些內容,然後您可能會獲得1,500個結果,而接下來只有800個。一個動態菜單為您添加了所有這些信息,並將其添加到嵌入頁面中,然後通過大量數據添加。 ViewMenu.add_row()最適合在某種Iterable使用,其中所有內容都可以通過,但僅將您想要的數據添加到菜單頁面中。
注意:在動態菜單中,所有添加的數據都放在嵌入的描述部分中。如果您選擇使用
custom_embed,則描述中的所有文本都將用您添加的數據覆蓋
ViewMenu.add_row(data: str)ViewMenu.clear_all_row_data()ViewMenu.set_main_pages(*embeds: Embed)ViewMenu.set_last_pages(*embeds: Embed)rows_requested製作新頁面之前,每個嵌入頁面上想要的行量ViewMenu(..., rows_requested=5)custom_embed您創建的嵌入式用作嵌入頁面。用於您的菜單美學ViewMenu(..., custom_embed=red_embed)wrap_in_codeblock將數據包裹在不和諧代碼塊中時的語言標識符。ViewMenu(..., wrap_in_codeblock='py') menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbedDynamic , rows_requested = 5 )
for data in database . request ( 'SELECT * FROM customers' ):
menu . add_row ( data )您可以使用menu.clear_all_row_data()
使用動態菜單時,您看到的唯一嵌入頁面是從您添加的數據中。但是,如果您想顯示更多的頁面,則可以使用方法ViewMenu.set_main_pages()和ViewMenu.set_last_pages() 。設置主頁,設置的嵌入將是菜單啟動時顯示的第一個嵌入。設置最後一頁是顯示的最後一個嵌入
menu . set_main_pages ( welcome_embed , announcement_embed )
for data in get_information ():
menu . add_row ( data )
menu . set_last_pages ( additional_info_embed )
# NOTE: setting main/last pages can be set in any order按鈕是您與菜單進行交互的內容。與反應不同,它們看起來更清潔,提供較小的速率限制問題,並在互動方面提供更多。啟用和禁用按鈕,在消息中使用Markdown超鏈接,甚至發送隱藏的消息。
ViewMenu.add_button(button: ViewButton)ViewMenu.disable_all_buttons()ViewMenu.disable_button(button: ViewButton)ViewMenu.enable_all_buttons()ViewMenu.enable_button(button: ViewButton)ViewMenu.get_button(identity: str, *, search_by='label')ViewMenu.remove_all_buttons()ViewMenu.remove_button(button: ViewButton)await ViewMenu.refresh_menu_items() class reactionmenu.ViewButton(*, style=discord.ButtonStyle.secondary, label=None, disabled=False, custom_id=None, url=None, emoji=None, followup=None, event=None, **kwargs)
ViewButton是代表Discord按鈕的類。它是discord.ui.Button的子類。
以下是按鈕設置的規則:
custom_id ,並且不能有urlurl ,並且不能具有custom_idstyle ( discord.ButtonStyle )按鈕樣式label ( str )按鈕上的文本custom_id ( str )一個ID來確定該按鈕應採取的操作。可用ID:ViewButton.ID_NEXT_PAGEViewButton.ID_PREVIOUS_PAGEViewButton.ID_GO_TO_FIRST_PAGEViewButton.ID_GO_TO_LAST_PAGEViewButton.ID_GO_TO_PAGEViewButton.ID_END_SESSIONViewButton.ID_CALLERViewButton.ID_SEND_MESSAGEViewButton.ID_CUSTOM_EMBEDViewButton.ID_SKIPemoji ( Union[str, discord.PartialEmoji] )表情符號用於按鈕ViewButton(..., emoji='?')ViewButton(..., emoji='<:miscTwitter:705423192818450453>')ViewButton(..., emoji='U000027a1')ViewButton(..., emoji='N{winking face}')url ( str )url for fins style discord.ButtonStyle.linkdisabled ( bool )如果應禁用該按鈕followup ( ViewButton.Followup )按下按鈕後發送的消息。僅適用於具有ViewButton.ID_CALLER或ViewButton.ID_SEND_MESSAGE的custom_id 。 ViewButton.Followup是一個類似於discord.abc.Messageable.send()的參數的類,用於控制消息是否是短暫的,包含文件,嵌入,tts等...event ( ViewButton.Event )設置一個按下要禁用或刪除的按鈕,請按一定的次數| 姓名 | 類型 | 預設值 | 用於 |
|---|---|---|---|
name | str | None | 按鈕的名稱 |
skip | ViewButton.Skip | None | 使用ViewButton.ID_SKIP的custom_id時,設置操作和跳過的頁面。例如,將操作設置為“+”和金額3。 |
persist | bool | False | 防止鏈接按鈕在菜單時間出門或停止時被禁用/刪除 |
| 財產 | 返回類型 | 資訊 |
|---|---|---|
clicked_by | Set[discord.Member] | 單擊按鈕的成員 |
total_clicks | int | 按鈕的點擊量 |
last_clicked | Optional[datetime.datetime] | UTC的時間上一次點擊按鈕的時間 |
menu | Optional[ViewMenu] | 按鈕附加到菜單 |
from reactionmenu import ViewMenu , ViewButton
menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbed )
# Link button
link_button = ViewButton ( style = discord . ButtonStyle . link , emoji = '?' , label = 'Link to Google' , url = 'https://google.com' )
menu . add_button ( link_button )
# Skip button
skip = ViewButton ( style = discord . ButtonStyle . primary , label = '+5' , custom_id = ViewButton . ID_SKIP , skip = ViewButton . Skip ( action = '+' , amount = 5 ))
menu . add_button ( skip )
# ViewButton.ID_PREVIOUS_PAGE
back_button = ViewButton ( style = discord . ButtonStyle . primary , label = 'Back' , custom_id = ViewButton . ID_PREVIOUS_PAGE )
menu . add_button ( back_button )
# ViewButton.ID_NEXT_PAGE
next_button = ViewButton ( style = discord . ButtonStyle . secondary , label = 'Next' , custom_id = ViewButton . ID_NEXT_PAGE )
menu . add_button ( next_button )
# All other ViewButton are created the same way as the last 2 EXCEPT
# 1 - ViewButton.ID_CALLER
# 2 - ViewButton.ID_SEND_MESSAGE
# 3 - ViewButton.ID_CUSTOM_EMBED
# ViewButton.ID_CALLER
def say_hello ( name : str ):
print ( 'Hello' , name )
call_followup = ViewButton . Followup ( details = ViewButton . Followup . set_caller_details ( say_hello , 'John' ))
menu . add_button ( ViewButton ( label = 'Say hi' , custom_id = ViewButton . ID_CALLER , followup = call_followup ))
# ViewButton.ID_SEND_MESSAGE
msg_followup = ViewButton . Followup ( 'This message is hidden!' , ephemeral = True )
menu . add_button ( ViewButton ( style = discord . ButtonStyle . green , label = 'Message' , custom_id = ViewButton . ID_SEND_MESSAGE , followup = msg_followup ))
# ViewButton.ID_CUSTOM_EMBED
custom_embed_button = ViewButton ( style = discord . ButtonStyle . blurple , label = 'Social Media Info' , custom_id = ViewButton . ID_CUSTOM_EMBED , followup = ViewButton . Followup ( embed = discord . Embed (...)))注意:當涉及使用
ViewButton.ID_CALLER的custom_id的按鈕時,ViewButton.ID_SEND_MESSAGE,ViewButton.ID_CUSTOM_EMBED或鏈接按鈕,您可以添加盡可能多的數量,最多是25個按鈕或更少的按鈕。對於所有其他按鈕ID,每個菜單只能有一個。
當您想在菜單中對信息進行分類時,請使用選擇。只有在菜單的menu_type type被TypeEmbed時才能使用選擇。您應該記住,不滿限制可以應用於每個消息的菜單UI項目(行)。
Page.from_embeds(embeds: Sequence[Embed])ViewMenu.add_select(select: ViewSelect)ViewMenu.remove_select(select: ViewSelect)ViewMenu.remove_all_selects()ViewMenu.disable_select(select: ViewSelect)ViewMenu.disable_all_selects()ViewMenu.enable_select(select: ViewSelect)ViewMenu.enable_all_selects()ViewMenu.get_select(title: Union[str, None])例子:
from reactionmenu import ViewMenu , ViewSelect , Page
menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbed )
menu . add_page ( discord . Embed ( title = "A showcase of console video games" , color = discord . Color . blurple ()))
menu . add_select ( ViewSelect ( title = "Console Video Games" , options = {
# NOTE: The discord.SelectOption parameter "default" cannot be set to True
discord . SelectOption ( label = "PlayStation" , emoji = "<:PlayStation:549638412538478602>" ) : [
Page ( embed = discord . Embed ( title = "Ratchet & Clank" , description = ..., color = discord . Color . yellow ()). set_image ( url = ...)),
Page ( embed = discord . Embed ( title = "God of War" , description = ..., color = discord . Color . blue ()). set_image ( url = ...))
],
discord . SelectOption ( label = "Xbox" , emoji = "<:Xbox:501880493285834752>" ) : [
Page ( embed = discord . Embed ( title = "Halo Infinite" , description = ..., color = discord . Color . green ()). set_image ( url = ...)),
Page ( embed = discord . Embed ( title = "Gears of War 4" , description = ..., color = discord . Color . red ()). set_image ( url = ...))
]
}))
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
await menu . start ()當您想使用UI選擇要轉到的頁面時,您可以使用此類型的選擇。
ViewMenu.add_go_to_select(goto: ViewSelect.GoTo)ViewMenu.enable_go_to_select(goto: ViewSelect.GoTo)ViewMenu.enable_all_go_to_selects()ViewMenu.disable_go_to_select(goto: ViewSelect.GoTo)ViewMenu.disable_all_go_to_selects()ViewMenu.remove_go_to_select(goto: ViewSelect.GoTo)ViewMenu.remove_all_go_to_selects() page_numbers參數ViewSelect.GoTo可以與3種不同類型一起使用
List[int]如果設置為整數列表,則指定的值是單擊選擇時唯一可用的選項page_numbers=[1, 5, 10]Dict[int, Union[str, discord.Emoji, discord.PartialEmoji]]如果您想在選擇中使用表情符號,則可以使用此類型page_numbers={1 : "?️", 2 : ""}ellipsis您可以設置一個字面的省略號,以使庫自動將所有頁碼分配給您已添加到菜單的頁面。如果您有25頁或更少,這可能會派上用場page_numbers=...注意:將
page_numbers參數設置為省略(...),只有在添加到select的go中,才能按照預期的方式工作。
@ bot . command ()
async def navigate ( ctx ):
menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbed )
menu . add_page ( discord . Embed ( title = "Twitter" ). set_image ( url = "..." ))
menu . add_page ( discord . Embed ( title = "YouTube" ). set_image ( url = "..." ))
menu . add_page ( discord . Embed ( title = "Discord" ). set_image ( url = "..." ))
# ...
menu . add_go_to_select ( ViewSelect . GoTo ( title = "Go to page..." , page_numbers = ...))
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
await menu . start ()await ViewMenu.refresh_menu_items()await ViewMenu.update(*, new_pages: Union[List[Union[Embed, str]], None], new_buttons: Union[List[ViewButton], None])菜單運行後,您可以更新菜單上的頁面或按鈕。使用ViewMenu.update() ,您可以替換頁面和按鈕。使用ViewMenu.refresh_menu_items()更新您已更改的按鈕。
@ bot . command ()
async def menu ( ctx ):
menu = ViewMenu (..., name = 'test' )
link_button = ViewButton (..., label = 'Link' )
menu . add_button ( link_button )
menu . add_page (...)
await menu . start ()
@ bot . command ()
async def disable ( ctx ):
menu = ViewMenu . get_session ( 'test' )
link_button = menu [ 0 ]. get_button ( 'Link' , search_by = 'label' )
menu . disable_button ( link_button )
await menu . refresh_menu_items ()如果未使用ViewMenu.refresh_menu_items()刷新按鈕,則在更改按鈕時不會更新菜單。
當您要替換菜單上的全部或幾個按鈕時,使用方法ViewMenu.update(...) 。
menu = ViewMenu (...)
# in a different .command()
await menu . update ( new_pages = [ hello_embed , goodbye_embed ], new_buttons = [ link_button , next_button ])注意:使用
ViewMenu.update(...)時,無需使用ViewMenu.refresh_menu_items()因為它們在更新調用中進行了更新。
ViewButton類帶有設置的Factory方法(類方法),該方法返回具有根據其custom_id (不包括鏈接按鈕)設置的參數的ViewButton 。
ViewButton.link(label: str, url: str)style : discord.ButtonStyle.linklabel : <label>url : <url>ViewButton.back()style : discord.ButtonStyle.graylabel :“ Back”custom_id : ViewButton.ID_PREVIOUS_PAGEViewButton.next()style : discord.ButtonStyle.graylabel :“下一步”custom_id : ViewButton.ID_NEXT_PAGEViewButton.go_to_first_page()style : discord.ButtonStyle.graylabel :“第一頁”custom_id : ViewButton.ID_GO_TO_FIRST_PAGEViewButton.go_to_last_page()style : discord.ButtonStyle.graylabel :“最後一頁”custom_id : ViewButton.ID_GO_TO_LAST_PAGEViewButton.go_to_page()style : discord.ButtonStyle.graylabel :“頁面選擇”custom_id : ViewButton.ID_GO_TO_PAGEViewButton.end_session()discord.ButtonStyle.grayViewButton.ID_END_SESSIONViewButton.all()ViewButton list.go_to_first_page()ViewButton.all_with_emojis()emoji參數的ViewButton list.go_to_first_page()ViewButton.generate_skip(label: str, action: str, amount: int)style : discord.ButtonStyle.graylabel : <label>custom_id : ViewButton.ID_SKIPskip : ViewButton.Skip(<action>, <amount>) menu = ViewMenu ( ctx , ...)
menu . add_page (...)
menu . add_page (...)
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
await menu . start ()您可以將ViewButton設置為被禁用或刪除的視圖頓
class ViewButton.Event(event_type: str, value: int)
event_type ( str )要採取的動作。可以是“禁用”或“刪除”value ( int )指定事件的設置。必須為> = 1。如果值是<= 0,則隱式設置為1例子:
menu = ViewMenu ( ctx , ...)
# disable a button after 5 clicks
button_1 = ViewButton (..., event = ViewButton . Event ( 'disable' , 5 ))
menu . add_button ( button_1 )
# remove a button after 10 clicks
button_2 = ViewButton (..., event = ViewButton . Event ( 'remove' , 10 ))
menu . add_button ( button_2 )注意:對鏈接按鈕無效。也不理想使用
custom_idofViewButton.ID_END_SESSION的按鈕
菜單繼電器是函數,隨時可以按下菜單中的按鈕。它被認為是具有ViewButton.ID_CALLER ID的ViewButton的擴展。與呼叫者按鈕不同,該按鈕沒有提供有關菜單上交互的詳細信息,繼電器可以。
ViewMenu.set_relay(func: Callable[[NamedTuple], None], *, only: Optional[List[ViewButton]]=None)ViewMenu.remove_relay()為繼電器創建函數時,該功能必須包含一個位置參數。按下按鈕時, RelayPayload對象(命名元組)將傳遞給該功能。 RelayPayload的屬性是:
member ( discord.Member )按下按鈕的人button ( ViewButton )按下按鈕例子:
async def enter_giveaway ( payload ):
member = payload . member
channel = payload . button . menu . message . channel
await channel . send ( f" { member . mention } , you've entered the giveaway!" )
menu = ViewMenu ( ctx , ...)
menu . set_relay ( enter_giveaway ) set_relay方法帶有only參數。如果該參數None ,則所有按下的按鈕都將中繼(鏈接按鈕除外,因為它們不發送交互事件)。您可以提供該參數的按鈕list ,因此只有從指定按鈕的按鈕按下將中繼的按鈕。
def example ( payload ):
...
menu = ViewMenu ( ctx , ...)
back_button = ViewButton . back ()
next_button = ViewButton . next ()
menu . set_relay ( example , only = [ back_button ])await ViewMenu.start(*, send_to=None, reply=False)await ViewMenu.stop(*, delete_menu_message=False, remove_buttons=False, disable_buttons=False)啟動菜單時,您可以選擇將菜單發送到某個頻道。參數send_to是您要將菜單發送到的頻道。您可以將send_to設置為頻道名稱( str ),通道ID( int )或通道對象( discord.TextChannel / discord.Thread )。例子:
menu = ViewMenu (...)
# channel name
await menu . start ( send_to = 'bot-commands' )
# channel ID
await menu . start ( send_to = 1234567890123456 )
# channel object
channel = guild . get_channel ( 1234567890123456 )
await menu . start ( send_to = channel )
# there's no need to specify send_to unless you want the menu to be sent to a different channel
# from the one you're sending the initial message/using the command in. the menu can be started
# in the current channel by omitting the send_to parameter
await menu . start ()注意:如果DM的菜單啟動了菜單,則
send_to無效
停止菜單時只有一個選項。如果您有多個參數為True ,則只有一個將執行
delete_menu_message > disable_buttonsdisable_buttons > remove_buttons這是ViewMenu的基本實現,您可以復制和粘貼以快速演示。
import asyncio
import discord
from discord . ext import commands
from reactionmenu import ViewMenu , ViewButton
bot = commands . Bot ( command_prefix = '!' , intents = discord . Intents . all ())
async def start_bot ():
async with bot :
await bot . start ( '...' )
@ bot . command ()
async def example ( ctx ):
menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbed )
for member in ctx . guild . members :
if member . avatar :
embed = discord . Embed ( description = f'Joined { member . joined_at . strftime ( "%b. %d, %Y" ) } ' )
embed . set_author ( name = member . name , icon_url = member . avatar . url )
menu . add_page ( embed )
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
menu . add_button ( ViewButton . end_session ())
await menu . start ()
asyncio . run ( start_bot ())