You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Python辐射剂量计算代码添加键盘事件返回参数设置

实现键盘中断循环并返回参数输入阶段的解决方案

问题描述

我有一段通过公式计算辐射剂量的Python代码,需求是添加键盘事件以中断while True循环,返回到#DTU_01(start)处重新输入参数后继续计算。但添加keyboard库后无效果,仅能在输入框输入内容,代码如下:

import json
from colorama import init, Fore, Style
import keyboard
import time

init()

with open("DTU.json", 'r') as file:
    data = json.load(file)

print('Расчет дозы для трех установов ДТУ')
a1_values = [float(data[dtu]['a1']) for dtu in data]
b1_values = [float(data[dtu]['b1']) for dtu in data]
a2_values = [float(data[dtu]['a2']) for dtu in data]
a3_values = [float(data[dtu]['a3']) for dtu in data]
b2_values = [float(data[dtu]['b2']) for dtu in data]
b3_values = [float(data[dtu]['b3']) for dtu in data]

print('DTU-01_1:')
print('a1=', a1_values[0], 'b1=', b1_values[0], 'a2=', a2_values[0], 'b2=', b2_values[0], 'a3=', a3_values[0], 'b3=', b3_values[0])
print('DTU-01_2:')
print('a1=', a1_values[1], 'b1=', b1_values[1], 'a2=', a2_values[1], 'b2=', b2_values[1], 'a3=', a3_values[1], 'b3=', b3_values[1])
print('DTU-01_3:')
print('a1=', a1_values[2], 'b1=', b1_values[2], 'a2=', a2_values[2], 'b2=', b2_values[2], 'a3=', a3_values[2], 'b3=', b3_values[2])
k_sens1 = [1.5, 1.2245, 1, 0.8163, 0.6666, 0.5442, 0.4444]
k_sens2 = [1.4964, 1.2239, 1, 0.8167, 0.6678, 0.5459, 0.4461]
k_sens3 = [1.4948, 1.2236, 1, 0.8169, 0.6682, 0.54665, 0.4471]

# DTU-1(start)
dtu = int(input("Номер ДТУ = "))

if dtu == 1:
    a_m = [float(a1_values[0]), float(a2_values[0]), float(a3_values[0])]
    b_m = [float(b1_values[0]), float(b2_values[0]), float(b3_values[0])]
    b = b_m[0]
    a = a_m[0]
    k = k_sens1
elif dtu == 2:
    a_m = [float(a1_values[1]), float(a2_values[1]), float(a3_values[1])]
    a = a_m[0]
    b_m = [float(b1_values[1]), float(b2_values[1]), float(b3_values[1])]
    b = b_m[0]
    k = k_sens2
else:
    a_m = [float(a1_values[2]), float(a2_values[2]), float(a3_values[2])]
    a = a_m[0]
    b_m = [float(b1_values[2]), float(b2_values[2]), float(b3_values[2])]
    b = b_m[0]
    k = k_sens3
# DTU-1(end)

# KdrDf(start)
n = int(input("K_group = "))
ks = k[n]  # Correct index for ks
k_dr = float(input('K_dreif = '))
dfon = float(input("Dfon = "))
# KdrDf(end)

while True:
    i1_str = input("I1 = ")
    i2_str = input("I2 = ")

    if ',' in i1_str:
        i1_str = i1_str.replace(',', '.')
    if ',' in i2_str:
        i2_str = i2_str.replace(',', '.')

    i_1 = float(i1_str)
    i_2 = float(i2_str)

    i1 = i_1 * ks
    i2 = i_2 * ks
    d1 = (k_dr * i1 * a) + b
    d2 = (k_dr * i2 * a) + b
    D = ((d1 + d2) / 2) - dfon

    if 1.5 <= D < 15:
       a = a_m[1]
       b = b_m[1]
       d1 = (k_dr * i1 * a) + b
       d2 = (k_dr * i2 * a) + b
       D = ((d1 + d2) / 2) - dfon
       print(f"{Fore.YELLOW}{round(D, 3)}{Style.RESET_ALL}")
    elif D >= 15:
        a = a_m[2]
        b = b_m[2]
        d1 = (k_dr * i1 * a) + b
        d2 = (k_dr * i2 * a) + b
        D = ((d1 + d2) / 2) - dfon
        print(f"{Fore.RED}{round(D, 3)}{Style.RESET_ALL}")
    else:
        print(f"{Fore.GREEN}{round(D, 3)}{Style.RESET_ALL}")

问题原因

原代码中input()是阻塞式调用,程序会卡在输入等待状态,主线程被占用,导致keyboard库的事件监听无法正常响应。

修改方案

通过外层循环包裹参数输入逻辑,在计算循环中轮询键盘按键状态,实现中断返回功能:

import json
from colorama import init, Fore, Style
import keyboard
import time

init()

with open("DTU.json", 'r') as file:
    data = json.load(file)

print('Расчет дозы для трех установов ДТУ')
a1_values = [float(data[dtu]['a1']) for dtu in data]
b1_values = [float(data[dtu]['b1']) for dtu in data]
a2_values = [float(data[dtu]['a2']) for dtu in data]
a3_values = [float(data[dtu]['a3']) for dtu in data]
b2_values = [float(data[dtu]['b2']) for dtu in data]
b3_values = [float(data[dtu]['b3']) for dtu in data]

