반응형

콘솔에서 빌드 시 -ldflags -H=windowsgui 플래그옵션을 함께 줘서 합니다.

go build -ldflags -H=windowsgui filename.go

 

 

반응형
반응형

오늘은 또다시 새로운 시도를 해 봅니다.

다들 Golang 강좌 / Web Framework 등 관련 포스트들이 많은데, 이 블로그에서는 항상 사이드 팁들만 올리는 것 같네요. 하지만 누군가는 필요한 사람도 있겠죠?^^;; 그렇게 믿어봅니다.

 

Golang 윈도우즈용 실행파일을 만들고나면 너무 멋없잖아요? 특히나 바탕화면에 둘 때엔..이렇게....

 

 

그래서 준비했습니다.

윈도우즈용 실행파일 아이콘 만들기!!

우선, 이거 하나 해보겠다고 Stack Overflow 꼬부랑 글씨 따라 한 삽질이 좀 되는데요...

1).  goversioninfo 설치 

  1 go get github.com/josephspurrier/govrsioninfo/cmd/goversioninfo

  2. testdata/resource/versioninfo.json을 작업 디렉토리로 복사

  3. //go:generate goversioninfo -icon=testdata/resource/icon.ico -manifest=testdata/resource/goversioninfo.exe.manifest 를 소스코드 상단에 추가

  4 go generate

  5 go build 

=> 결론은 잘 안됨. (설정을 잘 몰라서 그럴 것 같습니다만....어려워서 포기)

 

2). rsrc 설치

   1.  go get github.com/akaval/rsrc

   2.  rsrc -manifest goversioninfo.exe.manifes -ico icon.ico -o resource.syso (각 파일은 goversioninfo 설치파일로부터...)

==>결론은 이것도 안됨. 다 필요없음~

 

서론이 기네요. 본론 결론은 완전 간단!

리소스해커라는 프로그램이 있습니다. 이게 답입니다.^^;;;

 

 

 

우선 위 사이트로 가서 윈도우즈용 exe 설치파일을 다운받습니다. 그리고 설치합니다.

 

초간단 설치

 

그리고 리소스 해커를 실행해줍니다. 

 

 

그리고 나서...

1. File -> Open -> XXX.exe (go 빌드한 실행파일)

2. Action -> Add an Image or Other Binary Resource ... 를 클릭하고 

3. 본인이 마련한 XXX.ico 파일(아이콘으로 쓸 파일, ico형식이어야 함)을 선택해줍니다.

4. 저장. 끝!

 

아래 사진들은 참고하시기 바랍니다.

 

1. 실행파일 Open 후, 2. Action->Add an Image or Other Binary Resource ... 를  클릭

 

 

 

3. Select File 에서 XXX.ico파일 선택(윈도우 아이콘 이미지는 .ico형식이어야 함)

 

 

 

 

4. 최종 아이콘 이미지가 적용된 모습

 

자~ 바탕화면에도, 탐색기에서도 아이콘이 원하는 이미지로 잘 세팅되었죠?

이것으로 golang 실행파일 아이콘 만들기를 마치겠습니다.

 

-끝-

 

 

반응형
반응형

Fyne를 이용하여 Layout 구성하는 예제입니다.

//Fyne Layout Test

package main

import (
	"fmt"

	"fyne.io/fyne"
	"fyne.io/fyne/app"
	"fyne.io/fyne/layout"
	"fyne.io/fyne/widget"
)

func main() {
	f := app.New()
	w := f.NewWindow("")

	//상단에 넣을 위젯 및 레이아웃 - NewFormLayout
	lb_db_addr := widget.NewLabel("DB Address")
	tf_db_addr := widget.NewEntry()
	tf_db_addr.SetPlaceHolder("database@databaseservr.com:1526/orcl")

	lbUser := widget.NewLabel("Username")
	tfUser := widget.NewEntry()

	lbPass := widget.NewLabel("Password")
	tfPass := widget.NewPasswordEntry()

	qry := widget.NewEntry()
	btn_go := widget.NewButton("Go", func() { fmt.Println("Go Button") })

	ret := fyne.NewContainerWithLayout(layout.NewFormLayout())
	ret.AddObject(lb_db_addr)
	ret.AddObject(tf_db_addr)
	ret.AddObject(lbUser)
	ret.AddObject(tfUser)
	ret.AddObject(lbPass)
	ret.AddObject(tfPass)
	ret.AddObject(btn_go)
	ret.AddObject(qry)

	//하단에 넣을 위젯 및 전체 레이아웃 구성 - NewBorderLayout
	label2 := widget.NewLabel("Simple Data Search")
	labox2 := fyne.NewContainerWithLayout(layout.NewCenterLayout(), label2)

	b1 := widget.NewButton("Go1", func() { fmt.Println("Go1 Button") })
	b1.ExtendBaseWidget(b1)

	b2 := widget.NewButton("Go2", func() { fmt.Println("Go2 Button") })
	b2.ExtendBaseWidget(b2)

	out_entry := widget.NewEntry()
	out_entry.SetPlaceHolder("Results...")
	out_entry.ExtendBaseWidget(out_entry)

	frm := fyne.NewContainerWithLayout(layout.NewBorderLayout(ret, labox2, nil, nil)) //상, 하, 좌(없음), 우(없음)
	frm.AddObject(ret)                                                                //상단
	frm.AddObject(labox2)                                                             //하단
	frm.AddObject(out_entry)                                                          //좌-우가 없으므로 5번째에(center) 추가됨

	w.SetContent(frm)
	w.Resize(fyne.Size{Height: 640, Width: 480})
	w.ShowAndRun()

}

 

 

 

반응형
반응형

Fyne를 이용하여 GUI에서 테이블을 구현해 보았습니다.

아직 익숙하지 않아서 굴러다니는 소스 복사해다가 몇가지 위치/사이즈만 변형시켜보는 수준이지만,

필요하신 분이 있을지도 모른다는 희망에 올려봅니다.

package main

import (
	"fmt"

	"fyne.io/fyne"
	"fyne.io/fyne/app"
	"fyne.io/fyne/layout"

	//"fyne.io/fyne/theme"
	"fyne.io/fyne/widget"
)

func main() {
	app := app.New() //app 선언
	//app.Settings().SetTheme(theme.LightTheme()) //밝은 테마 설정

	w := app.NewWindow("Hello") //window 선언
	entry := widget.NewEntry()
	entry.SetPlaceHolder("database@databaseservr.com:5000/orcl")

	w.SetContent(
		widget.NewVBox(
			widget.NewLabel("Databas Address"), //레이블
			widget.NewHBox(
				entry, //엔트리 (문자열 입력)
				widget.NewButton("Go", func() { //종료버튼
					app.Quit()
				}),
			),
			makeTable( //makeTable함수를 사용하여 테이블 선언 및 변수 입력
				[]string{"Foo", "Bar", "Baz", "My_a", "My_b", "My_c"}, //칼럼(헤더)
				[][]string{{"1", "2", "3"}, {"4", "5", "6"}},          //데이터
			),
		),
	)
	w.Resize(fyne.NewSize(600, 600))
	w.ShowAndRun()
}

func makeTable(headings []string, rows [][]string) *widget.Box {

	columns := rowsToColumns(headings, rows)

	objects := make([]fyne.CanvasObject, len(columns))
	for k, col := range columns {
		box := widget.NewVBox(widget.NewLabelWithStyle(headings[k], fyne.TextAlignLeading, fyne.TextStyle{Bold: true}))
		for _, val := range col {
			box.Append(widget.NewLabel(val))
		}
		objects[k] = box
	}
	return widget.NewVBox(
		fyne.NewContainerWithLayout(layout.NewGridLayout(len(columns)), objects...),
	)
}

func rowsToColumns(headings []string, rows [][]string) [][]string {
	columns := make([][]string, len(headings))
	for _, row := range rows {
		for colK := range row {
			columns[colK] = append(columns[colK], row[colK])
		}
	}
	return columns
}

 

결과는 아래와 같이...

 

 

다음엔 쫌더 이쁘게 만들어봅시당...ㅋㅋㅋ

그럼 이만~~~

 

반응형
반응형

Go언어로 GUI를 만들려고 하니 이것저것 다른 GUI Toolkit을 만져보게 되네요.

