`
winzenghua
  • 浏览: 1369973 次
  • 性别: Icon_minigender_2
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

使用curses管理基于文本的屏幕--(五)

阅读更多

子窗体

现在我们已经探讨了多窗体,现在我们可以来看一下一类特殊的多窗体,名为子窗体。我们可以用下面的函数调用来创建和销毁子窗体:

#include <curses.h>
WINDOW *subwin(WINDOW *parent, int num_of_lines, int num_of_cols,
int start_y, int start_x);
int delwin(WINDOW *window_to_delete);

subwin函数具有与newwin几乎相同的参数列表,而子窗体的删除方式也与其他的窗体使用一个delwin调用方式相同。与新窗体类似,我们可以使用一系列的mvw函数将数据写入子窗体中。确实如此,绝大多数时候,子窗体的行为与新窗体非常类似,但是却有一点重要的区别:子窗体本身并不会存储一个单独的屏幕字符集,他们与子窗体创建时所指定的父窗体共享存储空间。这就意味着子窗体中的任何改动也同时会发生在底层的父窗体中,所以当一个子窗体被删除时,屏幕并不会发生变化。

第一眼感觉,子窗体似乎意义不大。为什么不直接将会变化发送给父窗体呢?子窗体的主要用途就是要提供一个更为简洁的方法来在另一个窗体中滚动部分内容。当编写一个curses程序时,滚动屏幕一部分的需要是十分常见的。通过使用子窗体以及滚动子窗体,我们可以达到这个目的。

使用子窗体的一个严格限制就是程序在刷新屏幕之前应调用touchwin函数。

试验--子窗体

1 首先,subscl.c的初始化代码部分使用一些文本初始化基窗体。

#include <unistd.h>
#include <stdlib.h>
#include <curses.h>
int main()
{
WINDOW *sub_window_ptr;
int x_loop;
int y_loop;
int counter;
char a_letter = ‘1’;
initscr();
for (x_loop = 0; x_loop < COLS - 1; x_loop++) {
for(y_loop=0;y_loop<LINES-1;y_loop++) {
mvwaddch(stdscr,y_loop,x_loop,a_letter);
a_letter++;
if(a_letter > '9') a_letter = '1';
}
} if (a_letter > 'Z') a_letter = 'A';

2 我们现在创建滚动子窗体,正如我们所建议的那样,我们必须在刷新屏幕之前"touch"父窗体。

sub_window_ptr = subwin(stdscr, 10, 20, 10, 10);
scrollok(sub_window_ptr, 1);
touchwin(stdscr);
refresh();
sleep(1);

3 然后我们创建子窗体的内容,向其中输入文本。滚动文本是通过一个循环来完成的。

werase(sub_window_ptr);
mvwprintw(sub_window_ptr, 2, 0, “%s”, “This window will now scroll”);
wrefresh(sub_window_ptr);
sleep(1);
for (counter = 1; counter < 10; counter++) {
wprintw(sub_window_ptr, “%s”, “This text is both wrapping and \
scrolling.”);
wrefresh(sub_window_ptr);
sleep(1);
}

4 在完成这个循环之后,我们删除子窗体。然后刷新基屏幕。

delwin(sub_window_ptr);
touchwin(stdscr);
refresh();
sleep(1);
  endwin();
exit(EXIT_SUCCESS);
}

工作原理

在将sub_window_ptr指向subwin的调用结果之后,我们就将子窗体变得可以滚动了。甚至是在子窗体被删除而基窗体(strdcr)已经刷新之后,屏幕上的文本仍然保持原样。这是因为子窗体实际更新的是stdscr的字符数据。

键区

在前面的讨论中我们已经看到了curses所提供的一些实用功能来处理键盘。许多键盘至少具有光标键与功能键。许多键盘还有键区和其他的键,例如Insert和Home。

在大多数的终端上解码这些按键是一个非常困难的事情,因为通常他们会发送一个以转义字符开始的字符串。这些程序所具有的不仅是单击Escape键和由按下一个功能键所引起的字符串之间区别的问题,而且他必须使用相同逻辑按键的不同序列来处理不同的终端。

幸运的是,curses提供了一个优雅的实用功能来管理这些功能按键。对于每一个终端,每一个功能键所发送的字符序列都会被存储,通常是存储在一个terminfo结构中,而所包含的头文件curses.h具有一个以KEY_为前缀的定义部分定义了逻辑按键。

当curses启动时,序列与逻辑按键之间的转换就被禁止了,而且必须使用keypad函数来打开。如果函数调用成功则会返回OK,否则返回ERR。

#include <curses.h>
int keypad(WINDOW *window_ptr, bool keypad_on);

一旦keypad模式通过将keypad_on参数设置为真打开后,curses就会接管按键的处理,从而读取键盘不仅会返回所按下的键,而且会返回逻辑按键的KEY_定义。

使用keypad模式时需要注意下面的三个限制:

转义序列的识别是时间相关的,而许多的网络协议会将字符组装到数所包中(会导致不能正确的识别转义序列),或者是分割他们(从而会导致功能按键序列会被识别为Escape与单个的字符)。这种情况在WAN或是其他繁忙的链接上是最糟糕的。唯一的解决办法就是进行编程使用信号来我们希望使用的每一个功能按键发送单一的,唯一的字符。
为了使得curses可以区分按下Escape与以Escape开头的键盘序列,他必须等待一小段时间。有时,一旦打开了keypad模式,Escape按键处理上的一个非常小的延时也会被注意到。
curses不能处理不唯一的转义序列。如果我们的终端有可以发送相同序列的两个不同的按键,curses只是简单的不处理这个序列,因为他不能确定应返回哪一个逻辑按键。

试验--使用Keypad

下面所显示的是一个简短的程序,keypad.c,演示了如何使用keypad模式。当我们运行这个程序时,试着按下Escape并且要注意到当程序等待以确定Escape是一个序列的开始还是单一的一个按键时的小段延时。

1 初始化程序与curses库,我们将keypad模式设置TRUE。

#include <unistd.h>
#include <stdlib.h>
#include <curses.h>
#define LOCAL_ESCAPE_KEY 27
int main()
{
int key;
initscr();
crmode();
keypad(stdscr, TRUE);

2 接下来我们必须关闭echo以及防止当光标键按下时光标进行移动。清除屏幕并显示一些文本。程序会等待每一次击键,除非他是Q,或是产生了一个错误,此时按键会被打印出来。如果击键匹配一个终端的keypad序列,那么就会打印这个序列。

noecho();
clear();
mvprintw(5, 5, “Key pad demonstration. Press ‘q’ to quit”);
move(7, 5);
refresh();
key = getch();
while(key != ERR && key != ‘q’) {
move(7, 5);
clrtoeol();
if ((key >= ‘A’ && key <= ‘Z’) ||
(key >= ‘a’ && key <= ‘z’)) {
printw(“Key was %c”, (char)key);
}
else {
switch(key) {
case LOCAL_ESCAPE_KEY: printw(“%s”, “Escape key”); break;
case KEY_END: printw(“%s”, “END key”); break;
case KEY_BEG: printw(“%s”, “BEGINNING key”); break;
case KEY_RIGHT: printw(“%s”, “RIGHT key”); break;
case KEY_LEFT: printw(“%s”, “LEFT key”); break;
case KEY_UP: printw(“%s”, “UP key”); break;
case KEY_DOWN: printw(“%s”, “DOWN key”); break;
default: printw(“Unmatched - %d”, key); break;
} /* switch */
} /* else */
refresh();
key = getch();
} /* while */
endwin();
exit(EXIT_SUCCESS);
}

分享到:
评论

相关推荐

    使用curses管理基于文本的屏幕

    ### 使用curses管理基于文本的屏幕 #### 一、curses简介 curses是一个用于创建基于文本的用户界面的库,它在Linux和类UNIX环境中非常流行。curses的重要性在于它提供了一个介于简单的基于行的程序和复杂的图形界面...

    Linux程序设计 第6章 使用curses函数库管理基于文本的屏幕

    即使是编写基于字符的全屏幕程序,使用curses函数库的方案也更简明,而程序本身也更独立于具体的终端。在编写这类程序时,使用curses函数库更比直接使用escape转义序列容易得多。curses函数库还可以对键盘进行管理,...

    python的curses库, win平台的各种whl包

    - 它提供了高级的文本输出和输入功能,比如分割屏幕、创建窗口、接受用户输入等,适合创建基于命令行的图形化界面。 - 在Windows系统上,curses库通常通过pdcurses或win32curses这样的移植版本来实现。 2. **whl...

    python_curses-2.2.2-cp312-cp312-win32.whl.zip

    **Python Curses**库是Python对原始C语言的`curses`库的封装,它提供了一套API,使得在基于文本的终端上创建图形用户界面成为可能。`curses`库可以处理键盘输入、屏幕输出和窗口管理,常用于控制台应用,如命令行...

    C语言学生成绩管理系统:使用curses函数库--源码

    curses库是用于处理文本模式用户界面的工具,特别是在没有图形窗口系统的情况下,它能够方便地在终端上进行屏幕管理和输入处理。通过使用curses,开发者可以更容易地控制屏幕输出和键盘输入,使得在命令行环境下也能...

    curses-2.2.1+utf8-cp37,py学习2048所需模块

    在Python编程领域,curses库是一个至关重要的工具,尤其在开发基于终端的用户界面时。curses库源于C语言,但在Python中被广泛使用,因为它允许开发者创建全屏交互式的应用程序,使得在命令行界面下的用户体验得以...

    Python-使用pythoncurses库创建的基于文本的多人游戏

    通过对这些文件的分析和学习,我们可以更深入地理解如何使用`curses`库来开发一个基于文本的多人游戏。这个项目可能包括了游戏规则、角色移动、碰撞检测、用户输入处理以及网络通信等方面的具体实现,这些都是游戏...

    python_curses-2.2.2-cp311-cp311-win_amd64.whl.zip

    在实际应用中,Python的curses库提供了许多函数和类,如`initscr()`用于初始化屏幕,`getch()`用于接收用户输入,`printw()`用于在屏幕上打印文本,以及`color_pair()`和`attron()`等用于设置颜色和文本属性。...

    python_curses-2.2.2-cp39-cp39-win32.whl.zip

    Python的curses库是用于创建基于终端的交互式应用程序的模块,它允许程序员在文本模式下处理用户输入和显示复杂的屏幕布局。`python_curses-2.2.2-cp39-cp39-win32.whl` 是一个专门为Python 3.9版本编译的curses库的...

    python_curses-2.2.2-cp311-cp311-win_arm64.whl.zip

    它能够管理屏幕上的窗口,处理键盘输入,以及更新屏幕内容,使得开发基于终端的应用程序变得更加简单。`curses`库的使用主要分为以下几个核心概念: 1. **窗口管理**:curses将屏幕划分为多个窗口,每个窗口可以...

    python_curses-2.2.2-cp39-cp39-win_amd64.whl.zip

    Python的curses库是一个在控制台上提供彩色和光标移动功能的模块,它使得开发者能够创建基于文本的用户界面。`python_curses-2.2.2-cp39-cp39-win_amd64.whl` 文件是这个库的一个预编译版本,专为Python 3.9构建,...

    PyCurses-使用python编写curses.pdf

    调试PyCurses程序通常涉及输出日志、使用调试器或专门的curses调试工具,以便跟踪屏幕更新和键盘事件。 总之,PyCurses为Python开发者提供了一个强大且灵活的工具,用于创建功能丰富的控制台应用程序,无论是在历史...

    817-0693-pdfOracle Solaris 9 - man pages section 3: Curses Libra

    curses.h 头文件定义了 Curses 库的 API,提供了各种函数和宏,用于创建和管理基于文本的用户界面。curses 库是 Curses 库的核心部分,提供了各种函数,用于创建和管理基于文本的用户界面。form 库是 Curses 库的一...

    Unix Curses 库导论-翻译版

    Curses 提供了一系列 API 来处理文本屏幕的操作: - `initscr`: 初始化 curses 模式 - `printw`: 在屏幕指定位置打印字符串 - `getch`: 获取用户按键 - `endwin`: 结束 curses 模式 ##### 6.3 属性 除了 API 外,...

    基于curses的简单弹球游戏

    1. **curses**:curses库是此项目的核心,它提供了一系列函数,用于管理屏幕上的文本布局、颜色、键盘输入处理等功能。在curses模式下,程序可以动态地更新屏幕,创建窗口、面板,并响应用户的按键事件,使得在字符...

    Curses-1.28.tgz

    Curses 是一个在文本模式下运行的库,用于创建基于终端的应用程序。它提供了一组高级函数,使得程序员可以方便地处理终端的显示、输入和颜色等特性,而无需关心底层的终端控制代码。Curses-1.28.tgz 是这个库的一个...

    Linux命令行终端图形界面编程库curses介绍

    - **文本编辑器**:如vim、nano等命令行编辑器,这些编辑器的界面都是基于curses构建的。 - **游戏开发**:如经典的《roguelike》游戏,这类游戏通常需要在有限的空间内展示大量信息。 - **脚本自动化**:编写用于...

    linux下使用curses库实现滚屏、彩色打印等个性化屏幕输出

    【curses库】是UNIX环境下用于处理终端交互的高级库,尤其适合开发基于文本界面的程序。它使得程序员能够方便地控制光标移动、屏幕显示和键盘输入,从而实现滚屏、彩色打印等功能,适用于各种不同类型的终端。curses...

    linux curses编程小游戏 源码

    Linux下的curses编程是一种在基于文本的终端上创建交互式用户界面的技术,它允许程序员创建动态更新的屏幕,类似于简单的图形界面。在这个“魔岛寻宝”游戏中,curses库被用来控制屏幕上的字符输出、读取用户输入,...

    Tutorial on Python Curses Programming

    尽管现在图形用户界面已经成为主流,但基于文本的用户界面仍然有着广泛的应用场景。在服务器管理、控制台应用开发等领域,curses 提供了一个强大的工具集来创建复杂的文本界面。此外,学习 curses 也有助于深入理解...

Global site tag (gtag.js) - Google Analytics