AHK多维列表可通过箭头键导航并按Enter

时间:2019-03-08 10:32:15

标签: list multidimensional-array autohotkey arrow-keys

在AHK(自动热键)中,我需要从具有主要类别且每个类别都有自己单独条目的表中加载列表。

blue            red             green               yellow
Item 1 of blue  Item 1 of red   Item 1 of green     Item 1 of yellow
Item 2 of blue  Item 2 of red   Item 2 of green     Item 2 of yellow
Item 3 of blue  Item 3 of red   Item 3 of green     Item 3 of yellow
Item 4 of blue                  Item 4 of green     Item 4 of yellow
Item 5 of blue                  Item 5 of green 
                                Item 6 of green 
                                Item 7 of green 

(能够从文件中加载表而不是直接将其写入脚本代码中会很好。但是我不知道将表保存在哪种表格式中以及如何将其动态地包含到脚本中。但这只是一个旁注)。

该表也可以在此处作为实际表查看:

https://docs.google.com/spreadsheets/d/1rFDX_XpD0seDHpkvqSHLnE8HwTmJHwjSv_zgaPCqG0Y

以下是详细的视频模拟(可以在浏览器中流式传输):

视频:  https://drive.google.com/open?id=1k4JBy9DShBKwQRswdz8Rxrb9wfvXXGmy

该视频是使用我能够创建的一些列表的屏幕截图制作的。然后将其编辑在一起,看起来就像是一个实际的工作脚本。

如视频所示,必须使用向上和向下箭头键浏览列表。按Enter键应打开所选类别的列表。然后,列表项本身也应该可以使用箭头键进行导航。

应该可以使用Backspace或向左箭头键(如视频中所示)返回到主要类别列表。

尽管,当不返回时,而是在一个列表项上按Enter键,然后脚本应将所选主要类别的索引号和实际所选项的索引号存储到两个临时变量中。使用这些变量,我必须执行进一步的操作。

这是我到目前为止所得到的。我只能为视频模拟创建列表。

#SingleInstance, Force

;GUi Layout
;-----------------------------------

Gui, +AlwaysOnTop

;Gui,+Delimiter
Gui, Add, ListBox, x20 y20 w180 r10 AltSubmit vList1 gSubit_All ,blue|red|green|yellow|
Gui, Add, ListBox, x+40 w200 r10 AltSubmit vList2 gSubit_All ,Item 1 of green|Item 2 of green|Item 3 of green|Item 4 of green|Item 5 of green|Item 6 of green|Item 7 of green|
Gui, Add, ListBox, x+40 w200 r10 AltSubmit vList3 gSubit_All ,Item 1 of blue|Item 2 of blue|Item 3 of blue|Item 4 of blue|Item 5 of blue|
Gui, Add, ListBox, x+40 w200 r10 AltSubmit vList4 gSubit_All ,
Gui, Show, x800 y150 w500 h200, Helper HS

return

对于动态加载表格的任何帮助,或者使用Enter键和向左箭头键浏览两个列表的任何帮助,都将受到赞赏。

1 个答案:

答案 0 :(得分:0)

关于从原始文件加载,这可能是一个问题。我无法找到有关AHK直接与Google表格进行交互的任何信息。如果可以将文件导出为CSV之类的文件,则可以使用FileRead从文件中读取内容,基本上可以执行任何操作。下面的示例使用您的文件,该文件以CSV格式导出到桌面。它使用第一行作为第一个列表,并将其余部分一起转储以用于第二个列表。

FileRead , sCSVRaw , %A_Desktop%/AHK list.csv
Loop , Parse , sCSVRaw , `n
{
    If A_Index = 1
    {
        sHeader := RegExReplace( A_LoopField , ",|`r" , "|" )
        Continue
    }
    sDataDump .= A_LoopField
}
sDataDump := StrReplace( sDataDump , "`r" , "," )

对于您问题的主要部分,我将使用OnMessage()功能让脚本监控某些按键,然后在检测到适当的按键后执行所需的操作。

OnMessage( 0x203 , "f_DblClick" ) ; Monitors left doubleclick
OnMessage( 0x100 , "f_KeyPress" ) ; Monitors keypresses (specifically, keyup events)

当我有机会时,我将添加一个可行的示例。 编辑:我有机会;你去了

aData := []
FileRead , sCSVRaw , %A_Desktop%/AHK list.csv
Loop , Parse , sCSVRaw , `n
{
    If A_Index = 1
    {
        sHeader := RegExReplace( A_LoopField , ",|`r" , "|" )
        Continue
    }
    ++nCt
    Loop , Parse , A_LoopField , `,
        aData[ A_Index , nCt ] := RegExReplace( A_LoopField , "`r" , "" )
}

