list - AHK 多维列表可使用箭头键和 Enter 导航
问题描述
在 AHK (Autohotkey) 中,我需要从一个表中加载一个列表,该表具有主要类别和每个单独的条目。
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 或 Arrow Left 键返回主类别列表(如视频中所示)。
虽然,当不返回,而是在一个列表项上按 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 键和左箭头键在两个列表中导航将不胜感激。
解决方案
关于从原始文件加载,这可能是一个问题。我找不到任何关于 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
推荐阅读
- intellij-15 - 在 IntelliJ 终端中运行 java 程序
- nativescript - 使用 aws sns 的 nativescript 推送通知
- kubernetes - 使用 mod_auth_openidc 会话 SSO 到 kubernetes
- mysql - Mysql排序顺序日期0000-00-00第一
- android - 升级颤振后创建方法通道 - 无法解析方法 getFlutterView()
- javascript - 单击功能在具有相同类名的元素上执行多次
- python - 二维列表中元素的平均值
- c# - 当工作表在 EPPlus 中有按钮时无法复制工作表?
- javascript - onload 元素的函数调用量是否有限
- c# - 为什么我的文本框没有更新我的 WPF 按钮命令的 CanExecute 值?