import math
import time
import tkinter as tk
from tkinter import messagebox, ttk
from concurrent.futures import ThreadPoolExecutor, Future
from typing import List
def is_prime(n):
"""
判断一个数是否为素数
"""
if n < 2:
return False
elif n == 2:
return True
elif n % 2 == 0:
return False
else:
for i in range(3, int(math.sqrt(n))+1, 2):
if n % i == 0:
return False
return True
def factorization(n):
"""
分解质因数
"""
factors = []
for i in range(2, int(math.sqrt(n))+1):
while n % i == 0:
factors.append(i)
n //= i
if n == 1:
break
if n > 1:
factors.append(n)
return factors
def calculate():
try:
n = int(entry.get())
except ValueError:
messagebox.showerror("错误", "请输入一个整数")
return
progress_bar['value'] = 0
result.set("计算中,请稍候...")
future = executor.submit(calculate_result, n)
future.add_done_callback(on_calculate_done)
# 启动进度条更新线程
progress_future = executor.submit(progress_worker, future)
def calculate_result(n):
start_time = time.time()
if is_prime(n):
result_str = f"{n} 是素数"
else:
factors = factorization(n)
result_str = f"{n} 不是素数,它可以分解为 {factors}"
end_time = time.time()
result_str += f" 用时 {end_time - start_time:.2f} 秒"
return result_str
def on_calculate_done(future: Future):
result.set(future.result())
def quit_program():
root.quit()
def update_progress(progress):
progress_bar['value'] = progress
def progress_worker(future: Future):
start_time = time.time()
while not future.done():
elapsed_time = time.time() - start_time
progress = elapsed_time / progress_bar_max_time * 100
progress = min(progress, 100)
update_progress(progress)
time.sleep(0.1)
update_progress(100)
root = tk.Tk()
root.title("素数判断")
# 创建控件
label = ttk.Label(root, text="请输入一个整数:")
label.pack(pady=10)
entry = ttk.Entry(root, width=40)
entry.pack(pady=10)
progress_bar = ttk.Progressbar(root, orient=tk.HORIZONTAL, length=400, mode='determinate')
progress_bar.pack(pady=10)
button = ttk.Button(root, text="判断", command=calculate)
button.pack(pady=10)
result = tk.StringVar()
result.set("结果将显示在这里")
result_label = ttk.Label(root, textvariable=result)
result_label.pack(pady=10)
quit_button = ttk.Button(root, text="退出", command=quit_program)
quit_button.pack(pady=10)
# 设置布局
root.geometry("500x300")
executor = ThreadPoolExecutor(max_workers=2) # 增加线程池大小为 2 ,用于同时执行计算和进度条更新任务
progress_bar_max_time = 5 # 进度条走满需要的时间,单位为秒
def calculate():
try:
n = int(entry.get())
except ValueError:
messagebox.showerror("错误", "请输入一个整数")
return
progress_bar['value'] = 0
result.set("计算中,请稍候...")
future = executor.submit(calculate_result, n)
future.add_done_callback(on_calculate_done)
progress_future = executor.submit(progress_worker, future)
def on_calculate_done(future: Future):
result.set(future.result())
progress_bar['value'] = 100
future.cancel() # 计算完成,取消进度条更新任务
def update_progress(progress):
progress_bar['value'] = progress
def progress_worker(future: Future):
start_time = time.time()
while not future.done():
elapsed_time = time.time() - start_time
progress = elapsed_time / progress_bar_max_time * 100
progress = min(progress, 100)
update_progress(progress)
time.sleep(0.1)
update_progress(100)
root.mainloop()
这个是让 ChatGPT 写的判断素数的代码,使用 Python 3.11.2 版本 执行,但是进度条不管怎么改都不完美。 之前 GUI 界面上没进度条的,命令行窗口里有,很准确,还有倒计时、百分比等信息, 移到 GUI 界面上就一直不完美,要么点了判断,进度条不走,出结果的时候一下子拉满;要么进度条走完了还在计算中,代码里用 progress_bar_max_time = 5 的固定值不咋地,弄个预估的动态值也行啊,ChatGPT 也知道我的意思,就是弄不出来。
我要求就是点判断后进度条开始匀速走,走完了刚好出来结果,最好进度条右边放个动态百分比数字。 放进度条就是为了计算大一点数时直观感受到大概时间
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.