메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

Sqlite + listview + tab 구현

데브카페

Sqlite + listview + tab 구현

  1. AutoIt으로 SQLite에 저장된 group별 key와 value를 ListView로 구현하고, group을 Tab으로 구분하여 해당 탭 선택 시 데이터가 표시되도록 하는 예제 코드를 작성해 드리겠습니다.

기능

  1. SQLite 데이터베이스 연결 및 생성: MyDatabase.db 파일을 생성하고, Groups 테이블에 GroupName, KeyName, ValueData 컬럼을 가집니다.
  2. 샘플 데이터 삽입: "GroupA", "GroupB", "GroupC" 세 개의 그룹에 샘플 키-값 데이터를 삽입합니다.
  3. GUI 생성:
    1. Tab 컨트롤을 사용하여 그룹을 탭으로 표시합니다.
    2. ListView 컨트롤을 사용하여 선택된 탭(그룹)의 키와 값을 표시합니다.
    3. 탭 선택 이벤트 처리: 탭이 변경될 때마다 해당 그룹의 데이터를 SQLite에서 불러와 ListView를 업데이트합니다.
  • SQLite UDF (User Defined Function)가 필요합니다.
  • 일반적으로 AutoIt 설치 시 포함되거나, AutoIt 포럼 등에서 다운로드 받을 수 있습니다.
  • 예제에서는 SQLite.au3 파일이 AutoIt 스크립트와 같은 폴더에 있다고 가정합니다.

AutoIt 스크립트 (SQLite_Tab_ListView.au3)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <SQLite.au3>
#include <TabConstants.au3>
#include <ListviewConstants.au3>
#include <StaticConstants.au3>
#include <GuiTab.au3>

; SQLite 데이터베이스 파일 경로
Global Const $g_sDBFile = @ScriptDir & "\MyDatabase.db"

; GUI 핸들
Global $g_hGUI
Global $g_hTab
Global $g_hListView
Global $g_idDummyTabItem ; 더미 탭 아이템의 ID를 저장할 변수

; 데이터베이스 핸들 (SQLite_Open이 반환하는 값)
Global $g_hSQLiteDB = 0 ; 초기값 0으로 설정

Func Main()
    ; 데이터베이스 초기화 및 샘플 데이터 삽입
    _InitDatabase()

    ; GUI 생성
    _CreateGUI()

    ; 탭에 그룹 로드
    _LoadGroupsToTab()

    ; GUI 메시지 루프
    While 1
        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $g_hTab
                ; 탭 변경 이벤트 처리
                _TabChanged()

        EndSwitch
    WEnd

    ; GUI 종료
    GUIDelete($g_hGUI)
    ; 데이터베이스 닫기
    If $g_hSQLiteDB <> 0 Then ; 데이터베이스 핸들이 유효하면 닫습니다.
        _SQLite_Close($g_hSQLiteDB)
    EndIf
    _SQLite_Shutdown() ; SQLite 엔진 종료
EndFunc

