Тема: AHK: Активация скрипта по нескольким нажатием на клавишу
Здравствуйте. Как сделать так, чтобы, например, после трех нажатий на Numpad1 активируется скрипт?
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Здравствуйте. Как сделать так, чтобы, например, после трех нажатий на Numpad1 активируется скрипт?
Создать счётчик нажатий, если он достигнет числа 3 значит пропустить поток к нужным действиям и обнулить счётчик.
qqlexa можешь дать код этого счетчика?
Что должно активироваться? Другой скрипт или часть кода текущего?
__Михаил__ часть кода.
Morux2112
Читаем эту тему и настраиваем как нужно.
Morux2112
Можно так, но будет срабатывать даже если они не подряд нажаты.
Numpad1::
I++
If (I < 3)
Return
I =
GoSub, Metka
Return
Metka:
ToolTip, 3 нажатия запустили этот участок кода...
Sleep, 1000
ToolTip
Return
Вот так будет проверка, была ли клавиши нажата три раза подряд и сколько времени прошло с последнего нажатия:
Numpad1::
if !(A_ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 400)
counter := 1
else if ++counter = 3
goto, Label
Return
Label:
MsgBox, три нажатия
Return
teadrinker не работает почему-то
Попробуйте заменить Numpad1:: на sc4f::
Должно быть три быстрых нажатия одно за другим.
Вот тут разные варианты для многократных нажатий: AHK: Двойное нажатие клавиш F1-F12. В посте 11 там универсальный код для любого количества нажатий.
Вот тоже универсальный, попроще:
Numpad1::
if !(A_ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 400)
counter := 1
else
++counter
SetTimer, Label, -400
Return
Label:
MsgBox, %counter% нажатий
Return
Хитришь. У тебя хелло ворлд, а там полный код, только метки добавляй для нужного количества нажатий.
F11::
N:=0
Loop {
N++
KeyWait, %A_ThisHotkey%
KeyWait, %A_ThisHotkey%, D T0.3
} Until ErrorLevel
If N=1
Send, {%A_ThisHotkey%}
Else
Gosub % IsLabel(L := A_ThisHotkey . "_" . N) ? L : "NotCombo"
Return
NotCombo:
Return
F11_2:
MsgBox, Нажато 2 раза.
Return
F11_5:
MsgBox, Нажато 5 раз.
Return
F11_10:
MsgBox, Нажато 10 раз.
Return
А зачем метки добавлять? Можно в одной метке проверять количество нажатий (и если нужно A_ThisHotkey) и выполнять соответствующее действие.
Проще так, на мой взгляд. Ничего проверять не нужно, просто создаёшь нужную метку. В остальной код вообще не лезешь.
Ну, дело вкуса. По мне, так мой подход более простой, и главное, более наглядный. Потом через год на код посмотришь, и удивишься, что за странные названия — F_11_2, F11_5. Хорошим названием считается, когда оно отражает, что там внутри происходит.
F11_5 = F11 нажата 5 раз. А ниже код обработчика этого события. Куда уж нагляднее-то? И главное достоинство — общий для всех процедур код вообще не трогается. Ни при добавлении обработки нового многонажатия, ни даже при добавлении новых клавиш — просто добавляешь имена клавиш к F11 сверху и именуешь соответствующие процедуры по тому же единому шаблону. Минимум умственных усилий.
Ну сравни, чем хуже:
Numpad1::
if !(A_ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 400)
counter := 1
else
++counter
SetTimer, Label, -400
Return
Label:
if (counter = 1)
Run, notepad
if (counter = 2)
Run, wordpad
if (counter = 3) ; если что-то более сложное
DoSomething()
Return
Ну, хотя бы тем, что после запуска Блокнота зачем-то пойдут проверки на равенство двум, трём и т.д.
Ну, если такой дотошный, можно использовать что-то вроде этого:
Label:
switch counter
{
case 1: Run, notepad
case 2: Run, wordpad
}
Return
Так много чего можно использовать. Но какой смысл сравнивать по простоте полуфабрикат с полным кодом? Как твой код определяет, какая клавиша нажата? Никак.
Почему полным? В любом случае нужно что-то добавлять.
Я бы так написал:
Label:
if (A_ThisHotkey = "Numpad1") {
if (counter = 1)
Run, notepad
else if (counter = 2)
Run notepad++
}
else if (A_ThisHotkey = "Numpad2") {
if (counter = 1)
Run, wordpad
else if (counter = 2)
Run winword
}
Return
Вроде всё просто.
Ну, или разделил бы на отдельные метки, только по-другому:
Numpad1::
Numpad2::
if !(A_ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 400)
counter := 1
else
++counter
SetTimer, _%A_ThisHotkey%, -400
Return
_Numpad1:
if (counter = 1)
Run, notepad
else if (counter = 2)
Run notepad++
Return
_Numpad2:
if (counter = 1)
Run, wordpad
else if (counter = 2)
Run winword
Return
Ну вот видишь, ты пошёл в том же направлении. Только при более сложных действиях, чем запуск Блокнота, у тебя более громоздко будет выглядеть. Да и вообще действий больше. Пока дойдёшь до counter = 5, придётся проверить все предыдущие значения. У Irbis'a же этого нет. Там берутся как бы две координаты, F11 и 5, и выполнение прыгает сразу в определяемую ими точку. А у тебя прыжок к линии и перебор её точек, пока дойдёшь до нужной.
Переиграл и уничтожил)).
Только при более сложных действиях, чем запуск Блокнота, у тебя более громоздко будет выглядеть.
Почему, я просто вызову функцию с внятным названием.
И зачем заботиться о том, как скрипт перебирает варианты? Ресурсами, которые на это расходуются, можно пренебречь. Зато код проще и читабельней.
teadrinker спасибо, все работает.
Обращайтесь!
YMP
Вариант Irbis'а, кстати, не работает с хоткеями, у которых есть префикс. Понятно, что можно модифицировать, но это приведёт к дополнительному усложнению кода. Мой же работает «из коробки».
A_TimeSincePriorHotkey < 400
KeyWait, %A_ThisHotkey%, D T0.3
По-моему правильней брать время через GetDoubleClickTime, так-как пользователь привык к определению двойного щелчка у мышки.
Не знаю, по-моему нет особого смысла. Двойное нажатие клавиши скорее всего будет медленнее, чем двойной клик, тут лучше чуть побольше с запасом взять.
Ну это я по своим ощущениям сужу.
У меня двойной клик настроен на 500ms и для клавиатуры вариант с 300ms не всегда срабатывает.
А, я подумал, ты наоборот быстрее хочешь. Думаю, до секунды любое значение будет приемлемо.
Почему, я просто вызову функцию с внятным названием.
Т.е. добавишь ещё один слой кода. Три слоя же более громоздко, чем два.
И зачем заботиться о том, как скрипт перебирает варианты? Ресурсами, которые на это расходуются, можно пренебречь.
А как же красота кода? Элегантность/экономичность решения? Ты от этого радости не испытываешь? Кроме того, посеешь действие — пожнёшь привычку. Привычка пренебрегать ресурсами разве хорошая вещь? Начнёшь с малого, а потом у тебя скрипты будут весом в гигабайт и работать со скоростью черепахи.
Зато код проще и читабельней.
Это как посмотреть. Наткнёшься ты на эту функцию с внятным названием, а как она вызывается, тебе будет непонятно. Надо смотреть, искать. А у Irbis'a ничего искать не нужно. F11_5 — и всё ясно. А что делает код — так вот же он, перед глазами. Если длинный и запутанный, суть можно пояснить в комментарии возле метки. Но это потребуется только для запутанного кода. А если ты будешь в комментарии указывать, как вызывается функция, тебе все функции придётся откомментировать. Это же сложнее. Не намного, но ведь мы говорим о том, что сложнее, а не о том, насколько.
Вариант Irbis'а, кстати, не работает с хоткеями, у которых есть префикс.
Так это и не требуется. Многократное нажатие — альтернатива префиксам. Выгода в том, что задействуется одна рука. Я вот на F6 повесил 5 действий по регулировке яркости монитора. Т.е. на всех функциональных клавишах я мог бы иметь 60 действий. Зачем мне тут ещё префиксы?
Но главное достоинство варианта Irbis'a я уже выше упоминал. В идеале, добавление функционала в программу должно требовать добавления нового кода и НЕ требовать изменения старого. Думаю, всем понятно, почему это и удобнее, и безопаснее. Вариант Irbis'a этому условию удовлетворяет лучше. Ни в какой общий с чем-то ещё код лезть не нужно. Пишется только код обработчика конкретного числа нажатий, который ни на что больше гарантированно не повлияет. А у тебя кроме самой функции ещё нужно прописать в другом месте её вызов. Да, в данном случае это мелочь. Но опять вспоминается, что посеешь действие — пожнёшь привычку, и т.д. вплоть до судьбы. Не лучше ли сеять действия, из которых вырастают более правильные привычки?
А у тебя кроме самой функции ещё нужно прописать в другом месте её вызов. Да, в данном случае это мелочь. Но опять вспоминается, что посеешь действие — пожнёшь привычку, и т.д. вплоть до судьбы. Не лучше ли сеять действия, из которых вырастают более правильные привычки?
А я вот всегда слышал, что правильная привычка — это называть функции в соответствии с тем, что в них происходит. Представь, видишь тысячу строк кода, которые озаглавлены F_5. Выглядит, как минимум странно. Так что аргумент мимо.
В идеале, добавление функционала в программу должно требовать добавления нового кода и НЕ требовать изменения старого.
Так у меня и не меняется старый, просто добавляем ещё две строки в конец.
Так это и не требуется. Многократное нажатие — альтернатива префиксам.
Ну, если тебе не требуется, то это не значит, что не требуется никому. А как же пресловутое Ctrl + C + C? Да и вообще, делать подобный хоткей без префикса — отнимать у клавиши изначальную функциональность, так что требуется, и ещё как.
Наткнёшься ты на эту функцию с внятным названием, а как она вызывается, тебе будет непонятно.
Как раз наоборот, у меня предельно понятно — if (counter = 3).
А как же красота кода? Элегантность/экономичность решения?
Мне кажется мой код вполне красивым и элегантным. Я не переживаю из-за того, что скрипту нужно несколько раз сравнить переменную с простым числом, я же не параноик. Как и ты, видимо, не переживаешь, что вот здесь
Gosub % IsLabel(L := A_ThisHotkey . "_" . N) ? L : "NotCombo"
скрипту придётся сравнить созданную метку со всеми имеющимися. А так как в скрипте их скорее всего большое количество, это займет куда больше времени, чем моё перечисление вариантов.
Т.е. добавишь ещё один слой кода. Три слоя же более громоздко, чем два.
А разве не хорошая привычка разбивать код на логические блоки? Ты разве никогда не писал функцию, которая внутри вызывает другую?
Ну и последний, надеюсь, убийственный аргумент. Мою функцию очень легко видоизменить так, чтобы заработал алгоритм с вызовом подобных меток, при этом она всё ещё останется более читабельной и компактной, и с возможностью использовать клавиши с префиксами. Показывать надо?
Представь, видишь тысячу строк кода, которые озаглавлены F_5. Выглядит, как минимум странно. Так что аргумент мимо.
Тут ты мухлюешь. Не F_5, а F11_5. Функциональные клавиши все тыщу раз видели и мгновенно узнают. Так что аргумент мимо не у меня, а у тебя.
Так у меня и не меняется старый, просто добавляем ещё две строки в конец.
Этим добавлением ты меняешь уже существующую процедуру. А код Irbis'a ничего уже существующего не меняет. Я ведь написал, что в данном конкретном случае это мелочь, но в плане формирования правильных привычек это хуже.
Да и вообще, делать подобный хоткей без префикса — отнимать у клавиши изначальную функциональность, так что требуется, и ещё как.
Так это твой код её отнимает, а не Irbis'a.
Как раз наоборот, у меня предельно понятно — if (counter = 3).
Это у тебя имя функции такое будет? Я же о том, что по имени твоей функции ты не поймёшь, как она вызывается, а по F11_5 понять можно. Так что однобокая у тебя читабельность.
Как и ты, видимо, не переживаешь, что вот здесь скрипту придётся сравнить созданную метку со всеми имеющимися.
Это движку придётся их сравнивать, а не скрипту. Мы же про красоту нашего кода говорим, а не кода авторов AutoHotkey.
А разве не хорошая привычка разбивать код на логические блоки?
Так это же не даром даётся. Всё имеет свою цену, поэтому и надо взвешивать, выгода там в данном случае или убыток. И больше блоков — это же более сложная конструкция.
Ну и последний, надеюсь, убийственный аргумент.
Ты ещё не расстался с иллюзией, что они существуют?
Показывать надо?
Покажи, т.к. я не очень понял, что ты в виду имеешь.
Не F_5, а F11_5. Функциональные клавиши все тыщу раз видели и мгновенно узнают.
Это просто опечатка. Речь не о том, что не узнают название клавиши, а о том, что оно ничего не говорит о содержании нижележащего кода.
Так это твой код её отнимает, а не Irbis'a
Этого не понял, каким образом? Мой код может использовать как клавиши с префиксами, так и без них. На всякий случай напомню, что "префиксы" не то же самое, что "модификаторы".
Numpad1::
if !(A_ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 400)
counter := 1
else
++counter
SetTimer, Label, -400
Return
Label:
try goto %A_ThisHotkey%_%counter%
Return
Numpad1_2:
run notepad
Return
Речь не о том, что не узнают название клавиши, а о том, что оно ничего не говорит о содержании нижележащего кода.
Почему ничего? Мне в названии клавиши виден прозрачный намёк на обработку её нажатий. А что он делает, можно увидеть из кода, либо комментарий добавить, как я уже выше писал.
Этого не понял, каким образом?
Возможно, и я тебя не понял, но раньше твой код при одном нажатии вызывал Блокнот, а теперь ничего не делает, а код Irbis'a посылает саму клавишу.
А что он делает, можно увидеть из кода, либо комментарий добавить, как я уже выше писал.
Так разве это отменяет правило внятно называть функции? Не понимаю, о чём ты споришь.
раньше твой код при одном нажатии вызывал Блокнот, а теперь ничего не делает, а код Irbis'a посылает саму клавишу.
Ты можешь назначить любое действие для любого количества нажатий любых клавиш в том числе и с префиксами, в том числе можешь и отправить саму клавишу.
Надеюсь, ты не будешь доказывать, что менее универсальный, компактный и гибкий код лучше?
Так разве это отменяет правило внятно называть функции? Не понимаю, о чём ты споришь.
Я и не собирался его отменять. В свою очередь, не понимаю, о чём споришь ты.
Ты можешь назначить любое действие для любого количества нажатий любых клавиш в том числе и с префиксами, в том числе можешь и отправить саму клавишу.
Конечно, могу. Только что мы тогда сравнивали всю дорогу? То, что могу сделать я, с тем, что сделал Irbis? По-моему, нет. Чтобы сравнить два кода по простоте, нужно, чтобы они имели одинаковый функционал. Я думал, это очевидно. А ты упорно предлагаешь код с меньшим функционалом или вообще кусочки кода. Какой в этом смысл, мне не понятно.
Что касается кода выше, то ты его изменил, приблизив, так сказать, к моим идеалам, но почему-то называешь это убийственным аргументом. Что должен убить этот аргумент? Твоё утверждение, что лестница из if-else-if лучше, красивее и элегантнее? Тогда это самоубийственный аргумент получается.
Надеюсь, ты не будешь доказывать, что менее универсальный, компактный и гибкий код лучше?
А ты что, пытаешься доказать, что код, который я сам должен дописывать, лучше готового? Тогда лучше всего код, которого вообще нет. Он самый компактный, универсальный и гибкий, т.к. я там могу сам прописать всё, что душе угодно. Если ты об этом, то я с тобой согласен.
А ты упорно предлагаешь код с меньшим функционалом
По-моему, ты либо потерял нить, либо валяешь дурака.
что мы тогда сравнивали всю дорогу? То, что могу сделать я, с тем, что сделал Irbis?
Да нет же, всё это можно сделать с моим кодом, а с кодом Irbis'а не всё.
Мой код проще, логичнее, при этом он имеет больший (а не меньший) функционал, поскольку есть возможность использовать клавиши с префиксами. Кроме того, если тебе нравится называть метки F5_5, с ним ты можешь делать и это, как показано в этом посте. Ничего дописывать, кроме самих меток уже не нужно. При этом всё ещё можно использовать клавиши с префиксами. При этом можно использовать лестницу из if или if-else, если это кому-то нравится, а если не нравится, можно метки вида F5_5. Понял теперь немного, о чём я говорю?
Понял теперь немного, о чём я говорю?
Я понял, что ты меня так и не понял. По простоте можно сравнивать два кода, которые делают ровно то же самое. Если твой при этом проще — прекрасно. Если он делает всё то же самое и плюс ещё что-то, то ещё лучше. Но если он делает что-то ещё, но при этом не делает чего-то, что делает другой, то сравнение не будет корректным. Твоё предложение мне самому это дописать — бессмысленно. Если мне надо будет твой код использовать, я допишу, естественно, но в контексте этого спора это бредовое предложение. Ты мне предлагаешь доказывать твою точку зрения. Зачем мне это надо?
Твоё предложение мне самому это дописать — бессмысленно
Э-э-э... Да ты читал ли мой предыдущий пост?
Ничего дописывать, кроме самих меток уже не нужно.
Разве не то же самое ты делаешь со своим кодом?
Но если он делает что-то ещё, но при этом не делает чего-то, что делает другой, то сравнение не будет корректным.
Так а разве такое есть? Если да, то что именно?
Э-э-э... Да ты читал ли мой предыдущий пост?
А ты мой читал? Не имеет значения, как ты воспроизводишь в своём коде функционал другого кода. Метками или ещё как-то. Либо ты это делаешь, и тогда коды можно сравнить по простоте, либо не делаешь, и тогда нельзя. Ты в школе учился дроби сравнивать? Знаешь, зачем их приводят к одному знаменателю? Здесь та же логика.
Разве не то же самое ты делаешь со своим кодом?
При чём здесь мой код? Сравнение-то было твоего кода с кодом Irbis'a. Кстати, твой-то код, строго говоря, — это тот, что с if-else-if, а не с метками вида F11_5. Ты же за него бился. Признал своё поражение или как понимать твой отказ от этого варианта?
Так а разве такое есть? Если да, то что именно?
А что ты мне предлагаешь самому дописать?
Понял, валяешь дурака. Тогда оставляю тебя с этим наедине.
Блин, такая дискуссия началась вчера, но концовка что-то не очень. Требую больше кода и аргументов чей код более универсальный!
А зачем?
ИМХО спор ни о чем.
Каждый свой имеет вкус, у всех свои святыни
Петя любит есть арбуз, Катя любит дыни (с).
Блин, такая дискуссия началась вчера, но концовка что-то не очень.
Многие споры ни к чему не приводят в итоге. Но тут важно, как спор закончить. Можно сказать что-то вроде: "Остаюсь при своём мнении, но не вижу смысла дальше спорить. Предлагаю на этом закончить." Если оппонент вменяемый, то он соглашается и люди расходятся, сохраняя достоинство и уважение друг к другу. Ну или можно кинуть в оппонента какашку и убежать, как это сделал teadrinker.
Непонимание между людьми обычное дело. Так что надо уметь разруливать эту неприятную ситуацию цивилизованно.
YMP
Так а разве такое есть? Если да, то что именно?
А что ты мне предлагаешь самому дописать?
Просто ты отвечаешь на конкретные вопросы вопросами, да ещё такими, которые напоминают разговор с призраками в голове. Где я тебе что-то предлагал дописать? Почему просто на вопрос не ответить?
Если оппонент вменяемый
В смысле, я невменяемый? Ну с таким подходом вряд ли с тобой вообще кто-то станет разговаривать, тебя вроде никто не оскорблял.
Почему просто на вопрос не ответить?
Потому что ты спрашиваешь о том, о чём я уже говорил. Но эту тему я предлагаю закрыть. Она умерла и труп остыл уже.
В смысле, я невменяемый?
Это ты сам додумал. Я описал примерную ситуацию, где человек, желающий закончить спор (а это был как раз ты), делает это цивилизованно, обращаясь с предложением к оппоненту, а оппонент (в данном случае я), будучи вменяемым, соглашается. Суть в том, что спор кончается по взаимному согласию, а не так, что один просто уходит, потому что он так решил, а другой там как хочет. Да ешё обвиняет его в чём-то напоследок. В первом случае видим знак уважения, а во втором неуважения. Ну и никакого дурака я не валял, так что да, это прозвучало для меня оскорбительно.
Во время спора всякое бывает, но важно, чтобы это там и оставалось, а не выходило за его пределы. Этой цели и служит его цивилизованное завершение. Ты же предпочёл оставить конфликт открытым. Вот это я считаю неправильным. А думать о моих идеях насчёт правильного кода ты вправе всё, что хочешь. Я на контроль твоих мыслей не претендую.
Суть в том, что спор кончается по взаимному согласию
В смысле, я должен оппонировать аргументам типа
При чём здесь мой код? Сравнение-то было твоего кода с кодом Irbis'a.
до тех пор, пока ты не согласишься меня отпустить?
до тех пор, пока ты не согласишься меня отпустить?
Нет, конечно. Ты делаешь предложение закончить спор. Оппонент может и не считать его для себя утратившим смысл, но если он человек вменяемый, он проявит к тебе уважение и согласится его закончить. Если не согласится, значит не сильно вменяемый и можно просто уйти. К тебе уже никаких претензий быть не может.
А, ну я просто воспринимаю ситуацию, когда отвечают вопросом на вопрос, как предложение закончить спор, сори, наверно я был не прав.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться