반응형

1. 장애물 신 추가

웹 설명서를 그대로 번역하면 적 신으로 나오는데, 마음에 들지않아 장애물이라고 표현하겠습니다. 장애물에 해당하는 몹(Mob)들은 화면 가장자리 4군데에서 랜덤하게 생성되고, 직선방향으로 움직이도록 할 계획입니다. 우선 Player에서 했던 것과 마찬가지로 새 신(scene)을 추가하고 Rigidbody2D 노드를 추가합니다. 그리고 이름은 Mob으로 바꿔주겠습니다.

 

그리고 아래의 버튼(잠금열쇠 옆에있는거..)을 클릭하여, 추가되는 자식노드만 따로따로 선택되지 않도록 해 줍니다.

 

이어서, Gravity Scale을 0으로 해 줍니다. 즉, 중력에 영향을 받지 않게 해줍니다. 이 값이 0이 아닐경우, Mob들은 중력의 영향을 받도록 계산되고, 화면 아래로 떨어지게됩니다. 조금 아래로 내려와 CollisionObject2D 카테고리의 Mask에 1을 체크 해제합니다. 이렇게 하면 Mob들끼리 서로 충돌하는 상황은 발생하지 않습니다.


2. 애니메이션 추가

Player 씬에서 수행했던 것과 마찬가지로, AnimatedSprite를 Node 하위에 추가하고,

인스펙터에서 Frames > 새 SpriteFrame 을 추가하여 한번 더 클릭하여 Animation 창을 띄워줍니다.


애니메이션은 fly, swim, walk의 세가지가 있으며, 각각의 케이스에 대해 2개의 이미지가 있습니다. 기존에 했던 것과 동일한 방식으로 이미지를 추가해줍니다. 아울러 재생속도를 초당 3프레임으로 변경해줍니다.

또한 Mob들의 사이즈를 조절하기 위해 AnimatedSprite 노드를 한번 더 클릭하고, 인스펙터 창의 Playing 속성을 "사용", Scale속성을 x, y 방향으로 각각 0.75씩 입력해줍니다.


3. 충돌 노드(CollisionShape2D) 추가

Player 씬과 마찬가지로 충돌 감지노드를 추가해야합니다. Mob 노드를 선택한 상태에서 새 노드를 추가해줍니다.

이번엔, CapsuleShape이면서도 Mob의 형상에 맞게 90도 회전하여 잘 커버되도록 조정해줍니다.

 

4. Mob.gd 스크립트

스크립트에서는 Mob이 생성될때 랜덤 형상, 랜덤 속도, 화면 밖으로 나갔을 때 삭제 처리를 할 예정입니다.

extends RigidBody2D

export var min_speed = 150  # Minimum speed range.
export var max_speed = 250  # Maximum speed range.

# Called when the node enters the scene tree for the first time.
func _ready():
	var mob_types = $AnimatedSprite.frames.get_animation_names()
	$AnimatedSprite.animation = mob_types[randi() % mob_types.size()]

func _on_VisibilityNotifier2D_screen_exited():
    queue_free()
	
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#	pass

mob_types는 애니메이션에서 설정한 3가지의 몹 이름을 배열로 갖게 됩니다. 그리고 실제 보여줄 에니메이션에서는 이 중 랜덤하게 골라서 설정하게 됩니다.

화면에서 해당 객체(생성된 Mob)가 나가게 되면 자체 제거(메모리 회수)를 하게되는데, 이때 사용하는 함수가 queue_free()입니다.

 

- Mob Scene 끝 -

 
반응형
반응형

1. 프로젝트 설정

프로젝트 > 프로젝트 설정을 클릭한 후, display > window메뉴로 가서 width480, height720으로 설정해줍니다.

그리고, Stretch로 내려가서 Mode: 2d, Aspect: keep으로 변경해줍니다.

2. Resource 폴더 추가

dodge_assets 파일은 링크 에서 다운받을 수 있습니다. Godot엔진 홈페이지의 Your First Game 챕터에서 찾을 수도 있습니다. 압축을 풀어서 생성된 프로젝트 폴더에 집어넣으면 아래와 같이 자동으로 프로젝트에 폴더가 추가됩니다.

3. Player 씬 추가

왼쪽 씬 탐색기에서 다른노드 > Area2D검색 >Area2D 를 선택합니다.

노드를 더블클릭하여 이름을 Player로 바꿔줍니다. 그리고 Player.tscn으로 저장합니다.

 

