반응형

 

package main

import (
	"database/sql"
	"fmt"	

	_ "github.com/go-sql-driver/mysql"
)

func checkError(err error) {
    if err != nil {
        panic(err)
    }
}

func main() {

	var name, email, phone string

	db, err := sql.Open("mysql", "root:1234@tcp(127.0.0.1:3306)/testdb")
	checkError(err)
	defer db.Close()
    
	fmt.Println("connect success")

	rows, err := db.Query("SELECT name, email, phone FROM members where id=?", 6)
	checkError(err)
	defer rows.Close()

	for rows.Next() {
		err := rows.Scan(&name, &email, &phone)
		checkError(err)
		fmt.Println("rows", name, email, phone)
	}
}
반응형
반응형

 

보통 프로그램이 커질수록 파일을 기능별로 분리 관리를 하죠. Go 언어에서도 파일 분리/관리 방법이 있습니다만 오늘은 이것 때문에 삽질을 좀 많이 했네요. 역시 기초부터 제대로 공부하고 써먹어야한다는 생각을 절실히 체감하는 오늘입니다.

 

1. 같은 package 안에서는 함수, 메서드 등의 이름 첫글자가 소문자여도 사용이 가능합니다. (non-public)

폴더 구분없이 파일만 구분해서 사용하고 싶을 경우, 같은 패키지(현재 main)으로 하고, 함수이름 첫글자 소문자(my_plus)일 경우 문제없이 인식 가능합니다. (import 같은 기능 필요 없음)

 

2. 다른 패키지로 관리할 때, 즉 폴더별로 관리할 경우 주의해야 할 사항이 몇가지 있어서 정리를 할까 합니다.

   1) 함수, 메서드 등의 이름 첫글자가 대문자이어야 사용 가능합니다.

   2) 다음으로는 지금까지 제가 Golang을 잘못 설정해서 쓰고 있던 것일 수도 있는데, 프로그램 작성을 go_pkg/src 하위에 작성해야만 import 시 인식이 가능합니다. 다른 방법(기타 툴의 사용이라던가..)이 있는지는 잘 모르겠으나, 현재까지는 go_pkg/src가 아닌 외부 폴더에서 작업할 경우 인식이 안되는 것으로 확인됩니다.

 

이상 간단판 패키지 관리 삽질기였습니다^^;;

 

~~끝~~

반응형
반응형

지금까지 만든 시계앱을 시스템 트레이로 만들어보도록 하겠습니다. 만들고 나면 이런 모양의 시스템 트레이가 하나 생성되게 됩니다. (Windows 기준). 모든 소스는 아래 공개해 놓았으며, 이전포스트는 굳이 참고하지 않아도 문제없습니다.

 

 

이미지는 다른 시계 예제에서 다운받아 온 것인데, 나름 귀엽네요. 그럼 이제 본격적으로 들어가보도록 하겠습니다.

 

1. 파일 정리

우선 지금까지는 main.go와 main.html에서 각각 기능과 뷰를 담당했는데, 앞으로는 시스템 트레이 프로그램이 메인이 되고, 거기서 clock 프로그램을 불러오는 방식으로 수정하도록 하겠습니다.


       main.go     : 시스템 트레이 실행 (시계 프로그램 불러오기)

           ㄴ clock.go   : 시계 프로그램 실행 (윈도우 생성 / 뷰 불러오기, 기존 main.go)

                  ㄴ clock.html  : 시계 화면구성 및 동작 (기존 main.html)

        assets - clock.ico  : 시스템 트레이용 시계 이미지


구조가 단순하므로 패키지 구성 없이 그냥 같은 폴더 내 main 패키지로 진행하겠습니다. 이미지는 별도로하구요. 트레이 아이콘으로 쓸 이미지를 공유드리니, 프로젝트 폴더 내 assets라는 폴더를 하나 더 만들어 그 안에 넣어주세요. (아래 코드에 따라...)

 

clock.ico
0.19MB

 

 

2. 라이브러리 설치

시스템 트레이 제작을 위해서는 시스템 트레이를 위한 라이브러리를 설치해야 하는데, 아주 이지한 Golang Library가 존재합니다. getlantern/systray라는 라이브러리입니다. 아래 명령으로 설치해줍니다.

go get github.com/getlantern/systray

 

3. main.go , 시스템 트레이 실행파일

