[精讚] [會員登入]
1528

【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

你可能感興趣的文章

【Nexus Repository Manager】(deploy)使他人可以對遠端資料庫做讀寫 使用 Nexus Repository Manager 來讓各個工程師控制自己的 Jar 包,不會有 Github Merge Crashed 問題。

【Wildfly/jBoss】[Linux](Connection Datasource)如何與MySQL資料庫建立連線 網頁瀏覽器和資料庫的關係密不可分,而通常會將兩者分開架設在不同的伺服器上面來提供服務,這時要如何進行連線呢?

【C】(%c, %d)解決讀取字元時的緩衝區殘留 不解決就會莫名其妙地冒出一些莫名其妙的東西

【教程】[HTML](進階版)如何在手機上編輯電子書(epub)預覽介面 可能會有人認為電子書(epub)只能用電腦來開啟、編輯,其實不是的,手機也可以編輯喔!

【Firefox \ Maven】[Headless](Linux) 如何使用Maven打包並驅動Firefox 有時候我們需要取得渲染後的網頁,當然是直接呼叫瀏覽器出來用啦

【Docker&Wildfly】(bitnami/wildfly)如何從零開始創建網頁伺服器 使用他人的 docker image 來架設我們的 wildfly web server

我有話要說

>>

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

訪客留言

[無留言]

隨機好文

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

婕兒──她的青春④ 「投降吧,耐耐!這回合妳將不會再有獲勝的機會了!哈哈哈哈!」 「妳確定?」耐耐臉上泛起一絲微笑,並將手中的牌展示給婕兒看 婕兒的笑容僵住了。恐懼浮現在她的臉。

艾米莉亞和高捷戀旅② 七點三十五分了。 「快到粉絲團!快!」小穹慌張地說,婕兒、耐耐也湊向手機。雖然她們沒有報名,不過也希望亦晨參賽,不免著急起來。 「亦晨?妳的報名序號是多少?」艾米快速滑動手機。合格的參賽者姓名和序號都

【英文作文賞析】說明使用塑膠製品對環境及人類傷害 由Fanny示範時所寫出的範文,雖然不是很完美,但是基本架構都已經具備了!

小穹‧動畫化‧體驗記⑧ 「我拒絕。」蕾蕾翹起腿。「妳也拒絕得太直接了吧?」小穹哭喪著臉。昨天寫好劇情大綱後,小穹把文檔傳給婕兒跟耐耐,並把自己的想法告訴她倆。她們兩個看