오늘은 fyne라는 toolkit을 설치해볼까 합니다. 설치 방법은 비교적 간단한데요. 아래와 같이 입력하면 설치가 됩니다.

(기본적으로 MSYS2 가 설치되어있어야 합니다.)

go get fyne.io/fyne

 

Hello world부터 띄워보겠습니다.

// fyne_hello.go
package main

import (
	"fyne.io/fyne/app"
	"fyne.io/fyne/widget"
)

func main() {
	a := app.New()

	w := a.NewWindow("Hello")
	w.SetContent(widget.NewVBox(
		widget.NewLabel("Hello Fyne!"),
		widget.NewButton("Quit", func() { 
			a.Quit() 
		}),
	))

	w.ShowAndRun()
}

 

내용은 아직 잘 모르지만 아래 그림처럼 잘 뜨네요..

 

 

 

 테마가 특이하단 생각이듭니다. 윈도우 프로그래밍 할때 쓰던C# 이나, JAVA 같은거랑은 완전 다른 느낌이네요. 나름 쉽게접근할 수 있어서 한번 몇가지 더 시도해 봐야겠습니다.

 

(ps) 우분투에서 설치하면서 Fyne 작동 시 아래와 같은 오류가 뜰 때에는...

# fyne.io/fyne/v2/vendor/github.com/go-gl/glfw/v3.3/glfw
/usr/bin/ld: cannot find -lXxf86vm
collect2: error: ld returned 1 exit status

 

추가로 라이브러리를 하나 더 설치해줍니다.

sudo apt-get install libgl1-mesa-dev xorg-dev

 

 

 

반응형

'Programming > Golang' 카테고리의 다른 글

go언어 fyne layout 예제  (4) 2020.04.07
go언어 fyne table만들기  (0) 2020.04.05
andlabs/ui Table예제 코드  (4) 2020.03.30
windows에 go언어 설치하기  (2) 2020.03.29
Glade를 활용한 go언어 gui프로그래밍  (0) 2020.03.26
반응형

Golang으로 테이블을 구현할만한 GUI 라이브러리를 찾고 있는 중, andlabs/ui에서 예제를 발견하여 소스 코드를 올려봅니다. 분석도 좀 필요한데..아직은 그냥 몇몇 부분만 단순화 해놓은 상태입니다.

// tabletest.go
package main

import (
	"fmt"

	"github.com/andlabs/ui"
	_ "github.com/andlabs/ui/winmanifest"
)

type modelHandler struct {
	row9Text    string
	yellowRow   int
	checkStates [3]int
}

func (mh *modelHandler) ColumnTypes(m *ui.TableModel) []ui.TableValue {
	return []ui.TableValue{
		ui.TableString(""), // column 0 text
		ui.TableString(""), // column 1 text
		ui.TableString(""), // column 2 text
	}
}

func (mh *modelHandler) NumRows(m *ui.TableModel) int {
	return 3
}

func (mh *modelHandler) CellValue(m *ui.TableModel, row, column int) ui.TableValue {

	fmt.Printf("%d %d\n", row, column)
	return ui.TableString(row_data[row][column]) //테이블 내부에서 모든 행/열에 대해 자동 수행됨.
												 //String으로 선언된 배열 값을 행/렬 값을 인덱스로 받아들
}

func (mh *modelHandler) SetCellValue(m *ui.TableModel, row, column int, value ui.TableValue) {
	mh.row9Text = string(value.(ui.TableString))
}

func newModelHandler() *modelHandler {
	m := new(modelHandler)
	m.row9Text = "You can edit this one"
	m.yellowRow = -1
	return m
}

//불러올 데이터를 전역변수로 정의
var row_data = [3][3]string{
	{"a", "b", "c"},
	{"f", "e", "d"},
	{"g", "h", "i"},
}