시스템 트레이 프로그램을 아래와 같이 작성합니다. 라이브러리를 임포트 하고, main함수에서 onReady와 onExit함수를 불러옵니다. onReady를 불러와서 기본적인 세팅을 하고, 고루틴으로 clock() 실행, quit메뉴 선택시 종료하는 함수를 실행합니다. 종료시 실행해야 할 일은 없으므로 onExit는 비워둡니다. 

package main

import (
	"fmt"
	"io/ioutil"
	"github.com/getlantern/systray" // window tray 관련 라이브러리
)

// Preaprare Program for execution ///
func main() {

	systray.Run(onReady, onExit)

}

func onReady() {
	systray.SetIcon(getIcon("assets/clock.ico"))			// Icon 불러오기
	systray.SetTitle("I'm alive!")
	systray.SetTooltip("Look at me, I'm a tooltip!")		// 마우스 오버 시 툴팁 표시

	mQuit := systray.AddMenuItem("Quit", "Quitsthis app")	// 종료 메뉴 추가

	go func() {
		for {
			select {
			case <-mQuit.ClickedCh:
				systray.Quit()
				return
			}
		}
	}()

	go func() {
		clock()
	}()

}

func onExit() {
	// Cleaning stuff here.
}

func getIcon(s string) []byte {
	b, err := ioutil.ReadFile(s)
	if err != nil {
		fmt.Print(err)
	}
	return b
}

4. clock.go 프로그램 작성

지난 post에서 작성한 main.go를 수정하여 작성하도록 하겠습니다. 자세한 변경은 아래 코드를 보시고, 중요 변경사항에 대해서만 말씀드리자면...

 

  • clock함수 작성: 기존에 main으로 되어있는 부분을 clock으로 수정합니다.
  • 작업표시줄에서 제거: window생성 부분에서(line30~35) sciter.SW_TOOL 을 추가합니다. 이 부분은 시스템 트레이로 실행되는 프로그램이 작업표시줄에도 표시되는 것을 막아줍니다.
  • 앱 위치 수정: 저는 시계가 화면 우상단에 위치시키겠습니다. 이를 위해 화면 사이즈를 시스템으로부터 얻어와야 하는데, 이것이 win.GetSystemMetrics(win.SM_CXSCREEN), win.GetSystemMetrics(win.SM_CySCREEN)입니다. 이를 잘 활용하여 앱의 크기와 위치를 재설정해줍니다. 
package main

import (
	"fmt"

	"github.com/lxn/win"

	sciter "github.com/sciter-sdk/go-sciter"
	"github.com/sciter-sdk/go-sciter/window"
)

// Specifying  havily used
// Singltons to make them
// package wide available
var root *sciter.Element
var rootSelectorErr error
var w *window.Window
var windowErr error

// Preapare Scitre For Execution ///
func init() {

	// initlzigin window for downloaer
	// app with appropriate properties
	cw := 200                                        //clock width
	ch := int(win.GetSystemMetrics(win.SM_CYSCREEN)) // clock height
	x_pos := int(win.GetSystemMetrics(win.SM_CXSCREEN)) - cw
	y_pos := 10
	rect := sciter.NewRect(y_pos, x_pos, cw, ch)
	w, windowErr = window.New(sciter.SW_TITLEBAR|
		sciter.SW_CONTROLS|
		sciter.SW_MAIN|
		sciter.SW_TOOL| //tool모드로, 작업표시줄에 아이콘 표시 안함.
		sciter.SW_GLASSY,
		rect)

	if windowErr != nil {
		fmt.Println("Can not create new window")
		return
	}
	// Loading main html file for app
	htloadErr := w.LoadFile("./clock.html")
	if htloadErr != nil {
		fmt.Println("Can not load html in the screen", htloadErr.Error())
		return
	}

	// Initializng  Selector at global level as we  are going to need
	// it mostly and as it is
	root, rootSelectorErr = w.GetRootElement()
	if rootSelectorErr != nil {
		fmt.Println("Can not select root element")
		return
	}

	// Set title of the appliaction window
	w.SetTitle("Simple")

}

// Preaprare Program for execution ///
func clock() {
	w.Show()
	w.Run()
}

5. clock.html 프로그램 작성