Func _InitDatabase()
    _SQLite_Startup() ; 데이터베이스 사용 전 항상 시작

    ; 데이터베이스 파일이 없으면 생성 및 샘플 데이터 삽입
    If Not FileExists($g_sDBFile) Then
        $g_hSQLiteDB = _SQLite_Open($g_sDBFile)
        If @error Then
            MsgBox(0, "오류", "데이터베이스를 열 수 없습니다: " & $g_sDBFile)
            Exit
        EndIf

        _SQLite_Exec($g_hSQLiteDB, "CREATE TABLE IF NOT EXISTS Groups (GroupName TEXT, KeyName TEXT, ValueData TEXT)")
        ConsoleWrite("데이터베이스 및 테이블 생성 완료." & @CRLF)

        ; 샘플 데이터 삽입
        _SQLite_Exec($g_hSQLiteDB, "INSERT INTO Groups (GroupName, KeyName, ValueData) VALUES ('GroupA', 'KeyA1', 'ValueA1')")
        _SQLite_Exec($g_hSQLiteDB, "INSERT INTO Groups (GroupName, KeyName, ValueData) VALUES ('GroupA', 'KeyA2', 'ValueA2')")
        _SQLite_Exec($g_hSQLiteDB, "INSERT INTO Groups (GroupName, KeyName, ValueData) VALUES ('GroupA', 'KeyA3', 'ValueA3')")

        _SQLite_Exec($g_hSQLiteDB, "INSERT INTO Groups (GroupName, KeyName, ValueData) VALUES ('GroupB', 'KeyB1', 'ValueB1')")
        _SQLite_Exec($g_hSQLiteDB, "INSERT INTO Groups (GroupName, KeyName, ValueData) VALUES ('GroupB', 'KeyB2', 'ValueB2')")
        _SQLite_Exec($g_hSQLiteDB, "INSERT INTO Groups (GroupName, KeyName, ValueData) VALUES ('GroupB', 'KeyB3', 'ValueB3')")

        _SQLite_Exec($g_hSQLiteDB, "INSERT INTO Groups (GroupName, KeyName, ValueData) VALUES ('GroupC', 'KeyC1', 'ValueC1')")
        _SQLite_Exec($g_hSQLiteDB, "INSERT INTO Groups (GroupName, KeyName, ValueData) VALUES ('GroupC', 'KeyC2', 'ValueC2')")
        _SQLite_Exec($g_hSQLiteDB, "INSERT INTO Groups (GroupName, KeyName, ValueData) VALUES ('GroupC', 'KeyC3', 'ValueC3')")

        ConsoleWrite("샘플 데이터 삽입 완료." & @CRLF)
        ; 데이터베이스 연결은 계속 유지해야 하므로 여기서 _SQLite_Close() 호출하지 않음
    Else
        ; 데이터베이스 파일이 이미 존재하는 경우 열기
        $g_hSQLiteDB = _SQLite_Open($g_sDBFile)
        If @error Then
            MsgBox(0, "오류", "데이터베이스를 열 수 없습니다: " & $g_sDBFile)
            Exit
        EndIf
    EndIf
EndFunc

Func _CreateGUI()
    $g_hGUI = GUICreate("그룹별 Key-Value", 600, 400)

    ; 탭 컨트롤 생성
    $g_hTab = GUICtrlCreateTab(10, 10, 580, 380)

    ; 리스트뷰 컨트롤 생성 (탭 내부)
    $g_idDummyTabItem = GUICtrlCreateTabItem("")
    $g_hListView = GUICtrlCreateListView("Key|Value", 20, 40, 560, 340, $LVS_REPORT)
    GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 0, 275) ; Key 컬럼 너비 설정
    GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 1, 275) ; Value 컬럼 너비 설정

    GUISetState(@SW_SHOW)
EndFunc

Func _LoadGroupsToTab()
;~     Local $aResult, $iRows, $iCols
    Local $sSQL = "SELECT DISTINCT GroupName FROM Groups ORDER BY GroupName"

    ; 데이터베이스에서 데이터 조회
    Local $aResult, $iRows, $iColumns
    _SQLite_GetTable2d(-1, $sSQL, $aResult, $iRows, $iColumns)
    If @error Then
        MsgBox(16, "SQLite Error", "데이터 조회 실패")
        Return
    EndIf

    ; 조회 결과를 ListView에 추가
;~     For $i = 1 To $iRows
;~         GUICtrlCreateListViewItem($aResult[$i][0] & "|" & $aResult[$i][1] & "|" & $aResult[$i][2], $idListView)
;~     Next

    ; 데이터베이스 핸들($g_hSQLiteDB)을 첫 번째 인자로 전달
;~     _SQLite_Query($g_hSQLiteDB, $sSQL, $aResult, $iRows, $iCols)

    If @error = 0 And $iRows > 0 Then
        For $i = 0 To $iRows
            GUICtrlCreateTabItem($aResult[$i][0])
        Next
        If $g_idDummyTabItem <> 0 Then
            GUICtrlDelete($g_idDummyTabItem)
            $g_idDummyTabItem = 0
        EndIf

        GUICtrlSetState($g_hTab, @SW_SHOW)
