PySimpleGUI点云处理程序:填充输入框后启用OK按钮
点云处理程序GUI:双输入框填充后启用OK按钮
我正在开发一款点云处理程序,需要实现仅当「Input cloud (las/laz)」和「Output folder」两个输入框都填充内容后,才启用底部的"OK"按钮的功能。界面分为左右两栏:左侧包含云处理核心设置(输入路径、输出文件夹、点云参数等),右侧是栅格生成、预览相关选项,底部默认显示禁用状态的OK按钮。
现有代码
def make_window(theme=Theme): NAME_SIZE = 23 def name(name): dots = NAME_SIZE-len(name)-2 return sg.Text(name + ' ' + '•'*dots, size=(NAME_SIZE,1), justification='r',pad=(0,0), font='Courier 10') sg.theme(theme) # thème défini au début du code layout_l = [[name('CLOUD'), sg.HSep()], [sg.Text('Input cloud (las/laz)')], [sg.InputText(s=(40,1)), sg.FileBrowse()], # Permet d'aller chercher le nuage en input [sg.Text('Output folder')], [sg.InputText(s=(40,1)), sg.FolderBrowse()], # Indique le dossier de sortie [name('Info input cloud'), sg.Checkbox('')], [name('Points per box'), sg.Spin(['1000000','10000000','15000000','50000000'], s=(15,2))], [name('Classification'), sg.Combo(['none','SMRF','CSF','PMF'], default_value = 'none', s=(15,2))], [name('Create HAG'), sg.Checkbox('')], [name('Info output cloud'), sg.Checkbox('')], [name('-ProgressBar'), sg.ProgressBar(100, orientation='h', s=(10,20), k='-PBAR_1-')], [sg.Text('')], [sg.Text('')], [sg.Text('')]] layout_r = [[name('RASTER'), sg.HSep()], [name('Type of cloud'), sg.Combo(['DIMORPH','MMS','FARO','VIAMETRIS'], default_value = 'DIMORPH', s=(15,22))], [name('Raster GS'), sg.Checkbox('')], [name('Raster RGB'), sg.Checkbox('')], [name('Raster Elevation GS'), sg.Checkbox('')], [name('Raster Elevation RGB'), sg.Checkbox('')], [name('Raster HAG'), sg.Checkbox('')], [name('-ProgressBar'), sg.ProgressBar(100, orientation='h', s=(10,20), k='-PBAR_2-')], [sg.Text('')], [sg.Text('')], [name('Preview'), sg.HSep()], [name('Preview'), sg.Checkbox('')], [sg.Text('')], [sg.Button('OK', disabled=True,k='-OK-'), sg.Cancel()]] # Lance le traitement layout = [[sg.T('Traitement de nuage de points', font='_ 18', justification='c', expand_x=True)], [sg.Col(layout_l), sg.Col(layout_r)]] # Compile les 2 fenêtre définies au dessus window = sg.Window('Programme CBR', layout, finalize=True, right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_VER_EXIT, keep_on_top=True, use_custom_titlebar=use_custom_titlebar) window['-PBAR_1-'].update(0) window['-PBAR_2-'].update(0) return window window = make_window() while True: # Tant que le GUI est affiché event, values = window.read() if event in (sg.WIN_CLOSED, 'Cancel'): # On peut en sortir avec Cancel break if values and values[1] and values[2]: window['-OK-'].update(disabled=False) window.refresh() window['-PBAR_1-'].update(5)
解决方案
核心修改点
- 给输入框添加唯一Key:避免依赖数字索引(索引会随控件增减变化),给两个输入框分别命名,保证逻辑稳定性
- 完善状态判断逻辑:每次窗口事件触发时,检查两个输入框的内容是否非空,同时处理内容被清空的场景(自动重新禁用按钮)
修改后的完整代码
def make_window(theme=Theme): NAME_SIZE = 23 def name(name): dots = NAME_SIZE-len(name)-2 return sg.Text(name + ' ' + '•'*dots, size=(NAME_SIZE,1), justification='r',pad=(0,0), font='Courier 10') sg.theme(theme) # thème défini au début du code layout_l = [[name('CLOUD'), sg.HSep()], [sg.Text('Input cloud (las/laz)')], # 给输入云框添加唯一Key [sg.InputText(s=(40,1), k='-INPUT_CLOUD-'), sg.FileBrowse()], [sg.Text('Output folder')], # 给输出文件夹框添加唯一Key [sg.InputText(s=(40,1), k='-OUTPUT_FOLDER-'), sg.FolderBrowse()], [name('Info input cloud'), sg.Checkbox('')], [name('Points per box'), sg.Spin(['1000000','10000000','15000000','50000000'], s=(15,2))], [name('Classification'), sg.Combo(['none','SMRF','CSF','PMF'], default_value = 'none', s=(15,2))], [name('Create HAG'), sg.Checkbox('')], [name('Info output cloud'), sg.Checkbox('')], [name('-ProgressBar'), sg.ProgressBar(100, orientation='h', s=(10,20), k='-PBAR_1-')], [sg.Text('')], [sg.Text('')], [sg.Text('')]] layout_r = [[name('RASTER'), sg.HSep()], [name('Type of cloud'), sg.Combo(['DIMORPH','MMS','FARO','VIAMETRIS'], default_value = 'DIMORPH', s=(15,22))], [name('Raster GS'), sg.Checkbox('')], [name('Raster RGB'), sg.Checkbox('')], [name('Raster Elevation GS'), sg.Checkbox('')], [name('Raster Elevation RGB'), sg.Checkbox('')], [name('Raster HAG'), sg.Checkbox('')], [name('-ProgressBar'), sg.ProgressBar(100, orientation='h', s=(10,20), k='-PBAR_2-')], [sg.Text('')], [sg.Text('')], [name('Preview'), sg.HSep()], [name('Preview'), sg.Checkbox('')], [sg.Text('')], [sg.Button('OK', disabled=True,k='-OK-'), sg.Cancel()]] layout = [[sg.T('Traitement de nuage de points', font='_ 18', justification='c', expand_x=True)], [sg.Col(layout_l), sg.Col(layout_r)]] window = sg.Window('Programme CBR', layout, finalize=True, right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_VER_EXIT, keep_on_top=True, use_custom_titlebar=use_custom_titlebar) window['-PBAR_1-'].update(0) window['-PBAR_2-'].update(0) return window window = make_window() while True: event, values = window.read() if event in (sg.WIN_CLOSED, 'Cancel'): break # 检查两个输入框是否都有有效内容(去除前后空格) input_filled = values['-INPUT_CLOUD-'].strip() != '' output_filled = values['-OUTPUT_FOLDER-'].strip() != '' # 双条件满足则启用按钮,否则保持/恢复禁用 window['-OK-'].update(disabled= not (input_filled and output_filled)) window['-PBAR_1-'].update(5)
说明
- 使用
strip()去除输入内容前后的空格,避免用户输入空字符导致误判 - 通过
disabled= not (input_filled and output_filled)实现双向状态控制:填充完成启用按钮,清空任意一个则自动禁用 - 用Key索引代替数字索引,后续调整界面控件时不会破坏原有逻辑
内容的提问来源于stack exchange,提问作者Abd El Oihabe
相关产品推荐
相关产品推荐

