[精讚] [會員登入]
1058

【Discord bot】[botton]按鈕的使用、響應和關閉

Discord的botton通常都要和View配合使用。

分享此文連結 //n.sfs.tw/16017

分享連結 【Discord bot】[botton]按鈕的使用、響應和關閉@小編過路君子
(文章歡迎轉載,務必尊重版權註明連結來源)
2022-12-13 12:51:31 最後編修
2022-12-12 03:38:52 By 過路君子
 

哈囉大家好,這裡是正在回味舊新聞的小編過路君子

目前正在看「蕭明禮惡意阻擋救護車」和「賴俊吉惡意阻擋救護車」這兩事件當時的新聞。

 

 

上一篇文章我們提到了如何將 Discord 機器人從 1.7.3 更新成 2.0.1,沒看過的可以往這裡走:【Discord bot 2.0.1】如何將舊機器人升級至目前最新版本

在那篇文章裡面我們有提到如果在 on_ready() 函數裡面少了一些設置,可能會造成 Discord 機器人在響應按鈕上失敗:

(所有圖片點擊都可以放大、變高清)

 

而當時小編對於 discord.ui.View 和 discord.ui.button 的介紹僅僅只有如此。

所以,今天小編來詳細的說一下該如何使用 Discord button 這個新的功能。

 

那麼在開始之前,小編先簡單的提一下按鈕的響應。

Discord botton 使用的響應方式是用 callback(event),那至於要如何響應,有兩種實作的方式,分別是:

  1. event 搭配 function 來完成響應。
  2. 使用 class 搭配 event 來完成響應。

小編認為對於程式管理來說第二種方式比較好,使用第一種方式的話程式碼會散落在檔案各處,所以接下來都會以介紹第二種方式為主。

 

Discord.ui.button 宣告

Step1. 宣告class

那我們接下來所有使用到的 class 都在 discord 裡面,所以只要開頭有寫: import discord即可正常執行。

首先我們先來寫個簡單的 class,那這個我們自己寫的 class 必須要繼承 discord.ui.View 呦。

class aButton(discord.ui.View):
    def __init__(self):
        super().__init__()

 

Step2. 註冊按鈕

接下來,我們會直接在這個 class 內註冊一個按鈕:

class aButton(discord.ui.View):
    def __init__(self):
        super().__init__()

    @discord.ui.button(label="confirm", emoji='\u2705', style=discord.ButtonStyle.success)

 

其中 button 後面括號可以設定三種屬性,分別是:

  1. label: 按鈕上所顯示的文字。
  2. emoji: 按鈕上所顯示的表情符號。
  3. style: 按鈕的樣式,總共有五種可選:primary, secondary, success, danger, & link(註1);實際效果可參考下圖。

圖片來源:https://guide.pycord.dev/interactions/ui-components/buttons

 

Step3. 加上callback

講白話一點就是當我們的按鈕被使用者點擊的時候,我們的程式需要做些什麼事情。

那使用方式也非常簡單,直接寫在下方即可。

class aButton(discord.ui.View):
    def __init__(self):
        super().__init__()

    @discord.ui.button(label="confirm", emoji='\u2705', style=discord.ButtonStyle.success)
    async def buttonEvent(self, interaction, button):
        # code here...
        pass

 

其中,按鈕的函數會被傳入兩個參數,而小編在這邊就不細講了,但會將它們的型態和相關的 reference 放在下方,有興趣的人可以自行查閱。

 

Discord.ui.button 基本使用

發送幾顆按鈕出去

class aButton(discord.ui.View):
    def __init__(self):
        super().__init__()

    @discord.ui.button(label="confirm", emoji='\u2705', style=discord.ButtonStyle.success)
    async def buttonEvent(self, interaction, button):
        # code here... 
        pass

class file(default):
    @commands.command()
    @commands.check(Permission.developer)
    async def sendButton(self, ctx):
        view = aButton()
        await ctx.send(content="nothing~", view=view)

async def setup(bot):
    await bot.add_cog(file(bot))

當使用者使用機器人指令「sendButton」的時候,我們的機器人會回應一串文字和一個按鈕給該使用者。

如果要送兩顆或以上的按鈕,就只需要多打幾行 @discord.ui.button 即可,每個按鈕皆可以獨自設定,不一定要每一顆都一樣。

當然,這顆按鈕是沒有任何的功能,畢竟我們按鈕的函數還是只有放 pass 嘛!而接下來我們就會針對此區塊來修改。

 

修改發送的訊息內容

class aButton(discord.ui.View):
    def __init__(self):
        super().__init__()

    @discord.ui.button(label="confirm", emoji='\u2705', style=discord.ButtonStyle.success)
    async def buttonEvent(self, interaction, button):
        await interaction.response.edit_message(content="Hello world")

 

停用按鈕

class aButton(discord.ui.View):
    def __init__(self):
        super().__init__()

    @discord.ui.button(label="confirm", emoji='\u2705', style=discord.ButtonStyle.success)
    async def buttonEvent(self, interaction, button):
        button.disabled = True
        await interaction.response.edit_message(content="Hello world", view=button.view)

這邊比較要注意的一點就是:如果有對按鈕(視圖View)做任何的變更都要傳回客戶端(上方程式最後一行),客戶端才會更新。

所以很多人遇上了明明已經將 disabled 設為 True,但是發現不管怎麼按按鈕,程式碼都沒有生效,其實不是程式碼沒有生效,而是生效了你沒有告知客戶端。

 

移除按鈕

有時候我們需要使用者按下按鈕,但我們只需要顯示對應的純文字訊息,此後按鈕便再無用處。

此時,雖然我們可以直接停用按鈕,但是如果我們每按下一個按鈕便會回傳兩個按鈕,例如:請使用者選擇一個是非題,然後產生兩個按鈕給使用者答題。如果僅僅只是將按鈕停用,很快便會造成版面的紊亂。

所以,這時候我們就必須將舊的按鈕移除,以免造成版面上掛滿數十個被停用的按鈕。

class aButton(discord.ui.View):
    def __init__(self):
        super().__init__()

    @discord.ui.button(label="confirm", emoji='\u2705', style=discord.ButtonStyle.success)
    async def buttonEvent(self, interaction, button):
        button.disabled = True
        button.view.remove_item(button)
        await interaction.response.edit_message(content="Hello world", view=button.view)

 

不響應的按鈕

當我們想要一個啞彈,也就是按下但客戶端不會發生任何事情的按鈕,例如:向其他伺服器發送一段訊息,但我不想讓客戶端發現我偷偷送了訊息出去。

我們的直覺就是直接在函數內寫入 pass 嘛!但是當我們真正按下按鈕的時候卻顯示這樣:

正確的方式是使用 defer() 來告訴客戶端此按鈕並不會回傳任何值會對其做響應。

class aButton(discord.ui.View):
    def __init__(self):
        super().__init__()

    @discord.ui.button(label="confirm", emoji='\u2705', style=discord.ButtonStyle.success)
    async def buttonEvent(self, interaction, button):
        await interaction.response.defer()

 

停止監聽

只要一顆按鈕被創建出來,那我們的 Discord機器人便會持續監聽此按鈕,直至 timeout(預設為 3 分鐘)。

在一般情況之下,我們不主動停止監聽按鈕問題不大(畢竟等到它 timeout 就好了嘛),但是如果我們有手動將 timeout 取消,就會造成伺服器資源被永久占用。

除非將機器人重新啟動,否則被使用完的按鈕仍舊會繼續占用伺服器資源,無法釋出給下一個人使用。

class aButton(discord.ui.View):
    def __init__(self):
        super().__init__()

    @discord.ui.button(label="confirm", emoji='\u2705', style=discord.ButtonStyle.success)
    async def buttonEvent(self, interaction, button):
        button.view.stop()
        await interaction.response.edit_message(content="Hello world", view=view)

使用這種方式要非常注意,如果同時有兩個及以上的按鈕,會一同被停止監聽

 

 

 

後記

上文小編有提到按鈕的樣式總共有五個,但是明明就有人寫了那五個 style 以外的呀!

那其實只是該名稱的別名,其效果是一樣的,小編在此當成附錄羅列出給各位。

樣式名稱 別名
primary blurple
secondary grey, gray
success green
danger red
link url

至於誰是樣式名稱、誰是別名,不是小編自己覺得,而是根據官方的Reference所整理出來的。

END

你可能感興趣的文章

【Wicket】[Header]如何讀取來自客戶端地檔頭和傳送自訂擋頭至客戶端 當需要設定檔頭或是讀取來自客戶端的檔頭時,這些程式碼就很好用

【JAVA】[java.lang.Class]如何不透過new來實體化class 在某些極端狀態下,我們沒有辦法直接將實體化後的 Object 傳入函數內,只能採用傳入 Class 在實體化成物件這種極端的方式來進行

【JDA/discord bot】刪除事件或slash(斜槓)指令的reply訊息 如何正確的等待 Async 的結束,在進行接下來的刪除訊息動作

【Linux】[CentOS 8]如何更新sudo指令 上次會想要更新sudo這個指令的時間應該是2017年了吧?轉眼間就2021了耶

【Stable Diffusion web UI】[AI 作畫](Linux)無 NVIDIA 顯卡之伺服器運行測試 凡事就是要試試看,才知道最後的結果

【JDA/discord bot】如何獲得訊息中的圖片和影片並儲存或轉傳 如何將訊息中的圖片或影片之類的多媒體提取出來之後,再進行相關的處理

我有話要說

>>

限制:留言最高字數1000字。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

高捷少女:美麗島的守護者① 婕兒跟耐耐嚇得臉色發白。「耐耐,小穹有這方面的愛好喔?」婕兒小聲地說。耐耐默默的拿出筆記本,臉上浮現一層微笑:「這麼大的新聞,要趕快記下來!」

高捷少女:美麗島的守護者⑥ 一陣貓叫傳到小雅耳中,原本要朝小雅撲過去的北風轉了個圈,從半空中落地,牠的表情宛如五雷轟頂。這聲音……難道是……

【歌評】蓮台野夜行 - 魔術師梅莉(魔術師メリー)  對於同一首歌每一個人都有不同的見解,看看別人對於這一首歌的看法,說不定就可以聽出這首歌想要表達的事情!

【數學】徐氏數學簡明講義(三) 第二章 直線與園 P2.1-15 Q6 6.平面上有一四邊形ABCD其頂點分別為(0,0)、(2,1)、(3,4)、(-1,5),此平面上另有P,Q兩點,求 :

艾米莉亞和高捷戀旅3(終) 「凝血神爪」,這是那名男子的綽號。會有這個稱號,是因為在他掌控下的夾娃娃機爪子,會變成比導彈還要準確、比刀劍還要凌厲的武器。關主看著那名男子,他已經選定了其中一座小型機台。這種小型機台裡面的娃娃都很小