【问题标题】:Command prompt messed up after running a Python program运行 Python 程序后命令提示符混乱
【发布时间】:2013-07-28 11:02:05
【问题描述】:

下面的代码创建一个布局并在布局中显示一些文本。接下来,使用Urwid 库中的原始显示模块将布局显示在控制台屏幕上。 (关于我的完整项目的更多信息可以从 Required widgets for displaying a 1D console applicationUsing Urwid to create a 2D console application 的问题中收集。

我的 Skype 帮助请求是 here。我可以运行代码来显示相关信息。按 F8 时,代码会询问屏幕上的对话框是否退出。按“y”键,应用程序结束。但在那之后,命令提示符就搞砸了。我无法在命令提示符下写任何东西。按 Enter 按钮只会重复命令提示符,如下所示:

[gehna@localhost urwidFormBrowser]$ [gehna@localhost urwidFormBrowser]$ [gehna@localhost urwidFormBrowser]$

代码是:

#!/usr/bin/env python

import sys
sys.path.append('./lib')
import os
from pprint import pprint
import random
import urwid
ui = urwid.raw_display.Screen()

class FormDisplay(object):

    def __init__(self):
        global ui
        #self.ui = urwid.raw_display.Screen()
        self.ui = ui
        self.palette = self.ui.register_palette([
            ('Field', 'dark green, bold', 'black'), # information fields, Search: etc.
            ('Info', 'dark green', 'black'), # information in fields
            ('Bg', 'black', 'black'), # screen background
            ('InfoFooterText', 'white', 'dark blue'), # footer text
            ('InfoFooterHotkey', 'dark cyan, bold', 'dark blue'), # hotkeys in footer text
            ('InfoFooter', 'black', 'dark blue'),  # footer background
            ('InfoHeaderText', 'white, bold', 'dark blue'), # header text
            ('InfoHeader', 'black', 'dark blue'), # header background
            ('BigText', RandomColor(), 'black'), # main menu banner text
            ('GeneralInfo', 'brown', 'black'), # main menu text
            ('LastModifiedField', 'dark cyan, bold', 'black'), # Last modified:
            ('LastModifiedDate', 'dark cyan', 'black'), # info in Last modified:
            ('PopupMessageText', 'black', 'dark cyan'), # popup message text
            ('PopupMessageBg', 'black', 'dark cyan'), # popup message background
            ('SearchBoxHeaderText', 'light gray, bold', 'dark cyan'), # field names in the search box
            ('SearchBoxHeaderBg', 'black', 'dark cyan'), # field name background in the search box
            ('OnFocusBg', 'white', 'dark magenta') # background when a widget is focused
           ])
    urwid.set_encoding('utf8')

    def main(self):
        global ui
        #self.view = ui.run_wrapper(formLayout)
        self.ui.start()
        self.view = formLayout()
        self.exit_view = formLayoutExit()
        self.loop = urwid.MainLoop(self.view, self.palette, unhandled_input=self.unhandled_input)
        self.loop.widget = self.view
        self.loop.run()

    def unhandled_input(self, key):
        if key == 'f8':
            self.loop.widget = self.exit_view
            return True
        if self.loop.widget != self.exit_view:
            return
        if key in ('y', 'Y'):
            raise urwid.ExitMainLoop()
        if key in ('n', 'N'):
            self.loop.widget = self.view
            return True

def formLayout():
    global ui
    text1 = urwid.Text("Urwid 3DS Application program - F8 exits.")
    text2 = urwid.Text("One mission accomplished")
    textH = urwid.Text("topmost Pile text")
    cols = urwid.Columns([text1,text2])
    pile = urwid.Pile([textH,cols])
    fill = urwid.Filler(pile)

    textT  = urwid.Text("Display")

    textSH = urwid.Text("Pile text in Frame")
    textF = urwid.Text("Good progress !")

    frame = urwid.Frame(fill,header=urwid.Pile([textT,textSH]),footer=textF)
    dim = ui.get_cols_rows()
    #ui is treated as global handle for all functions, either belonging
    #to any class or standalone functions such as formLayout
    #need to check if screen has been started
    if not ui._started:
        print("Screen has not been started, so no use of rendering.Thus return :-( ")
        return

    ui.draw_screen(dim, frame.render(dim, True))
    return frame


def formLayoutExit():
    exit = urwid.BigText(('exit'," Quit? "), urwid.font.HalfBlock5x4Font())
    exit = urwid.Overlay(exit, formLayout(), 'center', None, 'middle', None)
    return exit

def RandomColor():
    '''Pick a random color for the main menu text'''
    listOfColors = ['dark red', 'dark green', 'brown', 'dark blue',
                    'dark magenta', 'dark cyan', 'light gray',
                    'dark gray', 'light red', 'light green', 'yellow',
                    'light blue', 'light magenta', 'light cyan', 'default']
    color = listOfColors[random.randint(0, 14)]
    return color

def main():
    #global ui
    form = FormDisplay()
    form.main()

########################################
##### MAIN ENTRY POINT
########################################
if __name__ == '__main__':
    main()

我怀疑应用程序退出后显示的行为与 FormDisplay、formlayout 和 formlayoutExit 函数的返回调用有关。我该如何解决这个问题?

【问题讨论】:

  • 不管怎样,您可以通过输入reset 来修复您的终端。无论如何,您可能都想修复您的代码。 :)
  • 谢谢,在退出应用程序后键入“reset”会给我一个全新的终端,但我希望我的代码能够像许多其他 urwid 应用程序一样干净地退出。 :-) 响应
  • 我已经能够重现您的问题,但是我对 urwid 不是很熟悉,基本上raise urwid.ExitMainLoop() 应该恢复原始终端设置,包括回显,所以我我很难过。

标签: python user-interface python-2.7 console-application urwid


【解决方案1】:

确保在你的执行完成时使用sys.exit(retCode),这个问题应该不会发生

【讨论】:

    【解决方案2】:

    如果出现错误/异常,您的程序应该撤消在 curses 初始化期间对终端所做的更改。如果您不想这样做,则提供了一个包装函数。请检查文档。

    在您的情况下,您可以通过包装器调用而不是直接调用 main。

    curses.wrapper(main)
    

    【讨论】:

      猜你喜欢
      • 2020-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-30
      • 2023-03-25
      相关资源
      最近更新 更多