当前位置: 首页 > 面试题库 >

更新屏幕时,Python / curses用户输入

劳麒
2023-03-14
问题内容

我目前正在使用python /
curses编写应用程序用户界面,我想知道是否可以要求用户在用户界面不断更新时按下键(cbreak模式)以隐藏或显示某些面板或窗口。

我阅读了有关curses的官方python文档并进行了一些尝试,但是即使使用cbreak模式和非阻塞输入模式(nodelay)已激活,我也无法使其正常工作(我成功获取了用户输入,但是在阻止UI的代价不是我想要的)。

所以我的问题很简单,可能吗?如果是的话,怎么办?

我可能误读了文档,但没有找到任何替代文档或示例。

我曾考虑过使应用程序具有多线程功能,但在这种情况下,我没有看到这对我有什么帮助。

感谢您的帮助,建议或指向详细文档的指针。

编辑:

最后,我得到了以下多线程代码,但并不令人满意。UI已按原样提供,但刷新后显示异常。

我还不明白为什么在隐藏考虑的面板的情况下curses.panel.hidden()返回False。似乎刷新与面板关联的窗口会取消隐藏面板或类似的东西。我真的迷路了!

import threading
import curses, curses.panel
import random
import time

gui = None

class ui:
    def __init__(self):
        self.feeder = feeder(self)
        self.stdscr = curses.initscr()
        curses.noecho()
        curses.cbreak()
        curses.curs_set(0)
        self.stdscr.keypad(1)

        self.win1 = curses.newwin(10, 50, 0, 0)    
        self.win1.border(0)
        self.pan1 = curses.panel.new_panel(self.win1)
        self.win2 = curses.newwin(10, 50, 0, 0)    
        self.win2.border(0)
        self.pan2 = curses.panel.new_panel(self.win2)
        self.win3 = curses.newwin(10, 50, 12, 0)
        self.win3.border(0)
        self.pan3 = curses.panel.new_panel(self.win3)

        self.win1.addstr(1, 1, "Window 1")
        self.win2.addstr(1, 1, "Window 2")
        self.win3.addstr(1, 1, "Press 's' to switch windows or 'q' to quit.")


        self.pan1.hide()
        self.win1.refresh()

        curses.panel.update_panels()
        self.win2.refresh()
        self.feeder.start()


    def ask(self):
        while True:
            self.win3.addstr(5,1, "Hidden = win1: "+str(self.pan1.hidden())+\
                             "win2:"+str(self.pan2.hidden()), 0)
            self.win3.refresh()
            k = self.win3.getkey()
            if k == 's':
                if self.pan1.hidden():
                    self.pan2.hide()
                    self.pan1.show()
                    self.win1.refresh()
                    self.win3.addstr(2, 1, "Pan1 restored")
                else:
                    self.pan1.hide()
                    self.pan2.show()
                    self.win2.refresh()
                    self.win3.addstr(2, 1, "Pan2 restored")
                self.win3.addstr(5,1, "Hidden = win1: "+\
                                 str(self.pan1.hidden())+\
                                 " win2:"+str(self.pan2.hidden()), 0)

            elif  k == 'q':
                break        
        self.quit_ui()

    def quit_ui(self):
        self.feeder.stop()
        curses.nocbreak()
        self.stdscr.keypad(0)
        curses.curs_set(1)
        curses.echo()
        curses.endwin()
        exit(0)

    def display_data(self, window, data):
        window.addstr(3, 1, data, 0)



class feeder(threading.Thread):
    # Fake U.I feeder
    def __init__(self, ui):
        super(feeder, self).__init__()
        self.running = False
        self.ui = ui
        self.count = 0

    def stop(self):
        self.running = False

    def run(self):
        self.running = True
        self.feed()

    def feed(self):
        while self.running:
            self.ui.win1.addstr(3, 1, str(self.count)+\
                                ": "+str(int(round(random.random()*9999))))
            self.ui.win1.addstr(4, 1, str(self.running))
            self.ui.win2.addstr(3, 1, str(self.count)+\
                                ": "+str(int(round(random.random()*9999))))
            self.ui.win2.addstr(4, 1, str(self.running))
            time.sleep(0.5)
            self.count += 1


if __name__ == "__main__":
    gui = ui()
    gui.ask()

问题答案:

我终于成功地通过在double while循环中从sys.stdin中读取一个字节,然后避免使用另一个线程来使其工作。以下代码可能无法在MS
Windows上运行,并且由于我不是专业开发人员,因此它可能未经过优化或引发未捕获的错误,但这只是为了使我了解事情的工作原理而准备的草稿(尽管欢迎发表评论)
)。特别感谢Paul Griffiths指导我使用sys.stdin。

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

import curses, curses.panel
import random
import time
import sys
import select

gui = None

