Как отобразить список или текст во время работы программы

Это моя кодировка. Я столкнулся с проблемой, когда он не отображал ".display_message", пока он еще работает. Я получаю сообщение только после того, как proc torun {} выполнит свою задачу. Кстати, после 2000 года моя программа работает. Это очень длинный код, и я считаю, что он неприменим, поэтому я удалил его, чтобы упростить. Пожалуйста, ведите меня в этом. Благодарю.

proc torun {} {
    set total [.display_pc2 size]
    .display_message insert end "test" 


    for {set x 0} {$x < $total} {incr x} {
        set machine [.display_pc2 get $x]
            .display_message insert end "Copy to $machine now. Please wait..."
            .display_message see end
            after 2000
            .display_message insert end "Copy to $machine done"
            .display_message see end
            after 2000
    }
}

2 ответа

Вы должны полностью изменить способ написания этого кода и использовать обратные вызовы.

Идея состоит в том, что вы создаете список "задач", которые нужно выполнить (возможно, это был бы список целевых компьютеров), сохраняете его где-то, а затем обрабатываете его по одному элементу за раз, перепланируя выполнение с помощью обратного вызова в режиме ожидания.

Эскиз следует:

proc show_transfer_start {target} {
  .display_progress add ... $target
}

proc show_transfer_result {res} {
  .display_progress add ... $res
}

proc schedule_transfer {target rest} {
  after idle [after 0 [list do_step $target $rest]]
}

proc do_step {target rest} {
  set res [copy --to $target]
  show_transfer_result $res
  if {[llength $rest] > 0} {
    set next [lindex $rest 0]
    show_transfer_start $next
    schedule_tranfer $next [lrange $rest 1 end]
  }
}

set targets [list box1 box2 box3]
set first [lindex $targets 0]
show_transfer_start $first
schedule_transfer $first [lrange $targets 1 end]

Я никогда не делал тк (если это GUI, что вы делаете), но, возможно, вам нужен какой-то эквивалент flush когда используешь puts принудительно отобразить сообщение.

Так как я не могу догадаться, что сделано внутри .display_message Proc.

Редактировать:

Просто пришла идея: вы можете использовать after команда подделать многопоточность вашего приложения.

after 0 [list .display_message insert end "Copy to $machine now. Please wait..."; .display_message see end]

Который будет работать независимо от вашего текущего процесса в качестве обработчика событий. Может, это решит твою проблему с флешем. (Требуется Eventloop или update команда)

Другие вопросы по тегам