화면을 구성하는 clock.html파일을 아래와 같이 작성해줍니다. 지난 포스트의 main.html로부터 변경된 사항은

  • html태그에 window-resizable="true" 속성을 추가하여 크기조절이 가능하도록 했습니다.(....만 transparent 속성때문에 프레임이 선택되지 않습니다. transparent 이 외에 extended/solid 등 다른 옵션의 경우 가능하니 확인해보시기 바랍니다. sciter.com/html-window/
  • view.windowTopmost=true 속성을 스크립트 부분에 추가하여 시계가 항상 위에 표시되도록 합니다.
  • CSS에서 fixed클래스를 선언해서 해당 앱이 항상 다른 앱보다 뒤에서 표시되도록(바탕화면 바로 다음에..) 하려고 하였으나, 위 속성때문에 제대로 작동하진 않습니다.
  • 색상과 선의 두께 등도 기호에 맞게 조정합니다.
<html window-frame="transparent" window-resizable="true">
  <head>
    <title>Sciter2 clock</title>
    <style>
      html{
        background:transparent;
      }
      div.clock { 
        prototype:Clock; 
        width:*;
        height:*;
        /*border:1px solid black;*/
      }
      h3{
        color: white;
      }
      .fixed { position:fixed; left:0; top:0; right:0; bottom:0; z-index:-1; }
    </style>
    <script type="text/tiscript">

!function(){

  $(span#os).text = System.OS;
  
}();   

view.windowTopmost = true;   //항상 위에 존재

class Clock: Behavior 
{

  function attached() { 
    this.paintContent = this.drawclock; // attaching draw handler to paintContent layer
    this.timer(300,::this.refresh());
    
  }

  function drawclock(gfx)
  {
    
    var (x,y,w,h) = this.box(#rectw);
    var scale = w < h? w / 300.0: h / 300.0;
    var now = new Date();
    gfx.save();
    gfx.translate(w/2.0,h/9.0);
    gfx.scale(scale,scale);    
    gfx.rotate(-Math.PI/2);
    gfx.lineColor(color(0x32,0xA2,0xCF));
    gfx.lineWidth(3);
    gfx.lineCap = Graphics.CAP_ROUND;
       
    // Hour marks
    gfx.save();
    gfx.lineColor(color(0x32,0x5F,0xCF));
    for (var i in 12) {
      gfx.rotate(Math.PI/6);
      gfx.line(100,0,120,0);
    }
    gfx.restore();

    // Minute marks
    gfx.save();
    gfx.lineWidth(5);
    for (var i in 60) {
      if ( i % 5 != 0)
        gfx.line(117,0,120,0);
      gfx.rotate(Math.PI/30);
    }
    gfx.restore();

    var sec = now.second;
    var min = now.minute;
    var hr  = now.hour;
    hr = hr >= 12 ? hr-12 : hr;
  
    // write Hours
    gfx.save();
    gfx.lineColor(color(0x32,0x5F,0xCF));
    gfx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
    gfx.lineWidth(14);
    gfx.line(-20,0,70,0);
    gfx.restore();

    // write Minutes
    gfx.save();
    gfx.lineColor(color(0x32,0x5F,0xCF));
    gfx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
    gfx.lineWidth(10);
    gfx.line(-28,0,100,0);
    gfx.restore();
      
    // Write seconds
    gfx.save();
    gfx.rotate(sec * Math.PI/30);
    gfx.lineColor(color(0xD4,0x32,0));
    gfx.fillColor(color(0xD4,0x32,0));
    gfx.lineWidth(6);
    gfx.line(-30,0,83,0);
    gfx.ellipse(0,0,10);
    
    gfx.noFill();
    gfx.ellipse(95,0,10);
    gfx.restore();
    
    // outline
    gfx.lineWidth(8);
    gfx.lineColor(color(0x32,0xA2,0xCF));
    gfx.ellipse(0,0,142);
    
    gfx.restore();
    
  }  
    
}
 
    </script>
  </head>
<body>
  <div.fixed>
    <h3>Sciter clock using immediate mode drawing on <span #os></span></h3>
    <div class="clock" >
    </div>
  </div>


</body>
</html>

 

라이브러리 설치에 빠진 것이 없고, 위와 같이 구성하고 실행하면 작성한 프로그램이 항상 위에 작동하고, 시스템 트레이에서 실행되고, 작업표시줄에는 나타나지 않는 것을 보실 수 있을겁니다.

 

 

나름 위젯처럼 되었습니다. ㅎㅎㅎㅎㅎ

 

그럼 모두들 건승하십시오.

오늘은 이만~~~

 

 

반응형
반응형

go-sciter를 이용하여 아날로그 시계를 구현해보도록 하겠습니다. go-sciter를 이용한 프로그램은 데이터처리를 위한 .go 파일과 뷰 제어를 위한 .html파일로 구성이 되어있는데요, 오늘은 아날로그 시계 만들기는 html에서 시계의 움직임까지 표현해주고, .go파일에서는 그냥 html을 로딩하는 역할만 하게됩니다.

우선 결과물은 아래와 같이 나옵니다.

 

 

 

그럼, 소스는...

 

1. main.go (기본적인 html 로딩 포맷으로 기존과 동일)

package main

import (
	"fmt"

	sciter "github.com/sciter-sdk/go-sciter"
	"github.com/sciter-sdk/go-sciter/window"
)

// Specifying  havily used
// Singltons to make them
// package wide available
var root *sciter.Element
var rootSelectorErr error
var w *window.Window
var windowErr error

// Preapare Scitre For Execution ///
func init() {

	// initlzigin window for downloaer
	// app with appropriate properties
	rect := sciter.NewRect(0, 100, 200, 350)
	w, windowErr = window.New(sciter.SW_TITLEBAR|
		sciter.SW_CONTROLS|
		sciter.SW_MAIN|
		sciter.SW_GLASSY,
		rect)

	if windowErr != nil {
		fmt.Println("Can not create new window")
		return
	}
	// Loading main html file for app
	htloadErr := w.LoadFile("./main.html")
	if htloadErr != nil {
		fmt.Println("Can not load html in the screen", htloadErr.Error())
		return
	}

	// Initializng  Selector at global level as we  are going to need
	// it mostly and as it is
	root, rootSelectorErr = w.GetRootElement()
	if rootSelectorErr != nil {
		fmt.Println("Can not select root element")
		return
	}

	// Set title of the appliaction window
	w.SetTitle("Simple")

}

// Preaprare Program for execution ///
func main() {

	w.Show()
	w.Run()

}

 

2.main.html

<html>
  <head>
    <title>Sciter2 clock</title>
    <style>
    
      div.clock { 
        prototype:Clock; 
        width:*;
        height:*;
        /*border:1px solid black;*/
      }
    
    </style>
    <script type="text/tiscript">

!function(){

  $(span#os).text = System.OS;

}();   

    
class Clock: Behavior 
{

  function attached() { 
    this.paintContent = this.drawclock; // attaching draw handler to paintContent layer
    this.timer(300,::this.refresh());
  }

  function drawclock(gfx)
  {
    var (x,y,w,h) = this.box(#rectw);
    var scale = w < h? w / 300.0: h / 300.0;
    var now = new Date();
    gfx.save();
    gfx.translate(w/2.0,h/2.0);
    gfx.scale(scale,scale);    
    gfx.rotate(-Math.PI/2);
    gfx.lineColor(color(0,0,0));
    gfx.lineWidth(8);
    gfx.lineCap = Graphics.CAP_ROUND;
       
    // Hour marks
    gfx.save();
    gfx.lineColor(color(0x32,0x5F,0xA2));
    for (var i in 12) {
      gfx.rotate(Math.PI/6);
      gfx.line(100,0,120,0);
    }
    gfx.restore();

    // Minute marks
    gfx.save();
    gfx.lineWidth(5);
    for (var i in 60) {
      if ( i % 5 != 0)
        gfx.line(117,0,120,0);
      gfx.rotate(Math.PI/30);
    }
    gfx.restore();

    var sec = now.second;
    var min = now.minute;
    var hr  = now.hour;
    hr = hr >= 12 ? hr-12 : hr;
  
    // write Hours
    gfx.save();
    gfx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
    gfx.lineWidth(14);
    gfx.line(-20,0,70,0);
    gfx.restore();

    // write Minutes
    gfx.save();
    gfx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
    gfx.lineWidth(10);
    gfx.line(-28,0,100,0);
    gfx.restore();
      
    // Write seconds
    gfx.save();
    gfx.rotate(sec * Math.PI/30);
    gfx.lineColor(color(0xD4,0,0));
    gfx.fillColor(color(0xD4,0,0));
    gfx.lineWidth(6);
    gfx.line(-30,0,83,0);
    gfx.ellipse(0,0,10);
    
    gfx.noFill();
    gfx.ellipse(95,0,10);
    gfx.restore();
    
    // outline
    gfx.lineWidth(14);
    gfx.lineColor(color(0x32,0x5F,0xA2));
    gfx.ellipse(0,0,142);
    
    gfx.restore();
  }    
}
    
    </script>
  </head>
<body>
  <h2>Sciter clock using immediate mode drawing on <span #os></span></h2>
  <div class="clock" ></div>

</body>
</html>

이전 포스팅에서 말씀드렸다시피 TIScript라는 걸 사용해서 시계를 구현하는데요, 자바스크립트랑 비슷한 것 같긴한데 잘 모르겠는게 좀 있네요. 사실 자바스크립트도 잘 알지는 못하니... 좀 더 알아봐야겠습니다.

 

오늘은 이만~

반응형
반응형

간단히 날짜 표시하는 앱을 구현해보겠습니다.

 

1.main.go

package main

import (
	"fmt"
	"time"

	sciter "github.com/sciter-sdk/go-sciter"
	"github.com/sciter-sdk/go-sciter/window"
)

// Specifying  havily used
// Singltons to make them
// package wide available
var root *sciter.Element
var rootSelectorErr error
var w *window.Window
var windowErr error

// Preapare Scitre For Execution ///
func init() {

	// initlzigin window for downloaer
	// app with appropriate properties
	rect := sciter.NewRect(0, 100, 200, 350)
	w, windowErr = window.New(sciter.SW_TITLEBAR|
		sciter.SW_CONTROLS|
		sciter.SW_MAIN|
		sciter.SW_GLASSY,
		rect)

	if windowErr != nil {
		fmt.Println("Can not create new window")
		return
	}
	// Loading main html file for app
	htloadErr := w.LoadFile("./main.html")
	if htloadErr != nil {
		fmt.Println("Can not load html in the screen", htloadErr.Error())
		return
	}

	// Initializng  Selector at global level as we  are going to need
	// it mostly and as it is
	root, rootSelectorErr = w.GetRootElement()
	if rootSelectorErr != nil {
		fmt.Println("Can not select root element")
		return
	}

	// Set title of the appliaction window
	w.SetTitle("Simple")

}

// Preaprare Program for execution ///
func main() {

	t := time.Now().Format("2006-01-02 15:04:05")
	date_now, _ := root.SelectById("date")
	date_now.SetText(t)
	//date_now.SetText("hello")

	w.Show()
	w.Run()

}

 

2.main.html

<html window-frame="default" window-blurbehind>
<head>
    <head>
        <title>Simple Calc</title> 
        <meta name="viewport" content="width=device-width, initial-scale=1.0">  
        <style>
          html{
            background: transparent;
          }
          #date{
            color: white;
            text-align: left;
            font-size:20px;
          }
        </style>
    </head>
</head>
<body>
  <label id="date">date</label>
</body>
</html>

 

결과는 아래와 같이~~

 

투명하게 처리된 프로그램. 보이시나요?

 

 

Golang과 HTML로 GUI 실행파일 만든다는게 꽤 재미있네요. 자주 활용할 수 있을 것 같습니다.

오늘은 이만~~

반응형
반응형

 

이번엔 인터넷에서 go-sciter를 이용한 간단한 계산기 프로그램을 우연히 발견하여 이를 투명하게 개조해보았습니다.

참고로 이번 프로그램에는 컬러값을 설정할 때 "github.com/fatih/color" 라는 패키지가 필요합니다.

go get "github.com/fatih/color"

를 수행해서 추가로 필요한 패키지를 설치해 줍니다.

 

그리고 아래 코드를 작성해줍시다.

 

1. main.go

package main

import (
	"fmt"

	"github.com/fatih/color"
	sciter "github.com/sciter-sdk/go-sciter"
	"github.com/sciter-sdk/go-sciter/window"
)

// Specifying  havily used
// Singltons to make them
// package wide available
var root *sciter.Element
var rootSelectorErr error
var w *window.Window
var windowErr error

// Preapare Scitre For Execution ///
func init() {

	// initlzigin window for downloaer
	// app with appropriate properties
	rect := sciter.NewRect(0, 100, 200, 350)
	w, windowErr = window.New(sciter.SW_TITLEBAR|
		sciter.SW_CONTROLS|
		sciter.SW_MAIN|
		sciter.SW_GLASSY,
		rect)

	if windowErr != nil {
		fmt.Println("Can not create new window")
		return
	}
	// Loading main html file for app
	htloadErr := w.LoadFile("./main.html")
	if htloadErr != nil {
		fmt.Println("Can not load html in the screen", htloadErr.Error())
		return
	}

	// Initializng  Selector at global level as we  are going to need
	// it mostly and as it is
	root, rootSelectorErr = w.GetRootElement()
	if rootSelectorErr != nil {
		fmt.Println("Can not select root element")
		return
	}

	// Set title of the appliaction window
	w.SetTitle("Simple Calc")

}

// Preaprare Program for execution ///
func main() {

	addbutton, _ := root.SelectById("add")

	out1, errout1 := root.SelectById("output1")
	if errout1 != nil {
		color.Red("failed to bound output 1 ", errout1.Error())
	}
	addbutton.OnClick(func() {
		output := add()
		out1.SetText(fmt.Sprint(output))
	})

	w.Show()
	w.Run()

}

//////////////////////////////////////////////////
/// Function of calc                           ///
//////////////////////////////////////////////////

func add() int {

	// Refreshing and fetching inputs()
	in1, errin1 := root.SelectById("input1")
	if errin1 != nil {
		color.Red("failed to bound input 1 ", errin1.Error())
	}
	in2, errin2 := root.SelectById("input2")
	if errin2 != nil {
		color.Red("failed to bound input 2 ", errin2.Error())
	}

	in1val, errv1 := in1.GetValue()
	color.Green(in1val.String())

	if errv1 != nil {
		color.Red(errv1.Error())
	}
	in2val, errv2 := in2.GetValue()
	if errv2 != nil {
		color.Red(errv2.Error())
	}
	color.Green(in2val.String())

	return in1val.Int() + in2val.Int()
}

2.main.html

<html window-frame="transparent" window-blurbehind>
<head>
    <head>
        <title>Simple Calc</title> 
        <meta name="viewport" content="width=device-width, initial-scale=1.0">  
        <style>
          html{
            background: transparent;
          }
          div{
            color: white;
            text-align: right;
          }
        </style>
    </head>
</head>
<body>
    <div>
      <label for="">No1</label>
      <input type="number" style="width: 100px; margin: 0 auto;" id="input1" >
      <br>
      <label for="">No2</label>
      <input type="number" style="width: 100px; margin: 0 auto;" id="input2" >
      <br>
      <input type="button" style="width: 50px; margin: 0 auto;" value="Add ( + )" id="add"> 
      <hr>
      <input type="number" style="width: 100px; margin: 0 auto;" id="output1" disabled>
    </div>

</body>
</html>

 

실행결과는 ..

 

 

 

투명하게 나오니까 역시 이쁘네요.

오늘은 여기까지~~

 

반응형
반응형

윈도우에서 위젯같은 프로그램을 만들려고 프레임/배경/타이틀바 등을 투명하게 할 수 있는 라이브러리를 찾다가 go-sciter라는 것을 찾았습니다. (다른 라이브러리로 투명 구현하려고 한참동안 헤메었네요.ㅜㅜ)

 

sciter는..

화면 구성은HTML, CSS를 쓰고 tiscript라는 스크립트로 뷰를 제어하고, 실행 부분에서는 golang, python, rust, c# 등 다양한 언어로 구축할 수 있습니다. 물론 무료이구요. (실행 파일 내부에 sciter.dll을 포함시키기 위해서는 돈을 내야 한다고 합니다. 배포시 sciter.dll을 한 폴더에 같이 배포하면 문제는 없겠네요.)

 

설치는..

1.SDK 설치: sciter.com/download/ 에서 SDK를 다운받아 압축을 해제하고, \sciter\bin.win\ 디렉토리의 본인 os에 맞는 sciter.dll 파일을 C:\windows\system32 폴더로 복사해 넣어줍니다. 

 

 

 

 

 

 

2. Go-binding 라이브러리 설치

go get -x github.com/sciter-sdk/go-sciter

 

설치가 완료되었으니, 간단히 투명 화면 구성하는 방법에 대해 알아보겠습니다.

 

main.go

package main

import (
	"fmt"

	"github.com/sciter-sdk/go-sciter"
	"github.com/sciter-sdk/go-sciter/window"
)

func main() {

	rect := sciter.NewRect(100, 100, 600, 400)
	window, windowCreationErr := window.New(sciter.SW_MAIN|sciter.SW_TITLEBAR|sciter.SW_ENABLE_DEBUG, rect)

	if windowCreationErr != nil {
		fmt.Errorf("Could not create sciter window : %s",
			windowCreationErr.Error())
		return
	}

	uiFileLoadErr := window.LoadFile("./main.html")
	if uiFileLoadErr != nil {
		fmt.Errorf("Could not load ui file : %s",
			uiFileLoadErr.Error())
	}

	window.SetTitle("Hello")
	window.Show()
	window.Run()

}

 

main.html

<html window-frame="transparent" window-blurbehind>
    <head>
        <!--<title>Would be set from goLang code</title>-->
        <style>
          html{
            background: transparent;
          }
            h1{
                text-align: center
                
            }
        </style>         
          
    </head>
    <body>
        <h1>Hello Sciter</h1>     
    </body>
</html>

 

 

 

 

 

 

 

 

정말 간단하게 투명 UI가 생성되었네요. 이제 이걸 활용해서 뭔가 좀 더 만들어봐야겠습니다.

 

- 끝 -

반응형
반응형

아직 웹앱 / 웹서버 / API 이런 개념이 없긴 하지만, 회사의 웹 환경은 뭔가 기초가 되는 웹서버가 있고 앱들이 그 위에서 돌아가고 있기 때문에, 오늘은 go 웹앱과 nginx를 연동하는 방법에 대해 알아볼까 합니다.

 

1. go 앱 작성

아래와 같이 간단한 코드를 작성하고 빌드해서 exe파일을 만들어 줍니다.

// main.go
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello World")
	})

	http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) {
		name := r.URL.Path[len("/greet/"):]
		fmt.Fprintf(w, "Hello %s\n", name)
	})

	http.ListenAndServe(":9990", nil)

}

그리고 exe파일을 실행해줍니다. 브라우저로 포트 9990에 접속하면 아래와 같이 나옵니다.

간단하게 웹앱이 만들어졌습니다.

 

2. NginX 설치

저는 NginX 사이트를 들어갔었는데, 다운받는 경로를 찾기가 힘들더군요. 다운로드로 검색해서 들어갔습니다. 참고로 이곳 링크를 따라가시면 됩니다. 압축 파일이 다운받아지는데, 설치하는 프로그램이 아니고 곧바로 실행가능한 파일입니다. 따라서 "C:\" 나 "C:\Program Files\" 등 적당한 곳에 옮겨줍니다.

 

 

3. NginX 실행

저는 C:\ 바로 밑에 설치했는데요, 해당 폴더의 nginx.exe 파일을 실행하시면 nginx 서버가 실행됩니다.

그리고 브라우저를 통해서 localhost에 접속하면

nginx에 온걸 환영한다고...이렇게 나옵니다.

 

4. nginx.conf 파일 수정 및 재실행

nginx 설치 폴더의 conf폴더 내 nginx.conf 파일을 수정하여 server 부분에 아래의 코드만 남기고 제거합니다. 이렇게 해서 localhost:80으로 접근하면 자동으로 localhost:9990으로 연결되도록 합니다.

 server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            proxy_pass http://127.0.0.1:9990;  # 변경된 부분
            #root   html;
            #index  index.html index.htm;
        }

        #error_page  404              /404.html;

그리고 커맨드창에서(path 추가 안했다면, 설치폴더 경로로 이동) nginx -s reload 명령으로 재시작합니다.

 

5. localhost 확인

이번엔 localhost:80으로 다시 접속합니다. 그러면 go로 만든 앱의 결과물이 나타나는 것을 확인할 수 있습니다.

6. 기타

아래 ubuntu환경에서 go 웹앱을 nginx와 연동하는 방법에 대한 포스팅을 참조했습니다만, 그 중 systemd unit file 작성하는 부분을 누락했습니다. 왜하는지도 모르겠고, 어떻게 하는지도 모르겠네요. 아시는 분께서는 댓글 부탁드려요. 사실 이것 뿐만 아니라, 애초에 그냥 go 웹앱만 여러개 만들어서 돌리면 되는것 아닌가요? 굳이 apache나 nginx같은 웹서버랑 연동을 해야하는 걸까요? 취미로 혼자 공부하다보니 힘드네요. 누가 좀 알려주세요~~^^;;;;;

 

참고사이트

https://www.digitalocean.com/community/tutorials/how-to-deploy-a-go-web-application-using-nginx-on-ubuntu-18-04

반응형

+ Recent posts