Go로 간단한 시스템 트레이 앱 만들기
실습: 다른 국가를 선택할 수 있는 가능성과 함께 현재 현지 시간을 보여주는 시스템 트레이 애플리케이션을 빌드해 보겠습니다.
우리는 Getlantern의 라이브러리systray를 사용할 것입니다.
package main
import (
"fmt"
"io/ioutil"
"github.com/getlantern/systray"
)
func main() {
systray.Run(onReady, onExit)
}
func onReady() {
systray.SetIcon(getIcon("assets/clock.ico"))
systray.SetTitle("I'm alive!")
systray.SetTooltip("Look at me, I'm a tooltip!")
}
func onExit() {
// Cleaning stuff here.
}
func getIcon(s string) []byte {
b, err := ioutil.ReadFile(s)
if err != nil {
fmt.Print(err)
}
return b
}
이 코드를 바로 사용해 볼 수 있습니다.
할 일은 시스템 트레이에 아이콘과 함께 간단한 메시지를 표시하는 것뿐입니다. 그게 다야.
이것을 조금 나누어 봅시다. out
main()
에서 우리가 할 수 있는 유일한 일은 함수Run
를 사용하여 라이브러리 systray의 새 인스턴스를 호출하는 것입니다. 이 함수는 onReady에서 수행할 작업과 애플리케이션이 종료될 때 정의하는 몇 가지 매개 변수를 받습니다.SetIcon
, SetTitle
및 SetTooltip
는 매우 간단합니다. 고려해야 할 유일한 사항은 SetIcon
가 []바이트로 표시하려는 아이콘을 매개변수로 사용한다는 것입니다. 함수getIcon
를 사용하여 .ico 파일을 읽고 []바이트를 반환합니다.힌트: 무료 아이콘을 찾을 수 있는 좋은 장소는 IconArchive입니다.
이제 우리는 내가 살아있다는 것을 원하지 않습니다! 제목으로 타이머의 로컬 값으로 매초를 업데이트할 것입니다.
onReady()
함수를 업데이트하고 시간 값을 얻는 데 도움이 되는 몇 가지를 더 추가해 보겠습니다.func onReady() {
systray.SetIcon(getIcon("assets/clock.ico"))
for {
systray.SetTitle(getTime())
systray.SetTooltip("Look at me, I'm a tooltip!")
time.Sleep(1 * time.Second)
}
}
func getTime() string {
t := time.Now()
hour, min, sec := t.Clock()
return ItoaTwoDigits(hour) + ":" + ItoaTwoDigits(min) + ":" + ItoaTwoDigits(sec)
}
// ItoaTwoDigits time.Clock returns one digit on values, so we make sure to convert to two digits
func ItoaTwoDigits(i int) string {
b := "0" + strconv.Itoa(i)
return b[len(b)-2:]
}
실행하면 시계가 매초 업데이트되는 것을 볼 수 있습니다. 그러나 이것은 autoupdater를 구현하는 가장 좋은 방법은 아닙니다.
time.Sleep()
를 구현하면 현재 인스턴스를 일시 중지할 수 있지만 기본 프로세스를 차단하고 싶지는 않습니다. 이 경우 Go routine을 사용합니다.go func() {
for {
systray.SetTitle(getTime())
systray.SetTooltip("Look at me, I'm a tooltip!")
time.Sleep(1 * time.Second)
}
}()
이제 메뉴 항목을 추가할 차례입니다.
systray.AddMenuItem("Title", "Tooltip")
로 쉽게 할 수 있습니다. 이 함수는 누르면 채널을 반환합니다. 그래서 이런 식으로 몇 가지 항목을 추가하려고 합니다.localTime := systray.AddMenuItem("Local time", "Local time")
hcmcTime := systray.AddMenuItem("Ho Chi Minh time", "Asia/Ho_Chi_Minh")
sydTime := systray.AddMenuItem("Sydney time", "Australia/Sydney")
gdlTime := systray.AddMenuItem("Guadalajara time", "America/Mexico_City")
sfTime := systray.AddMenuItem("San Fransisco time", "America/Los_Angeles")
systray.AddSeparator()
mQuit := systray.AddMenuItem("Quit", "Quits this app")
또한 코드 상단에 사용 중인 시간대를 추적하는 방법을 추가해 보겠습니다.
var (
timezone string
)
그리고
systray.SetTitle(getTime())
를 systray.SetTitle(getClockTime(timezone))
로 바꿉니다.이제 메뉴 항목을 눌렀을 때 가져오는 방법입니다.
go func() {
for {
select {
case <-localTime.ClickedCh:
timezone = "Local"
case <-hcmcTime.ClickedCh:
timezone = "Asia/Ho_Chi_Minh"
case <-sydTime.ClickedCh:
timezone = "Australia/Sydney"
case <-gdlTime.ClickedCh:
timezone = "America/Mexico_City"
case <-sfTime.ClickedCh:
timezone = "America/Los_Angeles"
case <-mQuit.ClickedCh:
systray.Quit()
return
}
}
}()
그리고 시간대 선택기와 좀 더 호환되도록
getTime
함수를 수정해 보겠습니다.func getClockTime(tz string) string {
t := time.Now()
utc, _ := time.LoadLocation(tz)
hour, min, sec := t.In(utc).Clock()
return ItoaTwoDigits(hour) + ":" + ItoaTwoDigits(min) + ":" + ItoaTwoDigits(sec)
}
힌트: 시간대 식별자는 IANA 시간대 식별자로 알려져 있습니다. 그렇게 구글링. time.is에서 필요한 도시의 식별자를 쉽게 얻을 수 있습니다.
따라서 모든 코드는 다음과 같아야 합니다.
package main
import (
"fmt"
"io/ioutil"
"strconv"
"time"
"github.com/getlantern/systray"
)
var (
timezone string
)
func main() {
systray.Run(onReady, onExit)
}
func onReady() {
timezone = "Local"
systray.SetIcon(getIcon("assets/clock.ico"))
localTime := systray.AddMenuItem("Local time", "Local time")
hcmcTime := systray.AddMenuItem("Ho Chi Minh time", "Asia/Ho_Chi_Minh")
sydTime := systray.AddMenuItem("Sydney time", "Australia/Sydney")
gdlTime := systray.AddMenuItem("Guadalajara time", "America/Mexico_City")
sfTime := systray.AddMenuItem("San Fransisco time", "America/Los_Angeles")
systray.AddSeparator()
mQuit := systray.AddMenuItem("Quit", "Quits this app")
go func() {
for {
systray.SetTitle(getClockTime(timezone))
systray.SetTooltip(timezone + " timezone")
time.Sleep(1 * time.Second)
}
}()
go func() {
for {
select {
case <-localTime.ClickedCh:
timezone = "Local"
case <-hcmcTime.ClickedCh:
timezone = "Asia/Ho_Chi_Minh"
case <-sydTime.ClickedCh:
timezone = "Australia/Sydney"
case <-gdlTime.ClickedCh:
timezone = "America/Mexico_City"
case <-sfTime.ClickedCh:
timezone = "America/Los_Angeles"
case <-mQuit.ClickedCh:
systray.Quit()
return
}
}
}()
}
func onExit() {
// Cleaning stuff here.
}
func getClockTime(tz string) string {
t := time.Now()
utc, _ := time.LoadLocation(tz)
hour, min, sec := t.In(utc).Clock()
return ItoaTwoDigits(hour) + ":" + ItoaTwoDigits(min) + ":" + ItoaTwoDigits(sec)
}
// ItoaTwoDigits time.Clock returns one digit on values, so we make sure to convert to two digits
func ItoaTwoDigits(i int) string {
b := "0" + strconv.Itoa(i)
return b[len(b)-2:]
}
func getIcon(s string) []byte {
b, err := ioutil.ReadFile(s)
if err != nil {
fmt.Print(err)
}
return b
}
🎉
이 기능을 구현하는 다른/더 나은 방법을 알고 계십니까?
시간대 선택/채널을 하드코딩하는 것 같은데 이 부분을 최적화할 수 있는 방법을 찾을 수 있을까요?
실행할 준비가 된 모든 코드는 github.com/Osuka42g/simple-clock-systray 에서 찾을 수 있습니다. 해킹! ðŸ»
Reference
이 문제에 관하여(Go로 간단한 시스템 트레이 앱 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/osuka42/building-a-simple-system-tray-app-with-go-899텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)