python tty.setraw Ctrl + C不起作用(提取)

时间:2018-07-25 00:40:02

标签: python getch

这是我的代码。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

private List<Recipe> mRecipeDataSet;

public class ViewHolder extends RecyclerView.ViewHolder{


    protected CardView mCardView;
    protected TextView mTextView;

    public ViewHolder(View itemView) {
        super(itemView);

        mCardView = itemView.findViewById(R.id.recipe_cardview);
        mTextView = itemView.findViewById(R.id.id_of_recipe_item);
    }
}
@NonNull
@Override
public MyAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recipe_item, parent,false);
    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(@NonNull MyAdapter.ViewHolder holder, int position) {
        String id = mRecipeDataSet.get(position).getId();
        holder.mTextView.setText(id);

}

@Override
public int getItemCount() {
    return mRecipeDataSet.size();
}

public List<Recipe> setDataSet(List<Recipe> recipeList){
    return mRecipeDataSet;
}

public List<Recipe> getmRecipeDataSet() {
    return mRecipeDataSet;
}
}

在此代码中,KeyboardInterrupt异常不起作用。

谢谢

1 个答案:

答案 0 :(得分:5)

是的,当您将TTY设置为原始模式时,或者特别是在禁用termios设置ISIG时,您将不再得到相应的行为:

  ISIG   When any of the characters INTR, QUIT, SUSP, or DSUSP are
         received, generate the corresponding signal.

换句话说,大多数终端中的字符INTR(又名^C)不再产生is what Python uses to raise a KeyboardInterruptSIGINT信号。

这就是像emacs这样的全屏程序可以使用^C作为控制字符而不只是退出的方式。

因此,有两种选择:


不要调用setraw,而是设置所需的termios标志的确切集合,并确保不要禁用ISIG

值得一看的是Python tty.setraw的源代码,以确切地了解它的作用,并将其用作基准。

如果没有ISIG,您可以做完全相同的事情。但是,实际上,您应该阅读文档以了解这些内容的含义。

并确保在自己的系统上man termios,不要在线搜索;在Linux和macOS / * BSD上,情况有所不同,即使同一OS的版本之间也存在细微的差异。

即使在阅读了文档并进行了自己的实验之后,也可能并不完全清楚每种设置的效果。 This article似乎做得不错,可以解释进入原始模式的内容以及每个相关标志的实际含义(尽管我只是快速浏览了一下,而且,您仍然需要阅读man termios为您的平台)。


或者,您可以手动处理^C

您已经使用sys.stdin.read(1)一次读取一个字符,因此当有人按下^C时,您将要读取一个'\x03'字符。

发生这种情况时,您可以做任何想做的事情,包括raise KeyboardInterrupt


请注意,如果是Python 3,则可能需要以二进制模式阅读:

ch = sys.stdin.buffer.raw.read(1)
sys.stdin.flush()

(然后,您将检查b'\x03'而不是'\x03'。)

在文本模式下,即使它是UTF-8中的多字节字符(或任何语言环境),也应该一次获得一个完整字符。首先哪个看起来更简单-但这实际上可能会产生误导,因为单个字符仍然只能是按键的一部分。例如,在大多数终端上,向上箭头发送3个字符('\x1B[A', but read(1)`只会为您提供第一个字符。