우선 앞서 lxn/walk 와 win 을 제 깃헙으로 클론해서 따로 관리한다고 글 올렸으니 참고하시구요.
https://modu-print.tistory.com/731
Go언어 윈도 GUI 개발관련 win/walk 패키지 분리
기존에 Go언어로 윈도 GUI 개발과 관련하여 lxn/win, lxn/walk 패키지를 이용한 개발 방법을 글로 작성 했었는데요.. 작성한 글중중에도 .. WebView 의 자바스크립트 오류와 관련해서 이 패키지들을 수정
modu-print.tistory.com
창이나 특정 UI 객체에 드래그앤드랍을 통한 파일처리가 필요한 경우가 있습니다.
예를들어 파일리스트에 파일을 드래그앤 드랍으로 던지면 던진 파일들이 추가가 된다던지..
LineEdit 에 파일을 드래그앤드랍하면 해당 파일의 경로가 채워 진다던지 ..
/**
* TableViewWin
**/
func TableViewWin() {
cbModel := new(testTableViewListModel)
mgr, window := NewWindowMgrNoResizeNoMinMax("TableView 예제", 400, 300, GetIcon())
th := []tableViewHeader{{Title: "이름", Width: 150}, {Title: "설명", Width: 150}}
testTv := mgr.TableView(cbModel, th, true, true)
// 드랍파일
window.DropFiles().Attach(func(s []string) {
for _, fname := range s {
fmt.Println(fname)
//MsgBox(fname)
}
})
// 마우스 클릭
testTv.MouseDown().Attach(func(x int, y int, mouse walk.MouseButton) {
if mouse == walk.LeftButton && x > 18 {
nCurrItem := testTv.IndexAt(x, y)
if nCurrItem > -1 {
if cbModel.items[nCurrItem].checked {
cbModel.items[nCurrItem].checked = false
} else {
cbModel.items[nCurrItem].checked = true
}
testTv.UpdateItem(nCurrItem)
}
}
})
testTv.KeyUp().Attach(func(key walk.Key) {
if key == walk.KeyDelete {
currIdx := testTv.CurrentIndex()
if currIdx != -1 {
if !Confirm(fmt.Sprintf("%s 를 삭제합니다.", cbModel.items[currIdx].Name)) {
return
}
cbModel.items = append(cbModel.items[:currIdx], cbModel.items[currIdx+1:]...)
cbModel.PublishRowsReset()
}
} else if key == walk.KeyReturn {
od := testTableViewListItem{}
od.Name = "피로곰"
od.Desc = "만세"
cbModel.items = append(cbModel.items, od)
cbModel.PublishRowsReset()
}
})
testTv.ItemActivated().Attach(func() {
currIdx := testTv.CurrentIndex()
if currIdx != -1 {
MsgBox(fmt.Sprintf("선택된 아이템 : %d", currIdx))
}
})
mgr.PushButton("선택된 아이템", func() {
selectedIndex := testTv.SelectedIndexes()
if len(selectedIndex) == 0 {
MsgBox("없음")
} else {
MsgBox(fmt.Sprintf("%v", selectedIndex))
}
})
mgr.PushButton("전체체크", func() {
for idx, _ := range cbModel.items {
cbModel.items[idx].checked = true
testTv.UpdateItem(idx)
}
})
mgr.PushButton("전체체크해제", func() {
for idx, _ := range cbModel.items {
cbModel.items[idx].checked = false
testTv.UpdateItem(idx)
}
})
window.Starting().Attach(func() {
ad := []testTableViewListItem{
{Name: "피로곰", Desc: "만세"},
{Name: "Panic", Desc: "환자"},
{Name: "용민", Desc: "환자2"},
}
cbModel.items = append(cbModel.items, ad...)
cbModel.PublishRowsReset()
})
mgr.StartForeground()
}
기존에 테이블뷰(리스트컨트롤)을 설명하면서 사용한 예제에
// 드랍파일
window.DropFiles().Attach(func(s []string) {
for _, fname := range s {
fmt.Println(fname)
//MsgBox(fname)
}
})
드래그앤 드랍에 관한 이벤트 핸들러를 지정해 줬습니다. 보시면 window.DropFiles 라고 사용 했는데요 이러면 전체 창 어디에든 드래그앤 드랍이 먹게 되겠습니다.
만약에 테이블뷰에만 이벤트를 먹게하고 싶으면?
// 드랍파일
testTv.DropFiles().Attach(func(s []string) {
for _, fname := range s {
fmt.Println(fname)
//MsgBox(fname)
}
})
이렇게 테이블뷰 객체의 DropFiles 에다가 Attach 하면 되겠습니다.
[]string 배열로 드래그앤 드랍된 파일경로와 파일명이 전달됩니다.
LineEdit 라던지 TextArea 든 뭐든간에 이 DropFiles 메소드가 존재하는 walk 객체에는 전부 사용 가능합니다.
한가지.. 기존 lxn/walk 의 경우에는 최근에는 관리되고 있질 않고 마지막 수정이 14개월전인 만큼 .. 최근 윈도 시스템 변경사항은 적용되지 못한 부분이 좀 있습니다.
대표적으로 드래그앤드랍에 쓰이는 WM_DROPFILES 라는 윈도 메시지는 UAC(사용자계정컨트롤)이 동작하는 상황에서 관리자권한으로 실행된 프로세스에는 메시지 발생을 하지 않습니다.
그리하여 관련 부분에 문제 없도록 제가 관리하는 walk 패키지쪽에 수정해서 적용해 두었습니다.
go get github.com/pirogom/walk 해서 기존 lxn/walk 패키지를 대체하여 사용하시면 되구요
기존에 쓰고 계신분들은
go get -u github.com/pirogom/walk
하시면 되겠습니다.