그리고 자물쇠 아이콘 옆의 아이콘을 클릭해줍니다. 추후 자식 노드들이 추가될텐데, 자식노드들만 따로 선택되는 것을 방지해주는 기능이라고 합니다.

Player 노드 하위에 AnimatedSprite를 검색하여 추가합니다.

AnimatedSprite노드가 추가되면 우측의 Frames속성이 아직 [비었음] 상태입니다. [비었음]을 클릭하여 새 SpriteFrames를 선택합니다.

그리고 선택된 SpriteFrame를 한번 더 눌러주면 아래의 애니메이션 패널이 나타납니다.

4. 애니메이션 프레임 추가

Default를 walk라고 이름을 바꾸고, 새 애니메이션 추가 버튼을 클릭하여 up으로 이름으로 만들어줍니다. 아까 추가한 dodge_assets 폴더로 가보면 art라는 하위폴더가 있는데, 여기에서 PlayerGrey_walk1, 2는 walk프레임에, PlayerGrey_up1, 2는 up프레임에 드래그앤드랍으로 추가해줍니다.

다시 AnimationSprite노드를 클릭하고, 인스펙터 창에서 Node2D > Scale에서 x와 y를 각각 0.5로 입력하여 사이즈를 반으로 줄여줍니다.

5. 충돌감지노드 추가

Player노드에서 우클릭하여 새 노드를 추가합니다.검색창에 CollisionShape2D를 검색하여 추가해줍니다.

이 노드는 현재의 노드가 장애물(Mob)과 충돌을 감지할 수 있는 영역을 만들수 있게 해 줍니다. 즉, 이 노드만으로는 안되고, 실제 감지되는 영역을 지정해줘야합니다. 인스펙터 창에서 Shape > [비었음] 클릭 > 새 CapsuleShape2D 를 클릭하여 추가해줍니다.

그러면 캐릭터에 캡슐형 감지영역이 나타나게 됩니다.  감지영역의 핸들을 조정하여 적당히 커버될 수 있도록 조정합니다. 약간 이미지보다 작게 나타나도록 설정하는 것을 추천합니다.


6. Player 방향키 설정

적당히 진행하며 저장해주시고, 이제 Player의 움직임을 설정해줘야합니다. 여기서부터 코딩이 들어갑니다. Attach Script 버튼을 클릭합니다.

우선 필요한 변수를 선언합니다. (speed, screen_size)

export 키워드는 작업을 굉장히 편리하게 해 줍니다. 변수 앞에 export를 붙여주면 inpector 창에서 나타나게 됩니다. 그럼 inpector에서 값을 직접 설정하여, 테스트할 때 일일이 코드를 보지 않고도 테스트할 수 있도록 도와줍니다. 물론 스크립트에 설정된 기본값은 무시됩니다.

 

처음 게임이 시작되면 _ready()함수를 실행하게 되는데, 게임 창의 크기값을 가져와 screen_size라는 변수에 지정하도록 하겠습니다. 이 값은 나중에 활용할 계획입니다. 기존에 있던 pass 부분은 지워줍니다. 아무것도 안하는 함수일 때 필요한 지시어입니다.

func _ready():
    screen_size = get_viewport_rect().size

이제 진짜 움직임을 코딩합니다.

func _process(delta):
    var velocity = Vector2()  # The player's movement vector.
    if Input.is_action_pressed("ui_right"):
        velocity.x += 1
    if Input.is_action_pressed("ui_left"):
        velocity.x -= 1
    if Input.is_action_pressed("ui_down"):
        velocity.y += 1
    if Input.is_action_pressed("ui_up"):
        velocity.y -= 1
    if velocity.length() > 0:
        velocity = velocity.normalized() * speed
        $AnimatedSprite.play()
    else:
        $AnimatedSprite.stop()

우선 $AnimatedSprite.play() 의$는 get_node()의 단축 표기형입니다. get_node("AnimatedSprite").play()와 동일합니다. 위 코드는 아직 오류가 있는 것이 상하키와 좌우키를 동시에 누르면 1+1=2의 속도로 원래 움직임보다 더 빠르게 움직입니다.
다음으로 화면 밖으로 나가는 것을 방지하기 위해 clamp()함수로 영역을 지정해줍니다. func _process(delta)함수 하부에 이어서 아래 코드를 추가해줍니다.

position += velocity * delta
position.x = clamp(position.x, 0, screen_size.x)
position.y = clamp(position.y, 0, screen_size.y)

