【问题标题】:'AttributeError' while trying to create a console screen using urwid尝试使用 urwid 创建控制台屏幕时出现“AttributeError”
【发布时间】:2013-07-28 07:56:47
【问题描述】:

下面的代码创建一个布局并在布局中显示一些文本。接下来,使用 urwid 库中的原始显示模块将布局显示在控制台屏幕上。 (关于我的完整项目的更多信息可以从widget advice for a console projecturwid for a console project 的问题中收集。我的Skype 帮助请求是here。)但是运行代码失败,因为如下所述引发了AttributeError。在 /usr/lib64/python2.7/site-packages/urwid 查看 urwid 的源代码时,我看到 main_loop.py 和 curses_display.py 都有一个带有不同参数的 draw_screen 函数: main_loop.py -> def draw_screen(self):

curses_display.py > def draw_screen(self, (cols, rows), r):

我是否必须通过 import draw_screen from specificFile 命令指定使用哪一个?或者我在看画布概念有什么根本错误吗?我还可以看到文件中的框架类(class Frame(BoxWidget):) /usr/lib64/python2.7/site-packages/urwid/container.py 有渲染功能(def render(self, size, focus=False):

运行代码出错:
Traceback (most recent call last):
File "./yamlUrwidUIPhase6.py", line 104, in <module>
main() File "./yamlUrwidUIPhase6.py", line 98, in main
form.main()
File "./yamlUrwidUIPhase6.py", line 51, in main
self.loop.run()
File "/usr/lib64/python2.7/site-packages/urwid/main_loop.py", line 274, in run
self.screen.run_wrapper(self._run)
File "/usr/lib64/python2.7/site-packages/urwid/raw_display.py", line 237, in run_wrapper return fn()
File "/usr/lib64/python2.7/site-packages/urwid/main_loop.py", line 285, in _run self.draw_screen()
File "/usr/lib64/python2.7/site-packages/urwid/main_loop.py", line 508, in draw_screen
canvas = self._topmost_widget.render(self.screen_size, focus=True)
AttributeError: 'NoneType' object has no attribute 'render'

代码:

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 = 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.loop = urwid.MainLoop(self.view, self.palette, unhandled_input=self.unhandled_input)
        self.loop.run()

    def unhandled_input(self, key):
        if key == 'f8':
          quit()
          return


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

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():
    form = FormDisplay()
    form.main()

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

我不想更改函数 formLayout,因为我打算在这个基本代码框架中添加更多内容,其中将添加另一个函数,该函数重复调用 formLayout 以根据从 yml 文件中读取的值不断更新屏幕。我已经有一个单独的代码来处理读取 yaml 文件并从中提取有序字典。在弄清楚如何让基本的 urwid 控制台正常工作之后,我可以继续集成两者来创建我的最终应用程序。

【问题讨论】:

  • 你能在画布上运行dir,看看你会得到什么吗? Python REPL ofc。
  • 我不明白在画布上运行 dir 是什么意思?我知道 dir 是一个命令,你想让我在哪里运行它?
  • 打开你的python repl。导入您的类并在 frame 类上运行 dir。查看是否存在渲染。然后在widget 上运行dirdir() 一样,看看render 是否真的存在。
  • 我这样做了&gt;&gt;&gt; dir() ['__builtins__', '__doc__', '__name__', '__package__', 'readline', 'rlcompleter'] &gt;&gt;&gt; import urwid &gt;&gt;&gt; dir() ['__builtins__', '__doc__', '__name__', '__package__', 'readline', 'rlcompleter', 'urwid'] &gt;&gt;&gt; dir() urwid File "&lt;stdin&gt;", line 1 dir() urwid ^ SyntaxError: invalid syntax &gt;&gt;&gt; dir() frame File "&lt;stdin&gt;", line 1 dir() frame ^ SyntaxError: invalid syntax
  • 运行这个:dir(urwind)。看看会发生什么。

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


【解决方案1】:

通过在代码中添加以下行来删除属性错误,如question 所示。

第 1 行: self.loop.widget = self.view 在 FormDisplay 类的 main

第 2 行: 在函数 formLayout() 中执行 return Frame 而不是 return

第 3 行: 在unhandled_input 函数中添加了处理按键的行

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 2013-10-31
    • 1970-01-01
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多