كيفية الحصول على حرف واحد دون الضغط على زر الإدخال؟

StackOverflow https://stackoverflow.com/questions/174933

  •  05-07-2019
  •  | 
  •  

سؤال

كيف يمكنني الحصول على حرف لوحة مفاتيح واحد من الجهاز باستخدام Ruby دون الضغط على زر الإدخال؟حاولت Curses::getch, ، لكن هذا لم ينجح حقًا بالنسبة لي.

هل كانت مفيدة؟

المحلول

HTTP: //blade.nagaokaut. ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/2999

#!/usr/bin/ruby

begin
  system("stty raw -echo")
  str = STDIN.getc
ensure
  system("stty -raw echo")
end
p str.chr

و(اختبار على نظام بلدي X OS، قد لا تكون محمولة على جميع المنابر روبي). انظر http://www.rubyquiz.com/quiz5.html للحصول على بعض الاقتراحات الإضافية، بما في ذلك النوافذ.

نصائح أخرى

ومنذ روبي 2.0.0، هناك "الإعلام والتوعية / وحدة التحكم" في stdlib مع هذه الميزة

require 'io/console'
STDIN.getch

أعطى @Jay إجابة رائعة، ولكن هناك مشكلتان:

  1. يمكنك إفساد حالة tty الافتراضية؛
  2. أنت تتجاهل أحرف التحكم (^C لـ SIGINT، وما إلى ذلك).

الحل البسيط لذلك هو حفظ حالة tty السابقة واستخدام المعلمات التالية:

  • -icanon - تعطيل الإدخال المتعارف عليه (معالجة المسح والقتل)؛
  • isig - تمكين التحقق من الأحرف مقابل أحرف التحكم الخاصة INTR وQUIT وSUSP.

في النهاية سيكون لديك وظيفة مثل هذا:

def get_char
  state = `stty -g`
  `stty raw -echo -icanon isig`

  STDIN.getc.chr
ensure
  `stty #{state}`
end

ووضع الأولية (stty raw -echo) يسبب سوء الحظ السيطرة-C للحصول أرسلت في كحرف، وليس بوصفه SIGINT. حتى إذا كنت تريد منع إدخال مثل أعلاه، ولكن تسمح للمستخدم لضرب تحكم-C لوقف البرنامج في حين انها تنتظر، تأكد للقيام بذلك:

Signal.trap("INT") do # SIGINT = control-C
  exit
end

وإذا كنت تريد غير مؤمن الإدخال - وهذا هو، تحقق بشكل دوري إذا قام المستخدم الضغط على مفتاح، ولكن في هذه الأثناء، تذهب تفعل أشياء أخرى - ثم يمكنك القيام بذلك:

require 'io/wait'

def char_if_pressed
  begin
    system("stty raw -echo") # turn raw input on
    c = nil
    if $stdin.ready?
      c = $stdin.getc
    end
    c.chr if c
  ensure
    system "stty -raw echo" # turn raw input off
  end
end

while true
  c = char_if_pressed
  puts "[#{c}]" if c
  sleep 1
  puts "tick"
end

ملحوظة أنك لا تحتاج إلى معالج SIGINT خاص لغير مؤمن نسخة منذ TTY هو فقط في وضع الخام للحظة وجيزة.

ملاحظة: هذا هو الجواب والقديمة والحل لم يعد يعمل على معظم أنظمة

.

ولكن الجواب يمكن أن يكون مفيدا لبعض البيئات، حيث لا تعمل الطرق الأخرى. يرجى قراءة التعليقات أدناه.


وأول لديك لتثبيت HIGHLINE:

gem install highline

وإذا ثم حاول يعمل الأسلوب HIGHLINE لك:

require "highline/system_extensions"
include HighLine::SystemExtensions

print "Press any key:"
k = get_character
puts k.chr

وإذا كنت بناء اللعنات التطبيق، تحتاج إلى الاتصال

nocbreak

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/curses/rdoc/Curses.html#method-c-cbreak

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top