まず、私はPythonのnewbyです。大学でそれを学ばなければならず、その効率性に夢中になりました。python cursesウィンドウを使用した後にWindowsプロンプトが応答しないのはなぜですか?
cursesウィンドウを使用した後にWindows 7のプロンプトが応答しなくなるという問題があります。 Windows 10ではうまく動作します。私はデフォルト設定でWin7端末を使用しています。私のコードでは、cursesウィンドウを作成して、2つの同時進行バーを表示し、それぞれファイルのダウンロードを行います。私はcursesウィンドウをこのウィンドウ内の進行状況バーを処理するFileDownloadクラス(ダウンロードごとに1つのクラスインスタンス)に渡すことでこれを実装しました。奇妙なことに、ダウンロードが完了してコントロールがプロンプトに戻ると、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()
Pythonの標準ライブラリは、Windows上で呪いを実装していません。あなたが使っているcursesのバージョンを人に伝えれば助けになるかもしれません。 – eryksun
私はpython 3.5.1でcurses 2.2を使用しています。 – R01k