class ui:
    def __init__(self):
        self.stdscr = curses.initscr()
        curses.noecho()
        curses.cbreak()
        curses.curs_set(0)
        self.stdscr.keypad(1)

        self.win1 = curses.newwin(10, 50, 0, 0)    
        self.win1.border(0)
        self.pan1 = curses.panel.new_panel(self.win1)
        self.win2 = curses.newwin(10, 50, 0, 0)    
        self.win2.border(0)
        self.pan2 = curses.panel.new_panel(self.win2)
        self.win3 = curses.newwin(10, 50, 12, 0)
        self.win3.border(0)
        self.pan3 = curses.panel.new_panel(self.win3)

        self.win1.addstr(1, 1, "Window 1")
        self.win2.addstr(1, 1, "Window 2")
        self.win3.addstr(1, 1, "Press 's' to switch windows or 'q' to quit.")

        self.pan1.hide()

    def refresh(self):
        curses.panel.update_panels()
        self.win2.refresh()
        self.win1.refresh()

    def switch_pan(self):
        if self.pan1.hidden():
            self.pan2.bottom()
            self.pan2.hide()
            self.pan1.top()
            self.pan1.show()
        else:
            self.pan1.bottom()
            self.pan1.hide()
            self.pan2.top()
            self.pan2.show()

        self.refresh()

    def quit_ui(self):
        curses.nocbreak()
        self.stdscr.keypad(0)
        curses.curs_set(1)
        curses.echo()
        curses.endwin()
        print "UI quitted"
        exit(0)


class feeder:
    # Fake U.I feeder
    def __init__(self):
        self.running = False
        self.ui = ui()
        self.count = 0

    def stop(self):
        self.running = False

    def run(self):
        self.running = True
        self.feed()

    def feed(self):
        while self.running :
            while sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
                line = sys.stdin.read(1)
                if line.strip() == "q":
                    self.stop()
                    self.ui.quit_ui()
                    break
                elif line.strip() == "s":
                    self.ui.switch_pan()

            self.ui.win1.addstr(3, 1, str(self.count)+\
                                ": "+str(int(round(random.random()*999))))
            self.ui.win1.addstr(4, 1, str(self.running))
            self.ui.win2.addstr(3, 1, str(self.count)+\
                                ": "+str(int(round(random.random()*999))))
            self.ui.win2.addstr(4, 1, str(self.running))
            self.ui.refresh()
            time.sleep(0.1)
            self.count += 1

if __name__ == "__main__":
    f = feeder()
    f.run()


 类似资料:
  • 我正在开发一款新游戏,我正在用LibGDX实现屏幕。 我对触摸屏和触摸屏的结合有点迷恋。 我的渲染方法中包含以下内容: 目前我有4个不同的屏幕,当isTouch被触发时,它们都发生了变化,问题是在我触摸第一个屏幕一次后,它从屏幕1变成了4。我试图将输入处理器设置为空,但它仍然从屏幕1跳到4,而无需在每个屏幕上等待。屏幕1上的触摸似乎也会在屏幕2 3和4上自动触发。如何重置输入处理器或在下一个屏幕加

  • 我想重新绘制我的屏幕。到目前为止,它所做的只是在第一个屏幕上的头部应该在的地方显示一个点。这很好,但是我在代码中写了我想每秒将头部向下移动10个像素。我正在打印头部应该在的位置,在命令提示符中它显示y值确实在增加。但是在我的屏幕上,头部没有移动。 我尝试过使用revalidate方法,尝试扩展canvas类而不是jframe,我尝试过只为paint方法使用不同的类,我尝试过用paintCompon

  • 我是pygame的新手,我需要一些帮助,因为我的代码工作不正常。 好的,问题是:我希望屏幕在运行时变为白色,但它仍然是黑色的,但是当我按下退出按钮时,它会变为白色大约一秒钟,然后关闭。 当我放一张图片(像player.png)时,也会发生这种情况,它会在退出前出现大约一秒钟。我不知道我做错了什么, 请帮助修复代码并解释为什么会发生这种情况? 代码如下: 另外,我没有发现任何错误

  • 问题内容: 我目前正在编写一个小应用程序,以跟踪货币的来龙去脉,这只是为了提高我的C#常规技能。目前,对于我的登录屏幕,我具有以下代码 登录成功后,我要执行的操作是将当前PC的MachineName写入我的SQL数据库中“用户”表中的字段。这样,当我开始创建记录时,我可以快速找到我的UsersId(这是我的Transactions表中的外键)。 我知道您可以使用System.Enviroments

  • 问题内容: 我知道可以使用唤醒锁来保持屏幕,CPU等等,但是如何以编程方式更改Android手机上的“ 屏幕超时 ”设置。 问题答案: 该Settings.System提供商提供了一个SCREEN_OFF_TIMEOUT设置,可能是你在找什么。

  • 我有一个片段,我有一个listview。当我按下listview position时,我打开片断对话框,在其中我发送所单击项目的位置。在那里,我可以从ListView实时更改一些数据。但是当我改变我的方向(片段和对话框片段都有不同的布局)时,live更改不再起作用。如果我去另一个片段,比回来,改变是做了,但不是活着。 两者都将SetRetaInstance设置为true。 在片段中设置适配器: 对