Created
June 4, 2017 04:17
-
-
Save FingerLiu/771296462761b16ee6d685dc725eb0b4 to your computer and use it in GitHub Desktop.
curses 实现命令行聊天界面
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import curses, traceback, string | |
#-- Define the appearance of some interface elements | |
hotkey_attr = curses.A_BOLD | curses.A_UNDERLINE | |
menu_attr = curses.A_NORMAL | |
#-- Define additional constants | |
EXIT = 0 | |
CONTINUE = 1 | |
#-- Give screen module scope | |
screen = None | |
#-- Create the topbar menu | |
def topbar_menu(menus): | |
left = 2 | |
for menu in menus: | |
menu_name = menu[0] | |
menu_hotkey = menu_name[0] | |
menu_no_hot = menu_name[1:] | |
screen.addstr(1, left, menu_hotkey, hotkey_attr) | |
screen.addstr(1, left+1, menu_no_hot, menu_attr) | |
left = left + len(menu_name) + 3 | |
# Add key handlers for this hotkey | |
topbar_key_handler((string.upper(menu_hotkey), menu[1])) | |
topbar_key_handler((string.lower(menu_hotkey), menu[1])) | |
# Little aesthetic thing to display application title | |
screen.addstr(1, left+30, | |
" OC Curses Interface", | |
curses.A_STANDOUT) | |
screen.refresh() | |
#-- Magic key handler both loads and processes keys strokes | |
def topbar_key_handler(key_assign=None, key_dict={}): | |
if key_assign: | |
key_dict[ord(key_assign[0])] = key_assign[1] | |
else: | |
c = screen.getch() | |
if c in (curses.KEY_END, ord('!')): | |
return 0 | |
elif c not in key_dict.keys(): | |
curses.beep() | |
return 1 | |
else: | |
return eval(key_dict[c]) | |
def friends_view(): | |
s = curses.newwin(38, 30, 2, 1) | |
s.box() | |
s.addstr(1, 2, 'Friends', curses.A_BOLD) | |
s.addstr(3, 2, 'Jone Snow', curses.A_STANDOUT) | |
s.addstr(4, 2, 'Sansa', curses.A_NORMAL) | |
s.addstr(5, 2, 'Little Finger', curses.A_NORMAL) | |
s.addstr(6, 2, 'Lady Gaga', curses.A_NORMAL) | |
s.addstr(7, 2, 'Big Brother', curses.A_NORMAL) | |
s.refresh() | |
def message_view(): | |
s = curses.newwin(25, 89, 2, 31) | |
s.box() | |
s.addstr(1, 2, 'Message -- Jone Snow', curses.A_BOLD) | |
s.addstr(3, 2, 'I am the fire that burns against the cold, the light that', curses.A_NORMAL) | |
s.addstr(4, 2, 'brings the dawn, the horn that wakes the sleepers, the', curses.A_NORMAL) | |
s.addstr(5, 2, 'shield that guards the realms of men.', curses.A_NORMAL) | |
s.addstr(6, 2, 'I pledge my life and honor to the Night\'s Watch,', curses.A_NORMAL) | |
s.addstr(7, 2, 'for this night and all the nights to come.', curses.A_NORMAL) | |
s.refresh() | |
def input_view(): | |
s = curses.newwin(13, 89, 27, 31) | |
s.box() | |
s.addstr(1, 2, 'Type your message here...', curses.A_BOLD) | |
s.refresh() | |
# s.getch() | |
def oc_func(): | |
s = curses.newwin(6, 20, 2, 1) | |
s.box() | |
s.addstr(1, 2, "A", hotkey_attr) | |
s.addstr(1, 3, "bout OC", menu_attr) | |
s.addstr(2, 2, "P", hotkey_attr) | |
s.addstr(2, 3, "reference", menu_attr) | |
s.addstr(3, 2, "C", hotkey_attr) | |
s.addstr(3, 3, "hange account", menu_attr) | |
s.addstr(4, 2, "L", hotkey_attr) | |
s.addstr(4, 3, "og out", menu_attr) | |
s.refresh() | |
c = s.getch() | |
if c: | |
s.erase() | |
return CONTINUE | |
def edit_func(): | |
s = curses.newwin(6, 20, 2, 7) | |
s.box() | |
s.addstr(1, 2, "C", hotkey_attr) | |
s.addstr(1, 4, " Cut", menu_attr) | |
s.addstr(2, 2, "X", hotkey_attr) | |
s.addstr(2, 4, " Copy", menu_attr) | |
s.addstr(3, 2, "V", hotkey_attr) | |
s.addstr(3, 4, " Paste", menu_attr) | |
s.addstr(4, 2, "A", hotkey_attr) | |
s.addstr(4, 4, " Select All", menu_attr) | |
s.refresh() | |
c = s.getch() | |
if c: | |
s.erase() | |
return CONTINUE | |
def status_func(): | |
s = curses.newwin(6, 12, 2, 22) | |
s.box() | |
s.addstr(1, 2, "O", hotkey_attr) | |
s.addstr(1, 3, "line", menu_attr) | |
s.addstr(2, 2, "L", hotkey_attr) | |
s.addstr(2, 3, "eave", menu_attr) | |
s.addstr(3, 2, "I", hotkey_attr) | |
s.addstr(3, 3, "nvisible", menu_attr) | |
s.addstr(4, 2, "o", hotkey_attr) | |
s.addstr(4, 3, "ffline", menu_attr) | |
s.refresh() | |
c = s.getch() | |
if c: | |
s.erase() | |
return CONTINUE | |
def app_func(): | |
s = curses.newwin(6, 22, 2, 31) | |
s.box() | |
s.addstr(1, 2, "S", hotkey_attr) | |
s.addstr(1, 3, "creen Shot", menu_attr) | |
s.addstr(2, 2, "E", hotkey_attr) | |
s.addstr(2, 3, "moji Management", menu_attr) | |
s.addstr(3, 2, "M", hotkey_attr) | |
s.addstr(3, 3, "essage Management", menu_attr) | |
s.refresh() | |
c = s.getch() | |
if c: | |
s.erase() | |
return CONTINUE | |
def help_func(): | |
s = curses.newwin(30, 60, 5, 31) | |
s.box() | |
s.addstr(1, 16, "OC Client in Terminal V0.1", curses.A_UNDERLINE) | |
s.addstr(12, 10, "OC Client implemented in pure python.", menu_attr) | |
s.addstr(16, 10, "Use keyboard to navigate and chat!", menu_attr) | |
s.addstr(26, 26, "Copyright © Cloudist 2017", menu_attr | curses.A_RIGHT) | |
s.refresh() | |
c = s.getch() | |
if c: | |
s.erase() | |
return CONTINUE | |
def main(stdscr): | |
global screen | |
screen = stdscr.subwin(41, 121, 0, 0) | |
screen.box() | |
screen.hline(2, 1, curses.ACS_HLINE, 77) | |
screen.refresh() | |
# Define the topbar menus | |
oc_menu = ("OC", "oc_func()") | |
edit_menu = ("Content Edit", "edit_func()") | |
status_menu = ("Status", "status_func()") | |
app_menu = ("Application", "app_func()") | |
help_menu = ("Help", "help_func()") | |
exit_menu = ("Exit", "EXIT") | |
# Add the topbar menus to screen object | |
topbar_menu(( | |
oc_menu, edit_menu, status_menu, | |
app_menu, help_menu, exit_menu | |
)) | |
friends_view() | |
message_view() | |
input_view() | |
while topbar_key_handler(): | |
friends_view() | |
message_view() | |
input_view() | |
if __name__ == '__main__': | |
try: | |
# Initialize curses | |
stdscr = curses.initscr() | |
#curses.start_color() | |
# Turn off echoing of keys, and enter cbreak mode, | |
# where no buffering is performed on keyboard input | |
curses.noecho() | |
curses.cbreak() | |
# In keypad mode, escape sequences for special keys | |
# (like the cursor keys) will be interpreted and | |
# a special value like curses.KEY_LEFT will be returned | |
stdscr.keypad(1) | |
main(stdscr) # Enter the main loop | |
# Set everything back to normal | |
stdscr.keypad(0) | |
curses.echo() | |
curses.nocbreak() | |
curses.endwin() # Terminate curses | |
except: | |
# In the event of an error, restore the terminal | |
# to a sane state. | |
stdscr.keypad(0) | |
curses.echo() | |
curses.nocbreak() | |
curses.endwin() | |
traceback.print_exc() # Print the exception |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment