使用python curses窗口后,为什么Windows提示无响应?(Why is the Windows prompt unresponsive after using a python curs

编程入门 行业动态 更新时间:2024-10-11 07:34:31
使用python curses窗口后,为什么Windows提示无响应?(Why is the Windows prompt unresponsive after using a python curses window?)

首先,我是python的新手。 不得不在大学里学习它的课程,并被它的效率所吸引。

我有这个棘手的问题,在使用curses窗口后,Windows 7提示符无响应。 在Windows 10中,它运行良好。 请注意,我正在使用Win7终端及其默认设置。 在我的代码中,我创建了一个curses窗口,以显示2个同步进度条,每个进度条用于文件下载。 我通过将curses窗口传递给FileDownload类(每次下载一个类实例)来实现这一点,该类在此窗口中处理其进度条。 奇怪的是,在Windows 7中,当下载完成并且控件返回到提示时,它对键盘没有响应。 我通过在使用窗口后调用curses.endwin()来解决这个问题,但是这会导致提示一直显示在屏幕缓冲区中,隐藏了curses窗口。

这是我的代码。 任何想法都非常感谢。 谢谢!

# Skeleton version for simulations. # Downloads 2 files simultaneously and shows a progress bar for each. # Each file download is a FileDownload object that interacts with a # common curses window passed as an argument. import requests, math, threading, curses, datetime class FileDownload: def __init__(self, y_pos, window, url): # Y position of the progress bar in the download queue window. self.__bar_pos = int(y_pos) self.__progress_window = window self.__download_url = url # Status of the file download object. self.__status = "queued" t = threading.Thread(target=self.__file_downloader) t.start() # Downloads selected file and handles its progress bar. def __file_downloader(self): file = requests.get(self.__download_url, stream=True) self.__status = "downloading" self.__progress_window.addstr(self.__bar_pos + 1, 1, "0%" + " " * 60 + "100%") size = int(file.headers.get('content-length')) win_prompt = "Downloading " + format(size, ",d") + " Bytes:" self.__progress_window.addstr(self.__bar_pos, 1, win_prompt) file_name = str(datetime.datetime.now().strftime("%Y-%m-%d_%H.%M.%d")) dump = open(file_name, "wb") # Progress bar length. bar_space = 58 # Same as an index. current_iteration = 0 # Beginning position of the progress bar. progress_position = 4 # How many iterations will be needed (in chunks of 1 MB). iterations = math.ceil(size / 1024 ** 2) # Downloads the file in 1MB chunks. for block in file.iter_content(1024 ** 2): dump.write(block) # Progress bar controller. current_iteration += 1 step = math.floor(bar_space / iterations) if current_iteration > 1: progress_position += step if current_iteration == iterations: step = bar_space - step * (current_iteration - 1) # Updates the progress bar. self.__progress_window.addstr(self.__bar_pos + 1, progress_position, "#" * step) dump.close() self.__status = "downloaded" # Returns the current status of the file download ("queued", "downloading" or # "downloaded"). def get_status(self): return self.__status # Instantiates each file download. def files_downloader(): # Creates curses window. curses.initscr() win = curses.newwin(8, 70) win.border(0) win.immedok(True) # Download URLs. urls = ["http://ipv4.download.thinkbroadband.com/10MB.zip", "http://ipv4.download.thinkbroadband.com/5MB.zip"] downloads_dct = {} for n in range(len(urls)): # Progress bar position in the window for the file. y_pos = n * 4 + 1 downloads_dct[n + 1] = FileDownload(y_pos, win, urls[n]) # Waits for all files to be downloaded before passing control of the terminal # to the user. all_downloaded = False while not all_downloaded: all_downloaded = True for key, file_download in downloads_dct.items(): if file_download.get_status() != "downloaded": all_downloaded = False # Prevents the prompt from returning inside the curses window. win.addstr(7, 1, "-") # This solves the unresponsive prompt issue but hides the curses window if the screen buffer # is higher than the window size. # curses.endwin() while input("\nEnter to continue: ") == "": files_downloader()

First of all, I'm a newby in python. Had to take a course of it in college and got hooked by its efficiency.

I have this sticky problem where the Windows 7 prompt becomes unresponsive after using a curses window. In Windows 10 it works well. Note that I'm using the Win7 terminal with its default settings. In my code I create a curses window to show 2 simultaneous progress bars, each for a file download. I implemented this by passing the curses window to a FileDownload class (one class instance for each download) that handles its progress bar inside this window. Oddly, in Windows 7 when the downloads are done and the control returns to the prompt, it becomes unresponsive to the keyboard. I worked around this by invoking curses.endwin() after using the window, but this causes the prompt to display all the way down the screen buffer, what hides the curses window.

Here is my code. Any ideas are greatly appreciated. Thanks!

# Skeleton version for simulations. # Downloads 2 files simultaneously and shows a progress bar for each. # Each file download is a FileDownload object that interacts with a # common curses window passed as an argument. import requests, math, threading, curses, datetime class FileDownload: def __init__(self, y_pos, window, url): # Y position of the progress bar in the download queue window. self.__bar_pos = int(y_pos) self.__progress_window = window self.__download_url = url # Status of the file download object. self.__status = "queued" t = threading.Thread(target=self.__file_downloader) t.start() # Downloads selected file and handles its progress bar. def __file_downloader(self): file = requests.get(self.__download_url, stream=True) self.__status = "downloading" self.__progress_window.addstr(self.__bar_pos + 1, 1, "0%" + " " * 60 + "100%") size = int(file.headers.get('content-length')) win_prompt = "Downloading " + format(size, ",d") + " Bytes:" self.__progress_window.addstr(self.__bar_pos, 1, win_prompt) file_name = str(datetime.datetime.now().strftime("%Y-%m-%d_%H.%M.%d")) dump = open(file_name, "wb") # Progress bar length. bar_space = 58 # Same as an index. current_iteration = 0 # Beginning position of the progress bar. progress_position = 4 # How many iterations will be needed (in chunks of 1 MB). iterations = math.ceil(size / 1024 ** 2) # Downloads the file in 1MB chunks. for block in file.iter_content(1024 ** 2): dump.write(block) # Progress bar controller. current_iteration += 1 step = math.floor(bar_space / iterations) if current_iteration > 1: progress_position += step if current_iteration == iterations: step = bar_space - step * (current_iteration - 1) # Updates the progress bar. self.__progress_window.addstr(self.__bar_pos + 1, progress_position, "#" * step) dump.close() self.__status = "downloaded" # Returns the current status of the file download ("queued", "downloading" or # "downloaded"). def get_status(self): return self.__status # Instantiates each file download. def files_downloader(): # Creates curses window. curses.initscr() win = curses.newwin(8, 70) win.border(0) win.immedok(True) # Download URLs. urls = ["http://ipv4.download.thinkbroadband.com/10MB.zip", "http://ipv4.download.thinkbroadband.com/5MB.zip"] downloads_dct = {} for n in range(len(urls)): # Progress bar position in the window for the file. y_pos = n * 4 + 1 downloads_dct[n + 1] = FileDownload(y_pos, win, urls[n]) # Waits for all files to be downloaded before passing control of the terminal # to the user. all_downloaded = False while not all_downloaded: all_downloaded = True for key, file_download in downloads_dct.items(): if file_download.get_status() != "downloaded": all_downloaded = False # Prevents the prompt from returning inside the curses window. win.addstr(7, 1, "-") # This solves the unresponsive prompt issue but hides the curses window if the screen buffer # is higher than the window size. # curses.endwin() while input("\nEnter to continue: ") == "": files_downloader()

最满意答案

也许您正在使用cygwin(和ncurses):ncurses(与任何其他curses实现一样)在运行时更改终端I / O模式。 您可能会看到的变化是

输入字符不会被回显 你必须输入控制 J来结束输入行,而不是输入 输出不会在每行末尾自动刷新

它使这些更改允许它读取单个字符,并更有效地使用终端。

要更改终端的正常I / O模式,您可以使用endwin功能。 reset_shell_mode函数也很有用。

进一步阅读:

endwin (ncurses手册) reset_shell_mode (ncurses手册)

Perhaps you're using cygwin (and ncurses): ncurses (like any other curses implementation) changes the terminal I/O mode when it is running. The changes that you probably are seeing is that

input characters are not echoed you have to type controlJ to end an input line, rather than just Enter output is not flushed automatically at the end of each line

It makes those changes to allow it to read single characters and also to use the terminal more efficiently.

To change back to the terminal's normal I/O mode, you would use the endwin function. The reset_shell_mode function also would be useful.

Further reading:

endwin (ncurses manual) reset_shell_mode (ncurses manual)

更多推荐

本文发布于:2023-08-08 00:32:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1466684.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:窗口   提示   python   curses   Windows

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!