Go가 설치된 디렉토리(윈도우즈의 경우 디폴트로 C:\Go)를 가리키며, Go 실행파일은 GOROOT/bin 폴더에, Go 표준 패키지들은 GOROOT/pkg 폴더에 존재합니다. 윈도우즈에 GO 설치시 시스템 환경변수로 자동으로 설정됩니다.
GOPATH:
Go는 표준 패키지 이외의 3rd Party 패키지나 사용자 정의 패키지들을 이 GOPATH 에서 찾습니다. 복수 개의 경로를 지정한 경우, 3rd Party 패키지는 처음 경로에 설치됩니다. 그런데 최초 설치시 GOPATH가 C:\C:\Users\USER\go로 지정됩니다. 따라서 다른 폴더를 적용하고 싶을 경우에는 적당한 폴더로 변경해주는 게 좋을 것 같습니다.
GOROOT나 GOPATH나 모두 최초 설치시에는 사용자 변수로 등록되므로, 저는 삭제하고 다시 시스템 변수로 등록해주었습니다. 그리고 GOPATH는 3rd party 패키지 설치를 위한 폴더, 직접 작업할 파일 폴더, 이렇게 두 폴더를 각각 지정해 두었습니다.
3. Hello World 출력
LiteIDE로 작업을 했습니다. 폴더 하나를 생성하고, hello.go파일을 만들면 자동으로 아래와 같이 디폴트로 코드가 생성됩니다. 여기서 BR을 눌러줘도 되구요... (main함수가 한 폴더에 두개이상 존재하면 에러가 나기 때문에, 별도의 폴더를 생성하는 것이 필요합니다.)
커맨드 창에서 실행해도 잘 출력되는 것을 확인할 수 있습니다.
이상으로 Go언어 설치/환경변수 설정/Hello world 출력하는 방법에 대해 간단히 알아보았습니다.
3. 컨트롤->GtkButton 3개를 생성해서 아이디를 TestBtn, HelloBtn, exitBtn으로 해주세요. 그리고 그에 맞게 레이블도 수정해 줍니다.
이렇게 구성하면 glade2.glade 로 저장합니다. 물론 아무 이름이나 상관 없습니다만, 그럴 경우 아래 소스코드의 파일명 부분을 적당히 수정해주세요. 이제 아래의 소스코드를 수행해봅니다.
// gotk_glade.go
package main
import (
"errors"
"fmt"
"log"
"os"
"reflect"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
)
var headerBar *gtk.HeaderBar
func main() {
// Create a new application.
application, err := gtk.ApplicationNew("new.test", glib.APPLICATION_FLAGS_NONE)
errorCheck(err)
// Connect function to application startup event, this is not required.
application.Connect("startup", func() {
log.Println("application startup")
})
// Connect function to application activate event
application.Connect("activate", func() {
log.Println("application activate")
// Get the GtkBuilder UI definition in the glade file.
builder, err := gtk.BuilderNewFromFile("glade2.glade")
errorCheck(err)
// Map the handlers to callback functions, and connect the signals
// to the Builder.
signals := map[string]interface{}{
"on_main_window_destroy": onMainWindowDestroy,
"on_HelloBtn_clicked": clickedTestButton,
}
builder.ConnectSignals(signals)
// Get the object with the id of "main_window".
obj, err := builder.GetObject("main_window")
fmt.Println(reflect.TypeOf(obj))
errorCheck(err)
// Verify that the object is a pointer to a gtk.ApplicationWindow.
win, err := isWindow(obj)
fmt.Println(reflect.TypeOf(win))
errorCheck(err)
headerBar, err := builder.GetObject("headerbar")
errorCheck(err)
fmt.Println(reflect.TypeOf(headerBar))
//headerBar.SetTitle("sss")
// Show the Window and all of its components.
win.Show()
application.AddWindow(win)
})
// Connect function to application shutdown event, this is not required.
application.Connect("shutdown", func() {
log.Println("application shutdown")
})
// Launch the application
os.Exit(application.Run(os.Args))
}
func isWindow(obj glib.IObject) (*gtk.Window, error) {
// Make type assertion (as per gtk.go).
if win, ok := obj.(*gtk.Window); ok {
return win, nil
}
return nil, errors.New("not a *gtk.Window")
}
func errorCheck(e error) {
if e != nil {
// panic for any errors.
log.Panic(e)
}
}
// onMainWindowDestory is the callback that is linked to the
// on_main_window_destroy handler. It is not required to map this,
// and is here to simply demo how to hook-up custom callbacks.
func onMainWindowDestroy() {
log.Println("onMainWindowDestroy")
}
func clickedTestButton() {
fmt.Println("Testclick")
//headerBar.SetTitle("New Title!!")
}
1. 우선 Oracle Instant Client를 설치해야 합니다. 이건 다른 드라이버들을 설치한다고 해도 공통적인 사항입니다.
2. godror을 아래 명령어로 설치를 합니다.
go get github.com/godror/godror
3. 아래의 소스를 작성해서 테스트해 봅니다.
package main
import (
"database/sql"
"fmt"
_ "github.com/godror/godror"
)
func main() {
db, err := sql.Open("godror", "username/password@service_name:port/SID")
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
rows, err := db.Query("select EMP_#1 from TEMP where NAME='홍길동'")
if err != nil {
fmt.Println("Error running query")
fmt.Println(err)
return
}
defer rows.Close()
var emp string // DB에서 받을 데이터를 저장할 변수 선언
for rows.Next() {
rows.Scan(&emp) // DB에서 받은 데이터 할당
}
fmt.Printf("The date is: %s\n", emp)
}
사내에서 사용할 간단한 GUI프로그램 개발 환경을 구상 중입니다. 배포도 해야해서 VM위에서 돌아가는 Java는 좀 꺼림직하고... 다른 언어로 쓸 수 있는 GUI Toolkit을 찾아보다가 결국 QT/GTK/WxWidgets 로 가야할 것 같은데요. 배포가 어렵다는 C/C++로 가는 것 보다는 요즘 언어인 Go언어로, 그리고 바인딩이 잘 되어있는 GTK로 가보려고 합니다. Go언어 바인딩은 Gotk3가 있습니다. 이번 포스트에서는 Gotk3설치 및 예제 프로그래밍까지 수행해 보겠습니다.
우선 사전 준비해야 하는 작업이 좀 있습니다. 생각보다....(이거 하면서 그냥 Swing써야겠다고 생각하는 중....ㅠㅠ)
1. git 설치
2. MinGW-w64설치(MSYS2설치)
3. GTK 및 dependencies 설치
4. MinGW 환경변수 추가
5. Gotk3 설치
6. 예제 실행
1. GIT 설치
요기 사이트로 가서 Git을 설치합니다. 요즘은 Git을 알아야 한다는데,, 아직 제가 잘 몰라서,,
나중에 공부해서 올리는 것으로 하고, 우선 설치하겠습니다.
2. MinGW-w64설치(MSYS2설치)
요기 사이트에서 msys2-x86_64-xxxxxxx.exe파일을 다운받아 설치해 줍니다. 이걸 설치하면 리눅스에서 사용하던 터미널이 생깁니다. 그럼 리눅스 명령어로 GTK를 설치할 준비가 됩니다.
를 마지막에 한번 실행해 줘야 나중에 컴파일 할 때 에러가 없습니다. 버그픽스 명령어 같습니다.
4. MinGW 환경변수 추가
- C:\msys64\mingw64\bin
- C:\msys64\usr\bin
요 두 폴더를 Path에 추가해줍니다.
5. Gotk3 설치
이제 진짜 Gotk3가 설치되는지 보겠습니다. 이번엔 Git 터미널에서 아래 명령어를 수행합니다.
go get github.com/gotk3/gotk3/gtk
뭔가 에러가 조금 있었지만, Fail은 아닌 것 같습니다.
한번 아래 코드로 실행이 되는지 보겠습니다.
6. 예제 실행
아래 소스를 입력하고 Build&Run을 수행합니다.
Golang이 원래 컴파일이 엄청 빠른 언어인데, 최초 컴파일 때는 시간이 많이 걸립니다. 낼 출근이 심히 걱정됩니다...
4시간 자야되네...ㅠㅠ이게 머라고..
package main
import (
"log"
"github.com/gotk3/gotk3/gtk"
)
func main() {
// Initialize GTK without parsing any command line arguments.
gtk.Init(nil)
// Create a new toplevel window, set its title, and connect it to the
// "destroy" signal to exit the GTK main loop when it is destroyed.
win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
if err != nil {
log.Fatal("Unable to create window:", err)
}
win.SetTitle("Simple Example")
win.Connect("destroy", func() {
gtk.MainQuit()
})
// Create a new label widget to show in the window.
l, err := gtk.LabelNew("Hello, gotk3!")
if err != nil {
log.Fatal("Unable to create label:", err)
}
// Add the label to the window.
win.Add(l)
// Set the default window size.
win.SetDefaultSize(800, 600)
// Recursively show all widgets contained in this window.
win.ShowAll()
// Begin executing the GTK main loop. This blocks until
// gtk.MainQuit() is run.
gtk.Main()
}
비동기 프로그래밍을 직접 해본적이 없어서 잘은 모르지만, 아래 예제를 보니 정말 쉬운 것 같습니다.
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 10; i++ {
fmt.Println(s, "***", i)
}
}
func main() {
// 함수를 동기적으로 실행
say("Sync")
// 함수를 비동기적으로 실행
go say("Async1")
go say("Async2")
go say("Async3")
// 3초 대기
time.Sleep(time.Second * 3)
}