이제 "재생 장면" (F6)을 클릭하여 확인해봅니다.

이렇게 좌상단 구석에 우리 캐릭터가 위치하고 있습니다. 방향키를 눌러보면 움직이는 것이 보일 것입니다. 좀더 세부적인 동작은 아래에서 계속 하겠습니다.


7. 애니메이션 지정

Player가 상하로 움직일 때, 좌우로 움직일 때 각각 다른 애니메이션이 나오도록 지정을 해줘야 합니다. 방향을 역전시키는 것은 flip_v / flip_h 속성으로 간단히 만들 수 있습니다.

if velocity.x != 0:
    $AnimatedSprite.animation = "walk"
    $AnimatedSprite.flip_v = false
    $AnimatedSprite.flip_h = velocity.x < 0
elif velocity.y != 0:
    $AnimatedSprite.animation = "up"
    $AnimatedSprite.flip_v = velocity.y > 0

그리고, _ready() 함수에 아래 코드를 추가하여  게임 시작시 Player를 숨김상태로 시작하게 합니다.

hide()


8. 충돌 감지

이제 signal 기능을 이용하여 장애물과의 충돌을 인식시키도록 할 차례입니다. 스크립트 최상단 - extends Area2D 아래 - 에 아래 코드를 추가합니다.

signal hit

이렇게 하면 사용자가 정의하는 signal을 지정하게 됩니다. Player가 방출할 수 있는 signal의 종류는 Inspector창 옆의 Node탭에 보면 나타나게 됩니다. 방금 지정한 hit 시그널도 확인되는 것을 볼 수 있습니다.

본 게임에서의 장애물(Mob)은 RigidBody2D이고 body_entered(body: Node) 시그널이 발생하도록 할 계획입니다. 즉,

body_entered(body: Node)시그널 -> Player 사라짐

body_entered(body: Node)시그널 -> hit 시그널 -> 게임오버 진행 (Main.tscn에서 작성)

으로 구성할 예정입니다. 하단의 "연결" 또는 마우스 우클릭 후 "연결"을 클릭하고, 자동 생성된 함수명으로 "연결"을 클릭합니다.

그리고 연결되었다는 의미로 해당 함수 앞에 초록색 아이콘이 생성됩니다. 생성된 함수 내부에 아래와 같이 코딩합니다.

func _on_Player_body_entered(body):
    hide()  # 부닫히면 Player를 사라지게..
    emit_signal("hit")
    $CollisionShape2D.set_deferred("disabled", true)


이제 Mob이 Player와 충돌할 때마다 Signal이 방출되게 됩니다.

9. 초기화

마지막으로 새 게임 시작시 Player를 초기화하는 코드를 추가해줍니다.

func start(pos):
    position = pos
    show()
    $CollisionShape2D.disabled = false

 

<전체 코드:Player.gd>

extends Area2D

signal hit
export var speed = 400
var screen_size

# Called when the node enters the scene tree for the first time.
func _ready():
	screen_size = get_viewport_rect().size
	hide()


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	var velocity = Vector2()  # The player's movement vector.
	if Input.is_action_pressed("ui_right"):
		velocity.x += 1
	if Input.is_action_pressed("ui_left"):
		velocity.x -= 1
	if Input.is_action_pressed("ui_down"):
		velocity.y += 1
	if Input.is_action_pressed("ui_up"):
		velocity.y -= 1
	if velocity.length() > 0:
		velocity = velocity.normalized() * speed
		$AnimatedSprite.play()
	else:
		$AnimatedSprite.stop()
		
	# position
	position += velocity * delta
	position.x = clamp(position.x, 0, screen_size.x)
	position.y = clamp(position.y, 0, screen_size.y)
	
	# 방향 역전
	if velocity.x != 0:
		$AnimatedSprite.animation = "walk"
		$AnimatedSprite.flip_v = false
		$AnimatedSprite.flip_h = velocity.x < 0
	elif velocity.y != 0:
		$AnimatedSprite.animation = "up"
		$AnimatedSprite.flip_v = velocity.y > 0

func start(pos):
	position = pos
	show()
	$CollisionShape2D.disabled = false

func _on_Player_body_entered(body):
	hide()  # Player disappears after being hit.
	emit_signal("hit")
	$CollisionShape2D.set_deferred("disabled", true)

 

- Player Scene 끝 -

반응형
반응형

저장소 찾기가 쉽지않네요...

sudo add-apt-repository ppa:tomtomtom/conky-manager

sudo apt update && sudo apt install conky-manager2

 

그리고, 위젯에 요일이 제대로 표시가 안되고 네모로 나타나고 있습니다. 이건, Conky에서 설정한 폰트가 시스템에 없어서 그런건데요. .conky/ 폴더로 들어가면 fonts라는 폴더가 있습니다. 그곳에 있는 폰트 파일들을 /usr/share/fonts로 복사해줍니다. 이상한 것은 해당 위젯의 폰트가 GE_inspera.ttf인데, .conky/Gotham/Gotham파일에 보면 폰트가 GE Inspira로 되어있습니다.(언더바 빠짐). 이부분을 수정하여 GE_Inspira로 바꿔줍니다. 그러면 정상적으로 나옵니다.

 

 

반응형
반응형

 

삼성 프린터 드라이버를 찾고 있었는데, 삼성 프린터는 HP로 넘어갔다고 합니다.

따라서 프린터 드라이버 설치 시 HP의 잉크젯 JP 1000 시리즈나 또는 비지니스 잉크젯 1000 시리즈를 고르시면 됩니다.

반응형
반응형

 

Go언어로 다른 프로그램을 실행시키는 방법을 알아보겠습니다. 이번에도 역시 webview로 GUI를 구성하고, 버튼이 클릭되면 whale 브라우저를 실행하도록 해보겠습니다.

기존에 Webview가 설치되어있다면 다른 라이브러리 설치는 필요 없습니다. 단 os.exec 라이브러리를 사용하므로 임포트..정도는 필요합니다.

 

<main.go>

package main

import (
	"os/exec"

	"github.com/webview/webview"
)

func main() {
	w := webview.New(true)
	defer w.Destroy()
	w.SetSize(600, 200, webview.HintNone)
	// Create a GoLang function callable from JS
	w.Bind("hello", func() string { return "World!" })
	w.Bind("gorun", gorun)

	// Create UI with data URI
	w.Navigate(`data:text/html,
	 <!doctype html>
	 <html>
		<head><title>Hello</title></head>
		<body><h1>Run Servers!</h1></body>
		<button onclick="gorun();">RUN</button>
		<script> hello().then((x) => { console.log(x) }) </script>
	 </html>`)

	w.Run()
}

func gorun() {
	cmd := exec.Command("C:\\Program Files\\Naver\\Naver Whale\\Application\\whale.exe", "www.google.com")
	cmd.Start()
}

 

빨리 Gin 프로그램을 붙여 돌려봐야겠네요..^^

반응형
반응형

Oracle DB의 테이블을 이용해서 Join하는 방법을 알아보겠습니다.

 

1. 모델 정의

1:N관계에서 N쪽 테이블(TempDataroomHstry클래스)에 ForeignKey로 1쪽 테이블명(Temp래스)을 지정해줍니다. 이때, 1쪽 테이블의 참조하려는 필드가 Primary Key로 지정되어있으면 상관없지만, 없을 경우 필드 정의에(ForeignKey 함수 내부에서) to__field='목표필드' 를 지정해줘야 합니다. 그리고, db_column='참조칼럼명' 에서 해당 테이블에서 참조할 실제 칼럼(필드)명을 지정해줘야 합니다.

 

(*) Oracle DB에서만 이런 문제가 발생하는 것인지.. 아직은 잘 모르겠습니다. 이것 때문에 한참을 헤메었네요..^^;; 또한 이번의 경우 Temp의 emp_field와 TempDataroomHstry의 id는 사실 칼럼명은 동일하게 'emp_#'이었습니다. db_column에 넣어주는 값이 현재 테이블의 칼럼명인지, 목표 테이블의 칼럼명인지 좀 헷갈립니다...

<models.py>

from django.db import models


class Temp(models.Model):
    emp_field = models.CharField(db_column='emp_#', primary_key=True, max_length=7)  # Field renamed to remove unsuitable characters. Field renamed because it ended with '_'.
    emp_x = models.CharField(max_length=2, blank=True, null=True)
    kornm_n = models.CharField(max_length=32, blank=True, null=True)    
    res_1 = models.CharField(db_column='res_#1', max_length=12, blank=True, null=True)  # Field renamed to remove unsuitable characters.    
    sex_n = models.CharField(max_length=2, blank=True, null=True)    
    dept_c = models.CharField(max_length=16, blank=True, null=True)
    
    class Meta:
        managed = False
        db_table = 'TEMP'