;~         GUICtrlSetState(GUICtrlRead($g_hTab), $GUI_SELECT)
		GUICtrlSetState(GUICtrlRead($g_hTab), 256) ; 첫 번째 탭을 선택
        _TabChanged()
    Else
        MsgBox(0, "오류", "그룹을 로드할 수 없습니다: " & @error & " - " & @extended)
    EndIf
EndFunc

Func _TabChanged()
;~     Local $iSelectedTabItemIndex 	= GUICtrlRead($g_hTab)
;~ 	ConsoleWrite($iSelectedTabItemIndex & @CRLF)
;~     Local $sSelectedGroupName 		= GUICtrlRead($g_hTab,$iSelectedTabItemIndex)
;~ 	ConsoleWrite($sSelectedGroupName& @CRLF)

    ; 현재 선택된 탭의 인덱스를 가져옵니다.
    Local $iSelectedTabItemIndex = _GUICtrlTab_GetCurSel($g_hTab)

    ; 선택된 탭 아이템의 텍스트(그룹 이름)를 가져옵니다.
    Local $sSelectedGroupName = _GUICtrlTab_GetItemText($g_hTab, $iSelectedTabItemIndex)


;~ 	_GUICtrlTab_SetCurSel($g_hTab, $iSelectedTabItemIndex)
;~     ConsoleWrite("Current Selection: " & _GUICtrlTab_GetCurSel($g_hTab))

;~ 	$sSelectedGroupName="GroupA"
    ; 리스트뷰 초기화
    GUICtrlSendMsg($g_hListView, $LVM_DELETEALLITEMS, 0, 0)

    If Not StringIsSpace($sSelectedGroupName) Then
;~         Local $aResult, $iRows, $iCols
        ; SQL 인젝션 방지를 위해 _SQLite_Escape 함수 사용을 고려
        Local $sSQL = "SELECT KeyName, ValueData FROM Groups WHERE GroupName = " & _SQLite_Escape($sSelectedGroupName) & " ORDER BY KeyName"
;~ 		Local $sSQL = "SELECT KeyName, ValueData FROM Groups WHERE GroupName = 'GroupA' ORDER BY KeyName"
		ConsoleWrite($sSQL& @CRLF)
        ; 데이터베이스 핸들($g_hSQLiteDB)을 첫 번째 인자로 전달
;~         _SQLite_Query(-1, $sSQL, $aResult, $iRows, $iCols)

		Local $aResult, $iRows, $iColumns
		_SQLite_GetTable2d(-1, $sSQL, $aResult, $iRows, $iColumns)
		If @error Then
			MsgBox(16, "SQLite Error", "데이터 조회 실패")
			Return
		EndIf

        For $i = 0 To $iRows - 1
;~             GUICtrlCreateListViewItem($aResult[$i][0])
			GUICtrlCreateListViewItem($aResult[$i][0] & "|" & $aResult[$i][1], $g_hListView)
        Next
        If $g_idDummyTabItem <> 0 Then
            GUICtrlDelete($g_idDummyTabItem)
            $g_idDummyTabItem = 0
        EndIf

;~         If @error = 0 And $iRows > 0 Then
;~             For $i = 0 To $iRows - 1
;~                 GUICtrlCreateListViewItem($aResult[$i][0] & "|" & $aResult[$i][1], $g_hListView)
;~             Next
;~         Else
;~             ConsoleWrite("그룹 '" & $sSelectedGroupName & "' 에 데이터가 없습니다. 오류: " & @error & " - " & @extended & @CRLF)
;~         EndIf
    EndIf
EndFunc

Main()