func setupUI() {
	mainwin := ui.NewWindow("libui Control Gallery", 640, 480, true)
	mainwin.OnClosing(func(*ui.Window) bool {
		ui.Quit()
		return true
	})
	ui.OnShouldQuit(func() bool {
		mainwin.Destroy()
		return true
	})

	mh := newModelHandler()
	model := ui.NewTableModel(mh)
	table := ui.NewTable(&ui.TableParams{
		Model:                         model,
		RowBackgroundColorModelColumn: -1, // "RowBackgroundColorModelColumn"는 테이블의 전체 행에
		//사용되는 배경색을 사용하는 열 번호를 정의.
		//모든 행에 기본 배경색을 사용하려면 -1.
		//CellValue가 NULL이면 기본 배경색.
	})

	table.AppendTextColumn("Column 1", 0, ui.TableModelColumnNeverEditable, nil)
	table.AppendTextColumn("Column 2", 1, ui.TableModelColumnNeverEditable, nil)
	table.AppendTextColumn("Editable", 2, ui.TableModelColumnAlwaysEditable, nil)

	input := ui.NewEntry()
	button := ui.NewButton("Greet")
	box := ui.NewVerticalBox()
	box.Append(ui.NewLabel("Enter your name:"), false)
	box.Append(input, false)
	box.Append(button, false)
	box.Append(table, true)

	mainwin.SetChild(box)
	mainwin.SetMargined(true)

	mainwin.Show()
}

func main() {
	ui.Main(setupUI)
}

 

결과물은 아래처럼 나오는데.....적당히 수정해서 Oracle하고 연동해서 사용할 계획입니다.

(결과물 나오는대로 포스팅 업데이트 예정)

2020.04.01수정:

  외부 데이터를 받아들여 표시하기 위해 이것 저것 만져보았습니다. 우선 "RowBackgroundColorModelColumn" 녀석이 있는데, 이게 -1로 되어있어야 했습니다. 배경색을 정의하는 인자 같은데, 이걸 다른 값을 설정하면....예를 들어 3을 설정하면 칼럼 값이 3+3=6이 됩니다. 화면에 나타나지 않아서 찾느라 고생했습니다ㅠㅠ. 덕분에 CellValue 함수 정의하는데 고생을 좀 했습니다.

  

반응형
반응형

순서가 뒤바뀐 감이 없진 않지만... 저도 배우는 입장이라, 뒤늦게 알게된 것을 바로바로 포스팅합니다.

오늘은 Go언어 windows환경에 제대로 설치하기입니다. 순서는

1. 설치

2. 환경변수 설정

3. Hello World 출력

이 되겠습니다.

 

1. GO 설치

Go 공식 웹사이트인 http://golang.org/dl 에서 본인의 OS에 맞는 Go를 다운로드하여 설치합니다. Go는 Windows, Linux, Mac OS X 에서 사용할 수 있습니다.

 

 

Windows에 Go를 설치하기 위해서는 MSI 파일을 다운받아 실행하면 됩니다.

Go는 디폴트로 C:\go 폴더에 설치되며, MSI가 C:\go\bin을 PATH 환경변수가 자동으로 추가됩니다.

 

2. 환경변수 설정

Go는 2개의 중요한 환경변수(GOROOT와 GOPATH)를 사용합니다..
 

GOROOT:

 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 출력하는 방법에 대해 간단히 알아보았습니다.

 

-끝-

반응형
반응형

 

이번엔 gtk toolkit 전용 GUI Designer인 Glade를 이용하여 Go언어에서 활용해보도록 하겠습니다.

 

우선 Glade를 설치해야 합니다. linux에서는 비교적 쉽게 찾아서 설치 가능한데요.. 윈도우에서는 조금 설치가 쉽지 않습니다. Mingw를 설치하고 아래의 명령으로 설치를 진행해줍니다.

pacman -S mingw-w64-x86_64-glade

빠른 실행을 위해서는 sourceforge 사이트에서 예전버전을 다운받는 것도 괜찮아보입니다.

 

 

다음으로는 Glade에서 UI를 적당히 디자인 해줍니다. (glade예제파일)

생각해보니...그냥 적당히는 안될 것 같네요.

 

 

1. 최상위 - > GtkWindow 를 선택해주세요. 그리고 아이디를 main_window,  사이즈를 440, 250 으로 설정합니다.

2. 컨테이너-> GtkHeaderBar를 선택해주세요. 아이디를 headerbar, 간격 7, 항목 3으로 설정해주세요

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!!")
}


모두들 성공하시길 빌겠습니다.
그럼 이만~~

 

반응형

+ Recent posts