Что нового

[Элементы GUI] Создание элемента treeview с детьми и внуками

Latoid

Знающий
Сообщения
95
Репутация
11
Здравствуйте.
Имею, к примеру, следующие файлы в папке скрипта:

2009=09=19=23+23+54=Alexa_M.let
2009=09=19=23+23+55=Alexa_M.let
2009=09=19=23+23+56=Alexa_M.let
2009=09=19=23+23+57=Markovo.let
2009=09=19=23+25+35=Alexa_M.let
2009=09=19=23+25+37=Bay.let
2009=09=19=23+25+38=Alexa_M.let
2009=09=22=23+25+39=Alexa_M.let
2009=09=19=23+25+45=Geroy.let
2009=11=20=00+25+35=Alexa_M.let

Шаблон:
Год=НомерМесяца=Дата=Время=Название.расширение
Нужно получить в GUI элемент treeview такой:


09 2009 ; родитель 1
|
|-- Alexa_M ;дитё 1.1
| |
| |-- 19 23+23+54 ;внук 1.1.1
| |-- 19 23+23+55 ;внук 1.1.2
| |-- 19 23+23+56 ;внук 1.1.3
| |-- 19 23+25+35 ;внук 1.1.4
| |-- 19 23+25+38 ;внук 1.1.5
| |-- 22 23+25+39 ;внук 1.1.6
|
|-- Markovo ; дитё 1.2
| |
| |-- 19 23+23+57 ;внук 1.2.1
|
|-- Bay ; дитё 1.3
| |
| |-- 19 23+25+37 ;внук 1.3.1
|
|-- Geroy ;дитё 1.4
| |
| |--19 23+25+45 ;внук 1.4.1
|
|
|
11 2009 ;родитель 2
|
|-- Alexa_M ;дитё 2.1
| |
| |--20 00+25+35 ;внук 2.1.1

Можете помочь с этим? Спасибо
 

Lazycat

Осваивающий
Сообщения
46
Репутация
21
Есть у меня готовая функция, писал для преобразования плоских списков в дерево. Только немного адаптировал под пример. Для простоты список файлов в примере - просто массив.

Код:
Dim $nFileCount = 10
Dim $aFiles[$nFileCount]
$aFiles[0] = "2009=09=19=23+23+54=Alexa_M.let"
$aFiles[1] = "2009=09=19=23+23+55=Alexa_M.let"
$aFiles[2] = "2009=09=19=23+23+56=Alexa_M.let"
$aFiles[3] = "2009=09=19=23+23+57=Markovo.let"
$aFiles[4] = "2009=09=19=23+25+35=Alexa_M.let"
$aFiles[5] = "2009=09=19=23+25+37=Bay.let"
$aFiles[6] = "2009=09=19=23+25+38=Alexa_M.let"
$aFiles[7] = "2009=09=22=23+25+39=Alexa_M.let"
$aFiles[8] = "2009=09=19=23+25+45=Geroy.let"
$aFiles[9] = "2009=11=20=00+25+35=Alexa_M.let"

; Преобразуем имена файлов в двумерный список узлов
Dim $aItems[$nFileCount][3]
For $i = 0 To $nFileCount - 1
    $aResult = StringRegExp($aFiles[$i], "(\d{4})=(\d{2})=(\d{2})=(\d{2}\+\d{2}\+\d{2})=(\w+)\.let", 1) 
    ; тут надо проверочку, что регэксп отработал
    $aItems[$i][0] = $aResult[1] & " " & $aResult[0]
    $aItems[$i][1] = $aResult[4]
    $aItems[$i][2] = $aResult[2] & " " & $aResult[3]
Next

; Все элементы дерева храним во вложенных двумерных массивах
; Каждая строка массива: Имя узла, хэндл, список потомков
; Количество потомков узла в нулевом элементе
Dim $aRoot[1][3] = [[0,0,0]]

$hGUI = GUICreate("")
$hTree = GUICtrlCreateTreeView(5, 5, 350, 350)

; Заполним дерево
For $i = 0 To UBound($aItems) - 1
    _FillTree($aRoot, $aItems, $i, $hTree)
Next

GUISetState()
While 1
Wend

; Функции
Func _ItemIndex($aArray, $sItem)
    For $i = 0 To UBound($aArray)-1
        If $aArray[$i][0] == $sItem Then Return $i
    Next
    Return -1
EndFunc

Func _FillTree(ByRef $aArray, ByRef $aSource, $nSrcIndex, $hParent, $nLevel = 0)
    Local $hItem, $aTemp[1][3] = [[0,0,0]] 
    If $nLevel >= UBound($aSource, 2) Then Return
    $nIndex = _ItemIndex($aArray, $aSource[$nSrcIndex][$nLevel])
    If $nIndex = -1 Then 
        $aArray[0][0] += 1
        $nIndex = $aArray[0][0]
        ReDim $aArray[$nIndex+1][3]
        $aArray[$nIndex][0] = $aSource[$nSrcIndex][$nLevel]
        $aArray[$nIndex][1] = GUICtrlCreateTreeViewItem($aArray[$nIndex][0], $hParent)
        $aArray[$nIndex][2] = $aTemp
    EndIf
    $aTempItem = $aArray[$nIndex][2]
    _FillTree($aTempItem, $aSource, $nSrcIndex, $aArray[$nIndex][1], $nLevel + 1)
    $aArray[$nIndex][2] = $aTempItem
EndFunc
 
Автор
L

Latoid

Знающий
Сообщения
95
Репутация
11
Великолепно! Третий день не мог сиё сделать. Спасибо огромное.


Добавлено:
Сообщение автоматически объединено:

Loopback
Доделай, пож., доброе дело. Тут тебе дел на минуту. А я всё никак срастить не могу как твой код работает.
В-общем вот так у меня:
Код:
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <TreeViewConstants.au3>
#include <GuiTreeView.au3>
Opt("GUIOnEventMode", 1)
Dim $nFileCount = 17
Dim $aFiles[$nFileCount]
$aFiles[0] = "2009=09=19=23+23+54=Alexa_M.let"
$aFiles[1] = "2009=09=19=23+23+55=Alexa_M.let"
$aFiles[2] = "2009=09=19=23+23+56=Alexa_M.let"
$aFiles[3] = "2009=09=19=23+23+57=Markovo.let"
$aFiles[4] = "2009=09=19=23+25+35=Alexa_M.let"
$aFiles[5] = "2009=09=19=23+25+37=Bay.let"
$aFiles[6] = "2009=09=19=23+25+38=Alexa_M.let"
$aFiles[7] = "2009=09=22=23+25+39=Alexa_M.let"
$aFiles[8] = "2009=09=19=23+25+45=Geroy.let"
$aFiles[9] = "2009=11=20=00+25+35=Alexa_M.let"
$aFiles[10] = "2008=11=20=00+25+35=Alexa_M.let"
$aFiles[11] = "2007=11=20=00+25+35=Alexa_M.let"
$aFiles[12] = "2007=01=20=00+25+35=Markovo.let"
$aFiles[13] = "2007=01=22=00+25+35=Bay.let"
$aFiles[14] = "2007=01=22=00+27+35=Alexa_M.let"
$aFiles[15] = "2007=05=20=00+25+35=Bay.let"
$aFiles[16] = "2007=05=28=00+25+35=Alexa_M.let"


; Преобразуем имена файлов в двумерный список узлов
Dim $aItems[$nFileCount][3]
For $i = 0 To $nFileCount - 1
    $aResult = StringRegExp($aFiles[$i], "(\d{4})=(\d{2})=(\d{2})=(\d{2}\+\d{2}\+\d{2})=(\w+)\.let", 1) 
    ; тут надо проверочку, что регэксп отработал
    $aItems[$i][0] = $aResult[1] & " " & $aResult[0]
    $aItems[$i][1] = $aResult[4]
    $aItems[$i][2] = $aResult[2] & " " & $aResult[3]
Next

; Все элементы дерева храним во вложенных двумерных массивах
; Каждая строка массива: Имя узла, хэндл, список потомков
; Количество потомков узла в нулевом элементе
Dim $aRoot[1][3] = [[0,0,0]]

$hGUI = GUICreate("")
GUISetOnEvent($GUI_EVENT_CLOSE, "_ExitApp")
$hTree = GUICtrlCreateTreeView(5, 5, 350, 350)

; Заполним дерево
For $i = 0 To UBound($aItems) - 1
    _FillTree($aRoot, $aItems, $i, $hTree)
Next

GUISetState()
While 1
Wend

; Функции
Func _ItemIndex($aArray, $sItem)
    For $i = 0 To UBound($aArray)-1
        If $aArray[$i][0] == $sItem Then Return $i
    Next
    Return -1
EndFunc

Func _FillTree(ByRef $aArray, ByRef $aSource, $nSrcIndex, $hParent, $nLevel = 0)
    Local $hItem, $aTemp[1][3] = [[0,0,0]] 
    If $nLevel >= UBound($aSource, 2) Then Return
    $nIndex = _ItemIndex($aArray, $aSource[$nSrcIndex][$nLevel])
    If $nIndex = -1 Then 
        $aArray[0][0] += 1
        $nIndex = $aArray[0][0]
        ReDim $aArray[$nIndex+1][3]
        $aArray[$nIndex][0] = $aSource[$nSrcIndex][$nLevel]
        $aArray[$nIndex][1] = GUICtrlCreateTreeViewItem($aArray[$nIndex][0], $hParent)
		
		
		GUICtrlSetOnEvent(-1,"_GetTreeViewItem") ; Вот эта команда должна выполнятся только при создании внуков (элементов дерева третьего уровня вложености)
		
		
        $aArray[$nIndex][2] = $aTemp
    EndIf
    $aTempItem = $aArray[$nIndex][2]
    _FillTree($aTempItem, $aSource, $nSrcIndex, $aArray[$nIndex][1], $nLevel + 1)
    $aArray[$nIndex][2] = $aTempItem
EndFunc
 
Func _GetTreeViewItem()
	$grandson=GUICtrlRead(@GUI_CtrlId,1)
	$child = GUICtrlRead (_GUICtrlTreeView_GetParentParam($htree, $grandson), 1)
	$parent = GUICtrlRead (_GUICtrlTreeView_GetParentParam($htree, _GUICtrlTreeView_GetParentParam($htree, $child)), 1)
	ConsoleWrite ($parent & @CRLF)
	ConsoleWrite ($child & @CRLF)
	ConsoleWrite ($grandson & @CRLF)
	ConsoleWrite ("________________________" & @CRLF)
EndFunc ; ==> _GetTreeViewItem
 
Func _ExitApp()
	Exit 0
EndFunc ; ==> _ExitApp

Знаю, что коряво пишу, но как уж умею.

Т.е. при клике на ветку дерева в Консоль выводятся текст ветки и её предков. Из этого легко можно будет реконструировать имя файла обратно, чтобы отобразить его содержимое в соседнем с деревом элементом edit.
Просьба такая - команда GUICtrlSetOnEvent(-1,"_GetTreeViewItem") должна выполнятся только при создании "внуков", т.е. веток третьего уровня вложенности. )
Спасибо
 
Автор
L

Latoid

Знающий
Сообщения
95
Репутация
11
Все, сообразил

If $nLevel = 2 Then GUICtrlSetOnEvent(-1,"_GetTreeViewItem")
 
Верх