ncurse界面编程多线程示例

本文介绍了一个使用ncurses库在Linux环境下实现动态字符串数组显示的C++程序示例。通过设置不同的参数,可以实现字符串的左右跳动效果,并提供了简单的命令交互功能,如退出程序、全屏反向显示、指定某行字符反向显示等。程序包含编译、运行方式说明及使用示例,适合初学者了解ncurses库的基本应用。

linux ncurses界面编程网上资料很多,这里不再详述,这里只给一个例子。该示例给出了一个左右跳动的字符串数组景象:

//Compile: gcc -g ncurses_demo.c -o ncurses_demo -lpthread -lncurses
//Run: ./ncureses_demo 1 2 3 4 5 6 7 8 9 0
//Usage: q  quit, 空白 全部反向, 0-9, 指定某行字符反向显示
//

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <pthread.h>
#include <unistd.h>

#define MAXMSG 10	 //最多允许用户输入的字符串个数,超过的部分会忽略, 也是创建的线程数
#define TUNIT 20000  //usleep函数休眠的时间因子

struct propset
{
	char *str; //显示的字符串
	int row;   //行数, 一个线程对应一行
	int delay; //超时时间
	int dir;   //方向, 向左或是向右
};

int setup (int, char **, struct propset *);
void *animate (void *arg);

pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;

int main (int argc, char *argv[])
{
	int c;
	pthread_t thrds[MAXMSG];
	struct propset props[MAXMSG];
	int num_msg;
	int i;
	if (argc == 1)
	{
		printf ("usage:%s string ...\n", argv[0]);
		exit (1);
	}
	num_msg = setup (argc - 1, argv + 1, props);
	for (i = 0; i < num_msg; i++)
	{							//用户输入几个字符串就创建几个线程
		if (pthread_create (&thrds[i], NULL, animate, &props[i]))
		{						//若成功创建线程会返回0
			fprintf (stderr, "error creating thread");
			endwin ();
			exit (0);
		}
	}
	while (1)
	{
		c = getch ();
		if (c == 'Q' || c == 'q')
			break;				//退出
		if (c == ' ')
		{						//全部反向
			for (i = 0; i < num_msg; i++)
				props[i].dir = -props[i].dir;
		}
		if (c >= '0' && c <= '9')
		{						//指定某个字符串反向
			i = c - '0';
			if (i < num_msg)
				props[i].dir = -props[i].dir;
		}
	}
	pthread_mutex_lock (&mx);	//上锁,然后取消所有的线程
	for (i = 0; i < num_msg; i++)
		pthread_cancel (thrds[i]);
	endwin ();
	return 0;
}

int setup (int nstring, char *strings[], struct propset props[])
{
	int num_msg = (nstring > MAXMSG ? MAXMSG : nstring); //限制输入的字符串最大个数, 这里是10个
	int i;
	srand (getpid ());
	for (i = 0; i < num_msg; i++)
	{
		props[i].str = strings[i];
		props[i].row = i;
		props[i].delay = 1 + (rand () % 15);
		props[i].dir = ((rand () % 2) ? 1 : -1);
	}
	initscr ();
	crmode ();
	noecho ();
	clear ();
	mvprintw (LINES - 1, 0, "'Q' to quit,'0'..'%d' to bounce", num_msg - 1);	//在屏幕底端打印字条串
	return num_msg;
}

void *animate (void *arg)
{
	struct propset *info = arg;
	int len = strlen (info->str) + 2;	//+2 for padding
	int col = rand () % (COLS - len - 3);
	while (1)
	{
		usleep (info->delay * TUNIT);
		pthread_mutex_lock (&mx);
		move (info->row, col);
		addch (' ');
		addstr (info->str);
		addch (' ');
		move (LINES - 1, COLS - 1);
		refresh ();
		pthread_mutex_unlock (&mx);
		col += info->dir;
		if (col <= 0 && info->dir == -1)
			info->dir = 1;
		else if (col + len >= COLS && info->dir == 1)
			info->dir = -1;
	}
}

用法如下:

./ncurese_demo  1 2 3 4 5 6 7 8 9 0

q  退出, 空白键 全部反向, 0-9之一  指定某行字符反向显示

运行截图


参考文献

[1].http://www.kuqin.com/cpluspluslib/20111226/316716.html

[2].http://www.cnblogs.com/Xiao_bird/archive/2009/07/21/1527947.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值