class TempDataroomHstry(models.Model):
    seq_field = models.IntegerField(db_column='seq_#',primary_key=True)  # Field renamed to remove unsuitable characters. Field renamed because it ended with '_'.
    id = models.ForeignKey(Temp, to_field='emp_field', db_column='emp_#',on_delete=models.CASCADE, null=True, related_name='id')   #, related_name='tempdataroomhstry'
    in_d = models.DateField(blank=True, null=True)


    class Meta:
        managed = False
        db_table = 'TEMP_DATAROOM_HSTRY'

 

2. 데이터 활용하기

Join을 위해서는 "select_related()"나 "prefetch_related()"를 사용하는데, 이번에는 select_related()만 알아보도록 하겠습니다. select_related는 1:1 또는 1:N 의 경우에 사용할 수 있는 함수입니다. (정방향 참조필드). select_related()의 인자로는 해당 Table의 ForeinKey를 넣어줍니다. 아래의 예제에서는 우선 'id'칼럼을 이용하여 join후 모든 데이터를 불러오고 'in_d'를 기준으로 역정렬(desc)을 하여 list를 만들고, 이를 home.html에 넘겨줍니다.

<views.py>

from django.core.paginator import Paginator
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse

from .models import TempDataroomHstry

#### 초기화면 및 조회함수 ####
def index(request):
    list = {}
    list = TempDataroomHstry.objects.select_related('id').all().order_by('-in_d')

    # HTML에서 인자가 전달될 경우 처리
    q = request.GET.get('q', '')
    if q:
        list = list.filter(id=q)
    # 여기까지
   
    context = {'member_list': list}
    return render(request, 'home.html', context)

A테이블에 B가 조인될 경우 "[A].[조인된A칼럼명].[B칼럼명]"과 같이 사용하면 됩니다. 아래 home.html파일은 실제 Join된 데이터를 불러와 사용하는 예시를 볼 수 있습니다.

<home.html>

....
<tbody>
{% if member_list %}
  {% for member in member_list %}
    <tr>
      <td>{{ member.id.emp_field }}</td>
      <td>{{ member.id.kornm_n }}</td>
      <td>{{ member.id.res_1 }}</td>
      <td>{{ member.id.sex_n }}</td>
      <td>{{ member.id.dept_c }}</td>
      <td>{{ member.in_d }}</td>
    </tr>
  {% endfor %}
{% endif %}
</tbody>

 

~~~끝~~~

반응형
반응형

이번에는 Webview 라이브러리를 사용하면서 HTML 파일을 별도로 분리하는 방법을 알아보겠습니다. 그리고, 좀더 보기좋은 GUI 구성을 위해 부트스트랩도 함께 적용하도록 하겠습니다. 사실 이부분은...CSS 파일을 별도로 인식시켰으면 좋겠지만, 아직까지 별도의 CSS파일을 적용시키는 것은 안되는 것 같습니다. 

 

1. 라이브러리 설치

라이브러리 설치는 이전 강좌를 참고하세요.

 

2. main.go 파일 작성

main.go 파일에 전체 프로그램 구동을 구현합니다. 아울러, 버튼을 클릭했을 때 동작할 함수(go_hello)를 작성하고, 바인딩해줍니다. Webview라이브러리를 활용하면, go에서 javascript를 실행할 수도 있고, html파일(javascript 포함)에서 go언어를 실행할 수도 있습니다. 그러나 프로그램 가독성을 위해, Bind 한줄이 더 들어가더라도, 함수구현은 go에서 하도록 하겠습니다.

package main

import (
	"fmt"
	"os"

	"github.com/webview/webview"
)

var w webview.WebView

func main() {
	w = webview.New(true)
	defer w.Destroy()
	w.SetSize(600, 600, webview.HintNone) // Create a GoLang function callable from JS
	w.Bind("go_hello", go_hello)	// Go_hello 함수 구현과 html에서 호출하는 go_hello를 Bind해줍니다. 

	// Create UI with data URI
	dir, _ := os.Getwd()
	fmt.Println(dir)
	w.Navigate("file:" + dir + "/hi.html")

	w.Run()
}

// 함수 실행 시, javascript로 팝업 알람을 실행해서 데이터를 보여줍니다.
// HTML문서에서 보여주는 부분만큼은...javascript로..ㅠㅠ
func go_hello() {
	name := "You"
	w.Eval(`alert("Hello` + name + `");`)
}

데이터를 처리하는 것은 go 함수구현에서 할 수 있지만, 마지막으로 데이터를 HTML로 보내서 보여주는 부분은 Javascript로 할 수밖에 없겠네요..^^;;

 

3. hi.html

HTML로 뷰를 구현합니다. 서두에서 말했듯이 CSS 적용이 힘든 관계로 Bootstrap을 CDN으로 불러와 적용시키겠습니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

    <title>My App</title>
</head>
<body>
    <!--Header Section-->
    <div class="box-padding-big">
      <nav class="navbar navbar-expand-sm navbar-dark bg-dark">
        <div class="collapse navbar-collapse">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
              <a class="nav-link" href="#" id=navbardrop" data-toggle="dropdown">File</a>
              <div class="dropdown-menu">
              <a class="dropdown-item" href="#" onclick="go_hello()">Sub1</a>
              <a class="dropdown-item" href="#">Sub2</a>
              <a class="dropdown-item" href="#">Sub3</a>
              </div>
            </li>
            <li class="hav-item">
            	<a class="nav-link" href="#">Edit</a>
            </li>
            <li class="hav-item">
            	<a class="nav-link" href="#">View</a>
            </li>
            <li class="hav-item">
            	<a class="nav-link" href="#">Info</a>
            </li>
          </ul>
        </div>
      </nav>
    </div>

  <!--Main Section-->
  <div style="margin: 20px;">
  	<div style="font-size: 36px; color:chartreuse;font-weight:700">
      <div>GO-Webview HTML View Test <br/>
      with Bootstrap
      </div>
    </div>
    <p class="text-primary" style="margin-top:20px;">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam eget magna eros. Cras sit amet nulla dignissim, pretium justo sit amet, vulputate orci. Curabitur in aliquam lorem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi quis pulvinar nunc, sed posuere enim. In hac habitasse platea dictumst. Ut sodales augue eu elit bibendum, ut malesuada felis auctor. Sed mattis ipsum malesuada sem feugiat ultricies. Fusce ultrices vel est id pretium. Sed vel congue augue, non tincidunt tellus. Vivamus facilisis mollis tellus ac vulputate. 
    </p>
  </div>
</body>
</html>

 

4. 결과

아래 명령으로 결과를 확인합니다.

go run main.go

File - Sub1을 클릭하면...

알람 팝업이 잘 나옵니다.

 

이상으로 webview를 이용하여 html 파일과 bootstrap을 적용하는 방법을 알아봤습니다. 너무 쉽게 구현이 가능한데, 성능은 어느정도일지, 어떤 점이 부족할지 계속 알아봐야겠습니다.

 

~~~끝~~~

반응형
반응형

Go언어 GUI 라이브러리 중 Webview를 사용해서 데스크탑 앱을 만들어보도록 하겠습니다. Webview는 HTML로 레이아웃을 구성할 수 있어서 간단한 앱은 쉽게 만들 수 있습니다.

 

1. 라이브러리 설치

이번엔 리눅스환경에서(우분투 20.04) 라이브러리를 설치하겠습니다. 

sudo apt-get install libgtk-3-dev
sudo apt-get install libwebkit2gtk-4.0-dev

go get github.com/webview/webview

2. Sample Project

다음으로 간단히 main.go 파일을 생성하고, 아래와 같이 작성해줍니다.

package main

import "github.com/webview/webview"

func main() {
	w := webview.New(true)
	defer w.Destroy()
	w.SetSize(600, 200, webview.HintNone) // Create a GoLang function callable from JS
	w.Bind("hello", func() string { return "World!" })

	// Create UI with data URI
	w.Navigate(`data:text/html,
	 <!doctype html>
	 <html>
	  <head><title>Hello</title></head>
	  <body><h1>Hello, world!</h1></body>
	  <script> hello().then((x) => { console.log(x) }) </script>
	 </html>`)

	w.Run()
}

 

3. 실행

터미널에서 아래와 같이 명령하면..

go run main.go

이쁜 앱이 나타났습니다. 라이브러리만 설치하면 프로그램 작성은 정말 쉽게 할 수 있네요.

 

이상으로  Golang에서 Webview 라이브러리를 이용한 GUI개발을 알아봤습니다. 

다음번엔 HTML 파일을 분리하여 작성하는 방법을 알아보겠습니다.

 

~~~끝~~~

반응형

+ Recent posts