在curses,Python中打印线程函数

时间:2017-11-16 22:47:44

标签: python python-multithreading ncurses curses

在我的项目中,我必须在控制台上打印存储在数据库中的一些数据。我有两个返回字符串的函数。我应该将这些数据打印在两列中。 我想在python中使用模块curses来创建这两列。 到目前为止一切都很好。 另一件事是,我的两个函数使用threading.Timer。因此,生成的字符串每10秒更改一次,例如,如果我将Timer设置为10。 因此,当我将函数的结果放在列的addstr()上时,它会正确打印第一个String,但即使我的字符串发生更改,也没有任何更改。否则当我调整控制台的大小时,我注意到字符串发生了变化。 这是我的代码:

import sys,os
import curses , curses.panel 
import datetime
import time
import threading



def time_func():
    printStr = threading.Timer(10,time_func)
    printStr.start()
    s = "Simple example that display datetime \n" + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") 
    return s 

def draw_menu():


    k = 0
    cursor_x = 0
    cursor_y = 0


    # Clear and refresh the screen
    stdscr = curses.initscr()
    stdscr.clear()
    stdscr.refresh()

    # Initialize colors in curses
    curses.start_color()
    curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK)
    curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
    curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_WHITE)
    curses.curs_set(0)
    # Loop where k is the last character pressed
    while (k != ord('q')):

        # Declaration of strings
        statusbarstr = "Press 'q' to exit | STATUS BAR "

        '''Draw borders of the different columns'''
        height, width = stdscr.getmaxyx()
        stdscr.border()
        stdscr.vline(1, 3 * height // 4, '|', width - 2)
        stdscr.vline(1, height // 4, '|', width - 2)
        stdscr.refresh()

        '''Initialize the Statistics column'''
        column_one = curses.newwin(height - 2, 3 * width // 4, 1,
                                           1)
        _, a_x = column_one.getmaxyx()
        column_one.attron(curses.color_pair(1))
        column_one.attron(curses.A_BOLD)
        column_one.addstr(0, a_x // 2 - 2, "column one")
        column_one.hline(1, 0, '-', a_x)
        column_one.attroff(curses.color_pair(1))
        column_one.attroff(curses.A_BOLD)

        # I want to add my string here for example : 
        line = time_func()
        column_one.addstr(3,1, line)


        column_one.noutrefresh()

        '''Initialize the Alerts column'''
        column_two = curses.newwin(height - 2, width // 4, 1,
                                       3 * width // 4 )
        _, s_x = column_two.getmaxyx()
        column_two.attron(curses.color_pair(1))
        column_two.attron(curses.A_BOLD)
        column_two.addstr(0, s_x // 2 - 5, "column two")
        column_two.hline(1, 0, '-', s_x)
        column_two.attroff(curses.color_pair(1))
        column_two.attroff(curses.A_BOLD)

        column_two.addstr(3, s_x // 2 - 5,"test")

        column_two.noutrefresh()



        # Render status bar
        stdscr.attron(curses.color_pair(3))
        stdscr.addstr(height-1, 0, statusbarstr)
        stdscr.addstr(height-1, len(statusbarstr), " " * (width - len(statusbarstr) - 1))
        stdscr.attroff(curses.color_pair(3))

        # Turning on attributes for title
        stdscr.attron(curses.color_pair(2))
        stdscr.attron(curses.A_BOLD)

        # Rendering title


        # Turning off attributes for title
        stdscr.attroff(curses.color_pair(2))
        stdscr.attroff(curses.A_BOLD)

        # Print rest of text

        stdscr.move(height - 2, width - 2)

        # Refresh the screen
        stdscr.refresh()
        # Wait for next input
        k = stdscr.getch()

def main():
    curses.wrapper(draw_menu())

if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:0)

curses函数draw_menu正在等待循环结束时的输入。如果您调整终端的大小,那

k = stdscr.getch()

返回KEY_RESIZE,然后再次循环。

您可以在放弃getch之前将其更改为等待一小段时间。这将返回 -1

通常使用timeout(在curses中)完成,例如50毫秒。 Python中有一个wrapper for that(顺便提一下,它的描述不正确)。你应该阅读ncurses manual page for timeout

有时人们会说使用nodelay,这通常是不好的建议,因为它会使draw_menu线程占用大部分CPU时间。