কী-স্ট্রোক দিয়ে কীভাবে লুপটি মারবেন?


88

আমি সিরিয়াল ডেটা পড়ছি এবং কিছুক্ষণ লুপ ব্যবহার করে একটি সিএসভি ফাইলে লিখছি। আমি চাই যে ব্যবহারকারীরা পর্যাপ্ত ডেটা সংগ্রহ করার পরে তারা যখন লুপটি মারতে সক্ষম হবে।

while True:
    #do a bunch of serial stuff

    #if the user presses the 'esc' or 'return' key:
        break

আমি ওপেনসিভি ব্যবহার করে এরকম কিছু করেছি, তবে এটি এই অ্যাপ্লিকেশনটিতে কাজ করছে বলে মনে হয় না (এবং আমি সত্যিই কেবল এই ফাংশনটির জন্য ওপেনসিভি আমদানি করতে চাই না) ...

        # Listen for ESC or ENTER key
        c = cv.WaitKey(7) % 0x100
        if c == 27 or c == 10:
            break

তাই। আমি কীভাবে ব্যবহারকারীকে লুপটি ভেঙে দিতে পারি?

এছাড়াও, আমি কীবোর্ড বিঘ্নিত ব্যবহার করতে চাই না, কারণ লুপটি শেষ হওয়ার পরে স্ক্রিপ্টটি চালিয়ে যাওয়া দরকার।

উত্তর:


144

সবচেয়ে সহজ উপায় হ'ল এটি কেবল স্বাভাবিক Ctrl-C(সাইন ইন) দিয়ে বাধা দেওয়া ।

try:
    while True:
        do_something()
except KeyboardInterrupt:
    pass

যেহেতু উত্থাপিত হওয়ার Ctrl-Cকারণ তাই KeyboardInterruptকেবল এটি লুপের বাইরে ধরুন এবং এটিকে উপেক্ষা করুন।


4
@ ক্রিস: আপনি কেন চেষ্টা করে দেখুন না? (এবং তারপরে মন্তব্য করুন)
সাইলেন্টগোস্ট

এই ক্র্যাশগুলি (আমি ফিরে পেয়েছি ত্রুটির ট্রেস পেয়েছি) ^Cজারি করা হয় do_something()। আপনি কীভাবে এড়াতে পারবেন?
এটকোল্ড

আমার do_something()ইউএসবি থেকে কিছু মান পড়ে, তাই, ^Cআমি ভিতরে থাকাকালীন যদি জারি করা হয় তবে আমি do_something()কদর্য যোগাযোগের ত্রুটি পেয়েছি। পরিবর্তে, আমি যদি whileবাইরে থাকি তবে do_something()সমস্ত কিছু মসৃণ। সুতরাং, আমি কীভাবে এই পরিস্থিতিটি পরিচালনা করব তা ভাবছিলাম। আমি নিশ্চিত না যে আমি যথেষ্ট পরিমাণে নিজেকে পরিষ্কার করে দিয়েছি।
এটকোল্ড

@ অ্যাটকোল্ড তাই আপনার ব্যবহার করা একটি সংকলিত এক্সটেনশন মডিউল রয়েছে। এটি কোন ধরণের মডিউল? এটি কি একটি সাধারণ সি লাইব্রেরি মোড়ানো হচ্ছে?
কিথ

আমার কাছে একটি কল pyVISAএবং কল রয়েছে matplotlibযাতে আমার পরিমাপের লাইভ ভিজ্যুয়ালাইজেশন করতে পারি। এবং আমি মাঝে মাঝে ফানকি ত্রুটিগুলি পাই get আমি মনে করি আমার একটি পৃথক প্রশ্ন খোলার উচিত এবং আপনার উত্তর দূষিত করা বন্ধ করা উচিত ...
এটকোল্ড

36

এমন একটি সমাধান রয়েছে যার জন্য অ-মানক মডিউলগুলির প্রয়োজন নেই এবং এটি 100% পরিবহনযোগ্য

import thread

def input_thread(a_list):
    raw_input()
    a_list.append(True)

def do_stuff():
    a_list = []
    thread.start_new_thread(input_thread, (a_list,))
    while not a_list:
        stuff()

4
পাইথন 3+ ব্যবহারকারীদের জন্য কেবল একটি নোট: কাঁচা_পিন্ড () ইনপুট () এ নতুন নামকরণ করা হয়েছে, এবং থ্রেড মডিউলটি এখন থ্রেড।
Wieschie

পাইথন 3 তে ডাইথন 3 তে কাজ করেনি: "থ্রেডগুলি বিঘ্নের সাথে অদ্ভুতভাবে ইন্টারঅ্যাক্ট করে: কীবোর্ড ইন্টারটার্ট ব্যতিক্রম একটি স্বেচ্ছাচারিত থ্রেড দ্বারা প্রাপ্ত হবে ((সিগন্যাল মডিউলটি পাওয়া গেলে, বাধা সবসময় মূল থ্রেডে যায়))"
তৌহিদ

@ তোহিদ তবে এটি বাধা ব্যবহার করে না। এটি স্টিডিনের পড়া ব্যবহার করে।
আরটিয়ার

@ আর্টিয়ার যদি আমি ভুল না হয়ে থাকি তবে সমস্ত কীস্ট্রোক বাধা বাড়াতে, যেহেতু সেগুলি একটি হার্ডওয়্যার দ্বারা উত্থাপিত হয়। এই কোডটি কি আপনার জন্য কাজ করেছে এবং যদি তাই হয় তবে আপনি কোনও নির্দিষ্ট পরিবর্তন করেছেন?
তৌহিদ

4
@ তোহিদ কেবল thread-> _threadএবং raw_input-> input। লাইনটি খাওয়ানোর জন্য আপনাকে এন্টার টিপতে হবে। আপনি যদি কোনও কী করতে চান তবে গ্যাচ ব্যবহার করুন ।
আর্টিয়ার

14

নিম্নলিখিত কোডটি আমার পক্ষে কাজ করে। এটির জন্য ওপেনসিভি (আমদানি সিভি 2) প্রয়োজন।

কোডটি এমন একটি অসীম লুপের সমন্বয়ে গঠিত যা ক্রমাগত চাপা থাকা কীটির সন্ধান করছে। এই ক্ষেত্রে, যখন 'q' কী টিপানো হয়, প্রোগ্রামটি শেষ হয়। একটি ভেরিয়েবলের মান পরিবর্তন করতে বা কোনও ফাংশন সম্পাদন করার মতো বিভিন্ন ক্রিয়াকলাপ সম্পাদনের জন্য অন্যান্য কীগুলি (এই উদাহরণে 'বি' বা 'কে') চাপতে পারে।

import cv2

while True:
    k = cv2.waitKey(1) & 0xFF
    # press 'q' to exit
    if k == ord('q'):
        break
    elif k == ord('b'):
        # change a variable / do something ...
    elif k == ord('k'):
        # change a variable / do something ...

4
ভাল, তবে সিভি 2 খুব ভারী, যদি না আপনি ইতিমধ্যে এটি অন্য কোনও কিছুর জন্য ব্যবহার করছেন।
ogurets

4
কেন এবং 255 সহ
টেলস্পিন_কিট

@ টেলসপিন_কিট এবং 0 এক্সএফএফ "ভেরিয়েবলটি মাস্ক করে তাই এটি সর্বশেষ 8 টি বিটগুলিতে কেবলমাত্র মান রেখে যায় এবং বাকী সমস্ত বিট উপেক্ষা করে। মূলত এটি নিশ্চিত করে যে ফলাফলটি 0-255 এর মধ্যে হবে। দ্রষ্টব্য আমি কখনই ওপেনসিভিতে এটি করি না এবং জিনিসগুলি ভাল কাজ করে।
এরিক

7

পাইথন ৩.7-এর জন্য, আমি ব্যবহারকারী 297171 দ্বারা খুব সুন্দর উত্তর অনুলিপি করেছি এবং পরিবর্তন করেছি তাই এটি পরীক্ষিত পাইথন ৩.7-এর সমস্ত পরিস্থিতিতে কাজ করে।

import threading as th

keep_going = True
def key_capture_thread():
    global keep_going
    input()
    keep_going = False

def do_stuff():
    th.Thread(target=key_capture_thread, args=(), name='key_capture_thread', daemon=True).start()
    while keep_going:
        print('still going...')

do_stuff()

আমি জানি না আমি কিছু ভুল করছি বা কি করছে, তবে কীভাবে এই লুপটি থামানো যায় তা আমি বুঝতে পারি না? তুমি এটা কিভাবে করলে?
মিহকেল

@ মিহকেল আপনাকে <প্রবেশ> কী টিপতে হবে। এটি লুপটি প্রস্থান করবে।
রায়জিনজ

এটি শালীন, তবে প্রবেশ ছাড়া অন্য কীগুলিতে সাধারণীকরণ করে না।
জন ফোর্বস

পাইথন 2.7 এ আমার জন্য কাজ করে না তবে পাইথন 3 এ কাজ করে
crazjo

মাল্টিথ্রেডিং করা আমার মনে যা আছে তবে আমি উপরে @ কীথের উত্তরটি বেশ পছন্দ করি। সহজ এবং যথেষ্ট পরিষ্কার।
আসক্ত

4

পাইহুক সাহায্য করতে পারে। http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=PyHook_Tutorial#tocpyHook%5FTutorial4

কীবোর্ড হুক দেখুন; এটি আরও সাধারণীকরণ করা হয় - যদি আপনি নির্দিষ্ট কীবোর্ড ইন্টারঅ্যাকশন চান এবং কেবল কী-বোর্ড ইন্টারটার্প্ট ব্যবহার না করেন।

এছাড়াও, সাধারণভাবে (আপনার ব্যবহারের উপর নির্ভর করে) আমি মনে করি যে আপনার স্ক্রিপ্টটি মারার জন্য এখনও সিটিআরএল-সি বিকল্প উপলব্ধ থাকা অর্থপূর্ণ হয়ে উঠবে।

পূর্ববর্তী প্রশ্নটিও দেখুন: কীগুলি টিপানো হয় তা অজগরটিতে সনাক্ত করুন


1

সবসময় আছে sys.exit()

পাইথনের কোর লাইব্রেরিতে সিস্টেম লাইব্রেরিতে একটি প্রস্থান ফাংশন রয়েছে যা প্রোটোটাইপিংয়ের সময় খুব কার্যকর। কোডটি এই লাইনের সাথে থাকবে:

import sys

while True:
    selection = raw_input("U: Create User\nQ: Quit")
    if selection is "Q" or selection is "q":
        print("Quitting")
        sys.exit()
    if selection is "U" or selection is "u":
        print("User")
        #do_something()

অজগর 3 raw_inputএ প্রতিস্থাপন করা হয়েছেinput
তালহা আনোয়ার

1

আমি রাইজিনজ থেকে একটি নির্দিষ্ট কী দিয়ে স্ক্রিপ্টটি শেষ করতে উত্তরটি পরিবর্তন করেছি, এই ক্ষেত্রে এস্কেপ কীটি

import threading as th
import time
import keyboard

keep_going = True
def key_capture_thread():
    global keep_going
    a = keyboard.read_key()
    if a== "esc":
        keep_going = False


def do_stuff():
    th.Thread(target=key_capture_thread, args=(), name='key_capture_thread', daemon=True).start()
    i=0
    while keep_going:
        print('still going...')
        time.sleep(1)
        i=i+1
        print (i)
    print ("Schleife beendet")


do_stuff()

হ্যালো! এই কোডটি কীভাবে এবং কেন সমস্যার সমাধান করে তার ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে যদিও আপনার পোস্টের মান উন্নত করতে সত্যই সহায়তা করবে এবং সম্ভবত আরও বেশি ভোটের ফলাফল হবে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, কেবল এখনই জিজ্ঞাসা করা ব্যক্তি নয়। দয়া করে সম্পাদনা ব্যাখ্যা যোগ করতে পারেন এবং সীমাবদ্ধতা এবং অনুমানের কি প্রয়োগ একটি ইঙ্গিত দিতে আপনার উত্তর।
ব্রায়ান

1

খরগোশের গর্তের নীচে এই থ্রেডটি অনুসরণ করে, আমি এটিতে এসেছি, উইন 10 এবং উবুন্টু 20.04 এ কাজ করে। আমি কেবল স্ক্রিপ্টটি হত্যার চেয়ে বেশি, এবং নির্দিষ্ট কীগুলি ব্যবহার করতে চেয়েছিলাম এবং এটি এমএস এবং লিনাক্স উভয় ক্ষেত্রেই কাজ করতে হয়েছিল ..

import _thread
import time
import sys
import os

class _Getch:
    """Gets a single character from standard input.  Does not echo to the screen."""
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()

    def __call__(self): return self.impl()

class _GetchUnix:
    def __init__(self):
        import tty, sys

    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch

class _GetchWindows:
    def __init__(self):
        import msvcrt

    def __call__(self):
        import msvcrt
        msvcrt_char = msvcrt.getch()
        return msvcrt_char.decode("utf-8")

def input_thread(key_press_list):
    char = 'x'
    while char != 'q': #dont keep doing this after trying to quit, or 'stty sane' wont work
        time.sleep(0.05)
        getch = _Getch()
        char = getch.impl()
        pprint("getch: "+ str(char))
        key_press_list.append(char)

def quitScript():
    pprint("QUITTING...")
    time.sleep(0.2) #wait for the thread to die
    os.system('stty sane')
    sys.exit()

def pprint(string_to_print): #terminal is in raw mode so we need to append \r\n
    print(string_to_print, end="\r\n")

def main():
    key_press_list = []
    _thread.start_new_thread(input_thread, (key_press_list,))
    while True:
        #do your things here
        pprint("tick")
        time.sleep(0.5)

        if key_press_list == ['q']:
            key_press_list.clear()
            quitScript()

        elif key_press_list == ['j']:
            key_press_list.clear()
            pprint("knock knock..")

        elif key_press_list:
            key_press_list.clear()

main()

0

এটি পাইপ ইনস্টল পিনপুট সহ পিনপুট ইনস্টল করতে সহায়ক হতে পারে

from pynput.keyboard import Key, Listener
def on_release(key):
    if key == Key.esc:
        # Stop listener
        return False

# Collect events until released
while True:
    with Listener(
            on_release=on_release) as listener:
        listener.join()
    break 

0

থ্রেড এবং স্ট্যান্ডার্ড লাইব্রেরিগুলির সাথে আমি এটি সমাধানটি পেয়েছি

লুপটি একটি কী চাপ না দেওয়া অবধি চলতে থাকে,
একক অক্ষরের স্ট্রিং হিসাবে চাপানো কীটি

পাইথন ২.7 এবং 3 এ কাজ করে

import thread
import sys

def getch():
    import termios
    import sys, tty
    def _getch():
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(fd)
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch
    return _getch()

def input_thread(char):
    char.append(getch())

def do_stuff():
    char = []
    thread.start_new_thread(input_thread, (char,))
    i = 0
    while not char :
        i += 1

    print "i = " + str(i) + " char : " + str(char[0])

do_stuff()

-1
import keyboard

while True:
    print('please say yes')
    if keyboard.is_pressed('y'):
         break
print('i got u :) ')
print('i was trying to write you are a idiot ')
print('  :( ')

'ENTER' প্রবেশের জন্য

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.