- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试在一个长时间运行的函数的进度条下方实现一个简单的微调器(使用改编自 this answer 的代码)。
[######## ] x%
/ Compressing filename
我在脚本的主线程中运行压缩和进度条,在另一个线程中运行微调器,因此它实际上可以在压缩发生时旋转。但是,我对进度条和微调器都使用了 curses
,并且都使用了 curses.refresh()
有时终端会随机输出乱码,我不确定为什么。我认为这是由于微调器的多线程特性所致,因为当我禁用微调器时,问题就消失了。
这是微调器的伪代码:
def start(self):
self.busy = True
global stdscr
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
threading.Thread(target=self.spinner_task).start()
def spinner_task(self):
while self.busy:
stdscr.addstr(1, 0, next(self.spinner_generator))
time.sleep(self.delay)
stdscr.refresh()
这是进度条的伪代码:
progress_bar = "\r[{}] {:.0f}%".format("#" * block + " " * (bar_length - block), round(progress * 100, 0))
progress_file = " {} {}".format(s, filename)
stdscr.clrtoeol()
stdscr.addstr(1, 1, " ")
stdscr.clrtoeol()
stdscr.addstr(0, 0, progress_bar)
stdscr.addstr(1, 1, progress_file)
stdscr.refresh()
并从 main()
中调用,例如:
spinner.start()
for each file:
update_progress_bar
compress(file)
spinner.stop()
为什么输出有时会损坏?是因为单独的线程吗?如果是这样,关于更好的设计方法有什么建议吗?
最佳答案
Python 的 curses
模块所依赖的 curses
库不是线程安全的。
ncurses
有一个 curs_threads
功能,它显然自大约十年前的 5.7 以来就已经存在。但它需要改变您执行一些 API 调用的方式,并链接到 -lncursest
,它仍然不是微不足道的,而且……几乎没有人使用过它。
据我所知,没有任何标准安装程序或发行包会构建 Python curses
来链接 ncursest
——即使发行版包含 ncursest
首先,他们通常不会这样做。即使他们这样做了,也没有线程安全函数的绑定(bind),所以您仍然无法安全地访问诸如设置 tabsize 之类的东西。
根据我的(可能已过时,并且可能受平台限制)经验,您仍然可以摆脱困境,但您需要:
getch
和 getmouse
之类的东西。Lock
,然后确保每批更新都以refresh
结束,并且整批更新都在Lock 中。curs_threads
中提到的功能使用 Python 包装器——例如,不要更改 escdelay 或 tabsize。但是安全的方法是做与 tkinter 相同的事情。或其他不了解线程的 GUI 库。它不完全相同,但想法相似。最简单的版本是:
queue.Queue
以便您的后台线程可以请求运行 curses
命令。 (你不需要任何复杂的东西来表示一个“命令”,它只是一个 (func, *args)
元组,因为 Python。)如果您的后台线程需要调用返回值的函数,显然您需要稍微复杂一些。您可以查看 multiprocessing.dummy.AsyncResult
和 concurrent.futures.Future
的工作原理。或者你甚至可以窃取 Future
用于你自己的目的。但您可能不需要任何复杂的东西。
如果你在循环输入,你可能还希望你的主线程这样做(这意味着选择一个“帧速率”并在等待队列和输入之间交替,超时)并分派(dispatch)它,即使您总是分派(dispatch)到同一个线程。
你甚至可以写一个 mtTkinter
重现 curses
接口(interface)(甚至是 monkeypatches curses
模块)但用将函数和参数放入队列的调用替换每个函数的样式包装器。但我不确定这是否值得付出努力。
关于python - Python中的多线程诅咒输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51315269/
所以我有一个用 ncurses 制作的基本“贪吃蛇”游戏。 添加时 start_color(); init_color(COLOR_BLUE, 0, 0, 0); init_pair(
我想处理来自 stdin 的管道/终端,但同时,我希望我的其他操作继续处理,例如 上/下菜单 . fgets完成处理管道和屏幕渲染,但是,wgetch变得没有反应,所以我不能在开关内做任何事情。要关闭
我想在不清除屏幕的情况下在 Python 下使用 Curses。原因是我希望我的应用程序在现有屏幕上弹出一个简单的小菜单并很快退出。在退出时将弹出菜单的丑陋部分留在屏幕上是可以接受的,尽管不是首选。这
我已经开始用Python语言编写控制台了。太神奇了。但是,我尝试使用 curses 创建输入框,如下所示。我一直坚持如何放置输入行并在控制台的输入位置上写入输入。这部分你能帮我吗?我忘了问_是否可以使
我正在尝试创建这个程序,我在 stdscr 上并排打印两个窗口。我创建了“菜单”类来在一个地方声明整个屏幕的所有内容,我在 main 中创建了一个“菜单”对象(“menu_principal”),但没
大家好,我正在 Unix 中用 C 语言做作业,任务是制作一个简单的乒乓球游戏。我现在已经开始玩游戏了,除了有一个烦人的部分, Racket 正后方不断有一个闪烁的光标。我该如何关闭它? 这是截图。
我正在尝试创建一个交互式命令行程序,似乎 Mono-Curses是我需要的。但我对如何使用它感到非常困惑。我有一些问题。我真正需要什么来创建我的项目?我需要单声道还是可以使用 .net 框架?为什么那
我正在尝试学习 Windows XP 上的 Python 诅咒。我可以让 window.getkey 命令正常工作,但命令 window.getstr 不仅失败而且程序退出。以下是示例代码行: x =
#include #include #include #include #include "color.h" #include using namespace std; using name
我正在编写一个关于 pythoncurses 的程序,我想知道是否有一种方法可以阻止终端大小调整,以防止curses 在 Linux 和 Windows 上崩溃。这就是发生的事情..我可以阻止这种情况
我正在编写一个 python curses 游戏 ( https://github.com/pankshok/xoinvader )。我发现了一个问题:在终端模拟器中它工作正常,但在 tty 屏幕闪烁
当我将某些表情符号(特别是标志)输出到 Curses 的子窗口中时,它会使输出变形,即使是在该子窗口之外的输出也是如此。 运行: import curses def draw_screen(stdsc
快速退出带有使用curses模块的无限循环的Python程序的最佳方法是什么? 我尝试在循环末尾添加 nodelay() 方法: if screen.getch() == ord('q'):
我在 ncurses 中有一个菜单系统。选择其中一个选项会将您带到另一个菜单。但我该如何返回? import curses def Main(): x = 0 while x!= ord(
这段代码运行了 100 万次迭代(在我的机器上大约几秒钟),但是当我按住一个按钮时,我按住的 # 迭代并没有显着增加。 import curses stdscr = curses.initscr()
我在 Python 中编写了一个比一次性使用多一点的监控脚本,它使用 ncurses 和颜色来显示一些经常更新但几乎没有人感兴趣的值。为了提醒我注意重大变化,我进行了一些设置,以便当这些值进入有趣的领
我正在使用 ncurses 并使用 getstr() 获取输入字符串。我想通过 Tab 击键进行类似自动完成的操作。但是,我看不到使用 getstr() 捕获 Tab 的方法。我试过这个: char
Windows 是否有等同于 PHP 的 ncurses? 我已经创建了一个 CLI 脚本,并希望以一种很好的方式显示各种统计信息(当前处理的记录、完成百分比等),而不是将负载和文本堆输出到 cmd.
我很难尝试获得带有 ruby 和诅咒的纯白色(背景)和黑色(前景)文本。 用这段代码 Curses.init_pair(1,COLOR_BLACK,COLOR_WHITE) Curses.attron
我正在尝试 Curses.getchr,但是没有捕获像 Ctrl+s 这样的键,是否有任何库可以让我捕获它们,最重要的是直观/可读性好 FooBar.bind('Ctrl+s'){ raise "do
我是一名优秀的程序员,十分优秀!