Gui , +AlwaysOnTop
Gui , Add , ListBox , x20 y20 w180 r10 Choose1 vList1 AltSubmit gSubmit1 , %sHeader%
Gui , Add , ListBox , x+40 w200 r10 vList2 AltSubmit gSubmit2 ,
Gui , Show , x800 y150 w500 h200 , Helper HS

OnMessage( 0x100 , "f_KeyPress" )
Return

f_KeyPress( wP ) ; 37 = left, 39 = right, 13 = enter
{
    global bLeft := false , global bRight := false , global bEnter := false
    If ( wP = 37 )
        bLeft := true
    If ( wP = 39 )
        bRight := true
    If ( wP = 13 )
        bEnter := true
    If ( bLeft || bRight || bEnter )
        GoSub , sub_KeyPress
}

sub_KeyPress:
GuiControlGet , sFocus , FocusV
Gui , Submit , NoHide
If ( bLeft && sFocus = "List2" )
{
    List2 := ""
    GuiControl ,, List2 , |
    GuiControl , Focus , List1
}
If (( bRight || bEnter ) && sFocus = "List1" )
{
    sList2 := ""
    Loop , % nCt
        If !( aData[ List1 , A_Index ] = "")
            sList2 .= "|" . aData[ List1 , A_Index ]
    GuiControl ,, List2 , %sList2% 
    GuiControl , Focus , List2
    GuiControl , Choose , List2 , 1
}
If ( bEnter && sFocus = "List2" )
    MsgBox , List1: %List1%`nList2: %List2%
Return

Submit1:
If (( bLeft || bRight ) && List1 )
{
    bLeft := false , bRight := false
    GuiControl , Choose , List1 , %List1%
}
Return
Submit2:
If (( bLeft || bRight ) && List2 )
{
    bLeft := false , bRight := false
    GuiControl , Choose , List2 , %List2%
}
Return

事实证明,这比我预期的要长得多(也许有更好的方法?),但是它可以工作。如果您在执行代码时遇到麻烦,请告诉我,我将进行编辑并添加一些注释以进行解释。

此处显示旧代码以供参考和/或比较:

FileRead , sCSVRaw , %A_Desktop%/AHK list.csv
Loop , Parse , sCSVRaw , `n
{
    If A_Index = 1
    {
        sHeader := RegExReplace( A_LoopField , ",|`r" , "|" )
        Continue
    }
    sDataDump .= A_LoopField
}
sDataDump := StrReplace( sDataDump , "`r" , "," )

Gui , +AlwaysOnTop
Gui , Add , ListBox , x20 y20 w180 r10 Choose1 vList1 gSubmit1 , %sHeader%
Gui , Add , ListBox , x+40 w200 r10 vList2 AltSubmit gSubmit2 ,
Gui , Show , x800 y150 w500 h200 , Helper HS

OnMessage( 0x100 , "f_KeyPress" )
Return

f_KeyPress( wP ) ; 37 = left, 39 = right, 13 = enter
{
    global bLeft := false , global bRight := false , global bEnter := false
    If ( wP = 37 )
        bLeft := true
    If ( wP = 39 )
        bRight := true
    If ( wP = 13 )
        bEnter := true
    If ( bLeft || bRight || bEnter )
        GoSub , sub_KeyPress
}

sub_KeyPress:
GuiControlGet , sFocus , FocusV
Gui , Submit , NoHide
If ( bLeft && sFocus = "List2" )
{
    List2 := ""
    GuiControl ,, List2 , |
    GuiControl , Focus , List1
}
If (( bRight || bEnter ) && sFocus = "List1" )
{
    sList2 := ""
    Loop , Parse , sDataDump , `,
        If InStr( A_LoopField , Trim( List1 ))
            sList2 .= "|" . A_loopField
    GuiControl ,, List2 , %sList2% 
    GuiControl , Focus , List2
    GuiControl , Choose , List2 , 1
}
If ( bEnter && sFocus = "List2" )
{
    Loop , Parse , sHeader , "|"
        If ( A_LoopField = List1 )
            nList1Output := A_Index
    nList2Output := List2
    MsgBox , List1: %nList1Output%`nList2: %nList2Output%
}
Return

Submit1:
If (( bLeft || bRight ) && List1 )
{
    bLeft := false , bRight := false
    GuiControl , ChooseString , List1 , %List1%
}
Return
Submit2:
If (( bLeft || bRight ) && List2 )
{
    bLeft := false , bRight := false
    GuiControl , Choose , List2 , %List2%
}
Return