설명

  1. #include 지시문: 필요한 AutoIt 라이브러리 (GUI, Windows, SQLite, Tab, Listview)를 포함합니다.
  2. $g_sDBFile: SQLite 데이터베이스 파일의 경로를 정의합니다. @ScriptDir은 스크립트가 실행되는 디렉토리를 나타냅니다.
    1. Main() 함수:
      1. _InitDatabase()를 호출하여 데이터베이스를 초기화하고 샘플 데이터를 삽입합니다.
      2. _CreateGUI()를 호출하여 GUI를 생성합니다.
      3. _LoadGroupsToTab()를 호출하여 데이터베이스에서 그룹 목록을 가져와 탭으로 추가합니다.
      4. While 1 루프는 GUI 메시지를 처리합니다. $GUI_EVENT_CLOSE 메시지를 받으면 루프를 종료합니다.
      5. $g_hTab (탭 컨트롤)에서 메시지가 발생하면 _TabChanged() 함수를 호출하여 탭 변경 이벤트를 처리합니다.
    2. _InitDatabase() 함수:
      1. MyDatabase.db 파일이 없으면 새로 생성하고 Groups 테이블을 만듭니다.
      2. 샘플 데이터를 Groups 테이블에 삽입합니다 (GroupA, GroupB, GroupC).
      3. _SQLite_Startup() 및 _SQLite_Open()을 사용하여 데이터베이스에 연결합니다.
      4. 주의: 이 예제에서는 파일이 없을 때만 데이터를 삽입합니다. 매번 실행 시 데이터를 초기화하고 싶다면 FileExists 조건을 제거하고 _SQLite_Exec("DROP TABLE IF EXISTS Groups")를 추가할 수 있습니다.
    3. _CreateGUI() 함수:
      1. GUICreate()로 메인 윈도우를 생성합니다.
      2. GUICtrlCreateTab()으로 탭 컨트롤을 생성합니다.
      3. GUICtrlCreateListView()로 리스트뷰 컨트롤을 생성합니다. "Key|Value"는 리스트뷰의 컬럼 헤더를 정의합니다. LVS_REPORT 스타일은 자세히 보기 모드를 의미합니다.
      4. GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, ...)를 사용하여 각 컬럼의 너비를 설정합니다.
    4. _LoadGroupsToTab() 함수:
      1. SELECT DISTINCT GroupName FROM Groups 쿼리를 사용하여 데이터베이스에서 중복되지 않는 그룹 이름을 가져옵니다.
      2. 가져온 각 그룹 이름을 GUICtrlCreateTabItem()을 사용하여 탭 컨트롤에 추가합니다.
      3. 첫 번째 탭이 자동으로 선택되도록 GUICtrlSetState를 호출하고, _TabChanged()를 호출하여 첫 번째 탭의 데이터를 로드합니다.
    5. _TabChanged() 함수:
      1. GUICtrlRead($g_hTab)를 사용하여 현재 선택된 탭의 인덱스를 가져옵니다.
      2. GUICtrlRead($g_hTab & $iSelectedTab)를 사용하여 선택된 탭의 텍스트(그룹 이름)를 가져옵니다.
      3. GUICtrlSendMsg($g_hListView, $LVM_DELETEALLITEMS, 0, 0)를 사용하여 리스트뷰의 기존 데이터를 모두 삭제합니다.
      4. SELECT KeyName, ValueData FROM Groups WHERE GroupName = '...' 쿼리를 사용하여 선택된 그룹에 해당하는 키와 값을 가져옵니다.
      5. 가져온 키와 값을 GUICtrlCreateListViewItem()을 사용하여 리스트뷰에 추가합니다.

실행 방법:

    1. 위 코드를 SQLite_Tab_ListView.au3와 같은 이름으로 저장합니다.
    2. AutoIt이 설치된 경로의 SciTE 편집기에서 F5 키를 눌러 실행하거나, .au3 파일을 더블클릭하여 컴파일러로 실행합니다.

주의사항:

    1. SQLite UDF (SQLite.au3) 파일이 스크립트와 같은 디렉토리에 있는지 확인하세요. 만약 다른 곳에 있다면 #include 경로를 수정해야 합니다.
    2. 처음 실행 시 MyDatabase.db 파일이 생성되고 샘플 데이터가 삽입됩니다. 이후 실행부터는 기존 데이터베이스를 사용합니다.
    3. 에러 메시지나 디버깅 정보를 보고 싶다면 AutoIt Window Info 툴을 사용하거나 ConsoleWrite()를 활용하세요.

이 코드는 기본적인 기능을 제공하며, 필요에 따라 오류 처리, 데이터 유효성 검사, UI 개선 등 추가적인 기능을 구현할 수 있습니다.

Comments