<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          GoUI:一個(gè)非常簡單的 GUI 框架

          共 5113字,需瀏覽 11分鐘

           ·

          2020-10-01 08:10


          點(diǎn)擊上方藍(lán)色“Go語言中文網(wǎng)”關(guān)注,回復(fù)「電子書」領(lǐng)全套Go資料

          最近,我一直想開發(fā)一些桌面(主要是 Windows,但也可以考慮 MacOS 或 Linux)應(yīng)用程序。雖然 Go 不是開發(fā) UI 應(yīng)用程序時(shí)首選語言,但是該語言的簡單性和健壯性仍然使它成為我的首選語言。是的,這是我的錘子(hammer)... 但這是一個(gè)該死的漂亮錘子。

          以前,我曾將 Ebiten 圖形庫用于 Go,以便與孩子們一起編寫一些游戲。但是,對(duì)于一般的“應(yīng)用程序”開發(fā)(即需要“小部件 widgets”,例如按鈕,菜單等),Ebiten 并非真的適合。因此,我一直在尋找可以使用的 Go UI 庫。然而大多數(shù)都使用 cgo,但我真的希望我的應(yīng)用程序是純 Go。這純粹是個(gè)人喜好,我不知道使用 cgo 而不是純 Go 會(huì)有什么影響。如果我要使用 cgo,我認(rèn)為首選的 UI 庫肯定是 Fyne[1]。Fyne 看起來是一個(gè)非常全面的框架,如果您不介意 cgo,我絕對(duì)會(huì)建議你看看看 Fyne。

          還有其他一些庫,但沒有吸引我。他們說你永遠(yuǎn)不應(yīng)該編寫自己的安全性代碼,并且我也相信你不應(yīng)該編寫自己的 UI 庫。但是我忽略了這個(gè)建議...

          因此,我寫了一個(gè) GoUI[2] !!

          這純粹是那些“抓癢”的項(xiàng)目之一。雖然現(xiàn)在還很早,但 UI 庫的基本知識(shí)(由 Ebiten 進(jìn)行實(shí)際渲染)正在慢慢融合。在詳細(xì)介紹下面細(xì)節(jié)之前,我想先說明一下,我認(rèn)為程序在 CLI 達(dá)到了頂峰。其次,我不是 UI 編程人員……寫這些是我個(gè)人的興趣。

          GoUI 的基本思想是兩種類型的圖形元素。一個(gè)是可以包含其他面板或小部件的面板(Panel)。另一個(gè)是小部件,它是基本的 UI 元素(按鈕,文本輸入等)。我們目前使用的面板類型有 HPanel(水平添加)和 VPanel(我讓你猜)。從技術(shù)上講,我們確實(shí)有其他面板,例如工具欄,但這實(shí)際上只是 HPanel,需要一點(diǎn)點(diǎn)定制工作。總體而言,如果我可以結(jié)合其他現(xiàn)有面板/小工具來構(gòu)造一些“新”東西,那么我會(huì)做的。如果我需要優(yōu)化或與已有產(chǎn)品脫節(jié),那么我將做一些全新的事情。

          我們目前擁有的小部件是:

          • ImageButton:(由應(yīng)用程序提供的單擊/未單擊的圖像)。

          • TextButton:基本的彩色矩形,其中包含您想要的任何文本。

          • Checkbox:與 TextButton 相同,但是旁邊有一個(gè)小方框,可以打?qū)础?/p>

          • EmptySpace:完全由我控制。用于強(qiáng)制其他小部件之間的空間。一旦添加適當(dāng)?shù)奶畛洌撎畛淇赡軙?huì)消失。

          • Label:文本標(biāo)簽,不能輸入。

          • Text Input:文本輸入框。

          • RadioButtonGroup:這是一個(gè)面板,其中包含 vpanel 或 hpanel(取決于標(biāo)志),然后其中包含許多復(fù)選框。復(fù)選框?qū)D像(帶有刻度)替換為常規(guī)的單選按鈕。這是重新使用現(xiàn)有窗口小部件的好例子。如果事實(shí)證明我需要對(duì)復(fù)選框進(jìn)行足夠的修改以使其不適合用作單選按鈕,那么我將不得不放入一個(gè)真正的單選按鈕。但是目前,它運(yùn)行良好。

          我還沒有完成菜單,模態(tài)窗口等,但是正如我所說的……這還是早期。

          現(xiàn)在,讓我們嘗試一個(gè)超級(jí)簡單的 Demo。

          package?main
          ?
          import?(
          ????"github.com/hajimehoshi/ebiten"
          ????"github.com/kpfaulkner/goui/pkg"
          ????"github.com/kpfaulkner/goui/pkg/widgets"
          ????log?"github.com/sirupsen/logrus"
          ????"image/color"
          )
          ?
          type?MyApp?struct?{
          ????window?pkg.Window
          }
          ?
          func?NewMyApp()?*MyApp?{
          ????a?:=?MyApp{}
          ????a.window?=?pkg.NewWindow(800,?600,?"test?app",?false,?false)
          ????return?&a
          }
          ?
          func?(m?*MyApp)?SetupUI()?error?{
          ????vPanel?:=?widgets.NewVPanel("main?vpanel",?&color.RGBA{0,?0,?0,?0xff})
          ????m.window.AddPanel(vPanel)
          ????button1?:=?widgets.NewTextButton("text?button?1",?"my?button1",?true,?0,?0,?nil,?nil,?nil,?nil)
          ????vPanel.AddWidget(button1)
          ????return?nil
          }
          ?
          func?(m?*MyApp)?Run()?error?{
          ????m.SetupUI()
          ????ebiten.SetRunnableInBackground(true)
          ????ebiten.SetWindowResizable(true)
          ????m.window.MainLoop()
          ????return?nil
          }
          ?
          func?main()?{
          ????log.SetLevel(log.DebugLevel)
          ????app?:=?NewMyApp()
          ????app.Run()
          }

          讓我們解釋一下以上代碼。

          首先,該程序的核心仍然是直接調(diào)用 Ebiten。這些尚未封裝。因此,你將在 main 和 Run 函數(shù)中看到,我們基本上已經(jīng)制作了 MyApp 結(jié)構(gòu)的實(shí)例,然后調(diào)用 SetupUI,設(shè)置一些 Ebiten 標(biāo)志,然后調(diào)用 MainLoop。

          NewMyApp 函數(shù)調(diào)用 pkg.NewWindow 函數(shù)。這是應(yīng)用程序的主窗口。一旦添加了模態(tài)/其他窗口,這可能會(huì)更改,但是就目前而言,這將創(chuàng)建給定大小的主 UI 窗口。

          SetupUI 是你需要注意的地方。我們要做的第一件事是創(chuàng)建一個(gè) VPanel。請(qǐng)記住,VPanel 把小部件垂直堆疊放置。我們將 vPanel 添加到主窗口。實(shí)際上(當(dāng)前),我們應(yīng)該只在主窗口中添加 1 個(gè)面板,其他所有內(nèi)容都應(yīng)放入該面板中。因此,在這種情況下,我們創(chuàng)建 button1(新的 TextButton)并將其添加到 vPanel。

          花點(diǎn)時(shí)間來學(xué)習(xí)理解一下上面的 UI 技能。

          下面,讓我們做一些更有趣的事情。假設(shè)我們要在按下按鈕時(shí)做出響應(yīng)。創(chuàng)建 TextButton 的行是:

          button1?:=?widgets.NewTextButton("text?button?1",?"my?button1",?true,?0,?0,?nil,?nil,?nil,?nil)

          所有細(xì)節(jié)就不描述了,但是最后一個(gè)參數(shù)是帶有 func (event IEvent) error 簽名的事件處理程序。因此,如果我們創(chuàng)建一個(gè)帶有該簽名的方法,并將其作為最后一個(gè)參數(shù)傳遞給 NewTextButton。

          func?(m?*MyApp)?ButtonAction1(event?events.IEvent)?error?{
          ????log.Debugf("My?button1?action?1!!!")
          ????return?nil
          }

          然后我們將按鈕創(chuàng)建修改為

          button1?:=?widgets.NewTextButton("text?button?1",?"my?button1",?true,?0,?0,?nil,?nil,?nil,?m.ButtonAction1)

          現(xiàn)在,當(dāng)單擊按鈕時(shí),將調(diào)用 ButtonAction1 函數(shù),我們可以觸發(fā)所需的任何功能。

          是不是很簡單。

          現(xiàn)在,如果我想要在按鈕旁邊放點(diǎn)東西該怎么辦?我們?cè)谶@里要做的是創(chuàng)建一個(gè) HPanel,并將其首先放入 VPanel。然后,將按鈕添加到 HPanel。如果這樣做,我們最終將得到如下代碼:

          func?(m?*MyApp)?SetupUI()?error?{
          ?
          ????vPanel?:=?widgets.NewVPanel("main?vpanel",?&color.RGBA{0,?0,?0,?0xff})
          ????m.window.AddPanel(vPanel)
          ?
          ????hPanel?:=?widgets.NewHPanel("hpanel1",?&color.RGBA{0,?100,?0,?255})
          ????vPanel.AddWidget(hPanel)
          ?
          ????button1?:=?widgets.NewTextButton("text?button?1",?"my?button1",?true,?0,?0,?nil,?nil,?nil,?m.ButtonAction1)
          ????hPanel.AddWidget(button1)
          ?
          ????return?nil
          }

          從視覺上看,什么都不會(huì)改變。我們?nèi)匀恢伙@示 1 個(gè)小部件。

          現(xiàn)在,如果我們?cè)谕?HPanel 中添加一個(gè)復(fù)選框怎么辦?

          func?(m?*MyApp)?SetupUI()?error?{
          ?
          ????vPanel?:=?widgets.NewVPanel("main?vpanel",?&color.RGBA{0,?0,?0,?0xff})
          ????m.window.AddPanel(vPanel)
          ?
          ????hPanel?:=?widgets.NewHPanel("hpanel1",?&color.RGBA{0,?100,?0,?255})
          ????button1?:=?widgets.NewTextButton("text?button?1",?"my?button1",?true,?0,?0,?nil,?nil,?nil,?m.ButtonAction1)
          ????hPanel.AddWidget(button1)
          ?
          ????cb1?:=?widgets.NewCheckBox("my?checkbox1",?"check?me?please",?"",?"",?nil)
          ????hPanel.AddWidget(cb1)
          ?
          ????vPanel.AddWidget(hPanel)
          ????return?nil
          }

          因此,與之前完全相同,但只有這額外的兩條:創(chuàng)建復(fù)選框,然后添加到 hPanel。

          現(xiàn)在 UI 看起來是這樣:

          現(xiàn)在不擔(dān)心這里的間距了。

          現(xiàn)在讓我們?cè)?TextButton 下面添加一個(gè) ImageButton。這意味著我們將向 vPanel 添加第二項(xiàng)(第一項(xiàng)是 hPanel)

          imageButton?:=?widgets.NewImageButton("ib1",?"images/pressedbutton.png",?"images/nonpressedbutton.png",nil?)
          vPanel.AddWidget(imageButton)

          這是效果如下:

          這時(shí),我們有了 2 張圖片(屏幕截圖中只顯示了一張)。按下按鈕時(shí)一個(gè),不按下時(shí)一個(gè)(只更改了陰影)。懂了吧。

          好了,介紹就這么多。雖然該 UI 庫還不完善,但 GUI 的基本功能已經(jīng)可以實(shí)現(xiàn)了。再次放上該庫的地址:https://github.com/kpfaulkner/goui。

          作者:kpfaulkner[3]

          日期:2020 年 8 月 17 日

          原文鏈接:https://kpfaulkner.wordpress.com/2020/08/17/goui-a-very-simple-ui-framework/

          譯者:polaris

          參考資料

          [1]

          Fyne: https://fyne.io/

          [2]

          GoUI: https://github.com/kpfaulkner/goui

          [3]

          kpfaulkner: https://kpfaulkner.wordpress.com/author/kpfaulkner/



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包(下圖只是部分),同時(shí)還包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。

          關(guān)注公眾號(hào) 「polarisxu」,回復(fù) ebook 獲取;還可以回復(fù)「進(jìn)群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 75
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本一线视频在线观看 | 人妻体体内射精一区二区 | 午夜精品久久久久久久 | 国产色爱综合操网 | 日本韩国无码 |