print('DTU-01_1:')
print('a1=', a1_values[0], 'b1=', b1_values[0], 'a2=', a2_values[0], 'b2=', b2_values[0], 'a3=', a3_values[0], 'b3=', b3_values[0])
print('DTU-01_2:')
print('a1=', a1_values[1], 'b1=', b1_values[1], 'a2=', a2_values[1], 'b2=', b2_values[1], 'a3=', a3_values[1], 'b3=', b3_values[1])
print('DTU-01_3:')
print('a1=', a1_values[2], 'b1=', b1_values[2], 'a2=', a2_values[2], 'b2=', b2_values[2], 'a3=', a3_values[2], 'b3=', b3_values[2])
k_sens1 = [1.5, 1.2245, 1, 0.8163, 0.6666, 0.5442, 0.4444]
k_sens2 = [1.4964, 1.2239, 1, 0.8167, 0.6678, 0.5459, 0.4461]
k_sens3 = [1.4948, 1.2236, 1, 0.8169, 0.6682, 0.54665, 0.4471]

# 外层循环:控制重新输入参数的流程
while True:
    # DTU-1(start)
    dtu = int(input("Номер ДТУ = "))

    if dtu == 1:
        a_m = [float(a1_values[0]), float(a2_values[0]), float(a3_values[0])]
        b_m = [float(b1_values[0]), float(b2_values[0]), float(b3_values[0])]
        b = b_m[0]
        a = a_m[0]
        k = k_sens1
    elif dtu == 2:
        a_m = [float(a1_values[1]), float(a2_values[1]), float(a3_values[1])]
        a = a_m[0]
        b_m = [float(b1_values[1]), float(b2_values[1]), float(b3_values[1])]
        b = b_m[0]
        k = k_sens2
    else:
        a_m = [float(a1_values[2]), float(a2_values[2]), float(a3_values[2])]
        a = a_m[0]
        b_m = [float(b1_values[2]), float(b2_values[2]), float(b3_values[2])]
        b = b_m[0]
        k = k_sens3
    # DTU-1(end)

    # KdrDf(start)
    n = int(input("K_group = "))
    ks = k[n]  # Correct index for ks
    k_dr = float(input('K_dreif = '))
    dfon = float(input("Dfon = "))
    # KdrDf(end)

    print("开始计算,按Esc键返回参数输入阶段")
    # 计算循环:处理剂量计算逻辑
    while True:
        # 检查是否按下Esc键,触发返回参数输入
        if keyboard.is_pressed('esc'):
            print("\n已触发返回,重新输入参数...")
            # 等待按键松开,避免连续触发
            while keyboard.is_pressed('esc'):
                time.sleep(0.1)
            break
        
        # 输入I1并检查按键
        i1_str = input("I1 = ")
        if keyboard.is_pressed('esc'):
            print("\n已触发返回,重新输入参数...")
            while keyboard.is_pressed('esc'):
                time.sleep(0.1)
            break

        # 输入I2并检查按键
        i2_str = input("I2 = ")
        if keyboard.is_pressed('esc'):
            print("\n已触发返回,重新输入参数...")
            while keyboard.is_pressed('esc'):
                time.sleep(0.1)
            break

        # 处理输入的逗号转点
        if ',' in i1_str:
            i1_str = i1_str.replace(',', '.')
        if ',' in i2_str:
            i2_str = i2_str.replace(',', '.')

        # 处理非数字输入异常
        try:
            i_1 = float(i1_str)
            i_2 = float(i2_str)
        except ValueError:
            print("输入无效,请输入数字")
            continue

        # 剂量计算逻辑
        i1 = i_1 * ks
        i2 = i_2 * ks
        d1 = (k_dr * i1 * a) + b
        d2 = (k_dr * i2 * a) + b
        D = ((d1 + d2) / 2) - dfon

        if 1.5 <= D < 15:
            a = a_m[1]
            b = b_m[1]
            d1 = (k_dr * i1 * a) + b
            d2 = (k_dr * i2 * a) + b
            D = ((d1 + d2) / 2) - dfon
            print(f"{Fore.YELLOW}{round(D, 3)}{Style.RESET_ALL}")
        elif D >= 15:
            a = a_m[2]
            b = b_m[2]
            d1 = (k_dr * i1 * a) + b
            d2 = (k_dr * i2 * a) + b
            D = ((d1 + d2) / 2) - dfon
            print(f"{Fore.RED}{round(D, 3)}{Style.RESET_ALL}")
        else:
            print(f"{Fore.GREEN}{round(D, 3)}{Style.RESET_ALL}")

关键修改点

  1. 新增外层循环:将参数输入和计算逻辑包裹在一个外层while True循环中,中断计算循环后会自动回到参数输入步骤。
  2. 键盘按键轮询:在计算循环的每次迭代中,用keyboard.is_pressed('esc')检查按键状态,输入前后都加入检查,确保在输入过程中也能触发返回。
  3. 按键防抖处理:触发返回后等待按键松开,避免连续触发多次。
  4. 输入异常处理:添加try-except捕获非数字输入,防止程序崩溃。

内容的提问来源于stack exchange,提问作者plkh_20

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 08:50:58