Я пытаюсь создать немодальный диалог, поскольку всякий раз, когда появляется диалоговое окно, останавливается процесс реального времени, который выполняется в главном gui, после некоторого повторного поиска я понимаю, что проблема, вызывает остановку в реальном времени части - это команда «vwait» в процедуре диалога. Как я могу сделать мой текущий диалог немодальным, чтобы он не влиял на процесс реального времени в спине? Должен ли я помещать msgDialog в другой поток каждый раз, когда я вызываю proc? или каким другим способом я могу это сделать?Как создать немодальное диалоговое окно в tcl/tk
TCL КОД:
proc MsgDialog {w message type icon} \
{
if {![winfo exists $w]} {
set dialColor white
image create photo .alert -format PNG -file alertIcon.png -width 40
image create photo .question -format PNG -file questionicon.png
toplevel $w -borderwidth 2 -relief raised -background $dialColor
wm overrideredirect $w 1
set x [expr { ([winfo vrootwidth $w] - 350 )/2 }]
set y [expr { ([winfo vrootheight $w] - 190)/2 }]
wm geometry $w 350x190+${x}+${y}
frame $w.msgPnl -relief flat -borderwidth 1 -background $dialColor -width 280 -height 140
place $w.msgPnl -x 0 -y 0
frame $w.imgPnl -relief flat -borderwidth 1 -background $dialColor -width 50 -height 140
place $w.imgPnl -x 285 -y 0
frame $w.btnPnl -relief flat -borderwidth 1 -background $dialColor -width 300 -height 50
place $w.btnPnl -x 0 -y 130
label $w.msgPnl.message -text $message -background $dialColor -justify center -wraplength 270 -font dialogFont
pack $w.msgPnl.message -anchor center -pady 20 -padx 10 -expand 1 -fill both
if {$type == "ok"} {
button $w.btnPnl.okbut -text "OK" -background black -foreground white -relief flat -command {set _res "ok"} -width 8 -height 2 -highlightthickness 2 -font boldFont
grid $w.btnPnl.okbut -row 1 -column 1 -padx 125
} elseif {$type == "yesno"} {
button $w.btnPnl.yes -text "Yes" -background black -foreground white -relief flat -command {set _res "yes"} -width 8 -height 2 -highlightthickness 2 -font boldFont
button $w.btnPnl.no -text "No" -background black -foreground white -relief flat -command {set _res "no"} -width 8 -height 2 -highlightthickness 2 -font boldFont
grid $w.btnPnl.yes -row 1 -column 1 -padx 50
grid $w.btnPnl.no -row 1 -column 2
} else {
button $w.btnPnl.okbut -text "OK" -background $btnColor -relief flat -command {set _res "ok"} -width 8 -height 2
pack $w.btnPnl.okbut -side top -anchor center
}
if {$icon == "alert"} {
label $w.imgPnl.alertI -image .alert -compound top -background $dialColor
pack $w.imgPnl.alertI -fill both -expand 1 -pady 20
} elseif {$icon == "question"} {
label $w.imgPnl.quest -image .question -compound top -background $dialColor
pack $w.imgPnl.quest -fill both -expand 1 -pady 20
} else {
label $w.imgPnl.alertI -image .alert -compound top -background $dialColor
pack $w.imgPnl.alertI -fill both -expand 1 -pady 20
}
raise $w
vwait _res
destroy $w
return $::_res
}
}
я что-то вроде этого пытается, но когда я получаю неправильное имя команды MsgDialog
set tid [thread::create {thread::wait}]
::thread::send -async $tid {MsgDialog .dialog "Are you ready for measurement ?" yesno question} answer
vwait answer
if {$answer == yes} {
#do something
}
Хорошим способом обработки немодального взаимодействия является вызов вызывающего абонента MsgDialog для запуска обратного вызова при завершении взаимодействия. (Затем вы можете распутать поток выполнения, чтобы сделать что-то, что выглядит модально в работе с помощью сопрограмм 8.6.) –
Спасибо Эрик, я думаю, что понимаю, что вы имеете в виду, что вы имеете в виду идентификатор окна? –
В вашем коде это было $ w, которое является локальной переменной. Значение, хранящееся в $ w, должно быть доступно для proc, который выполняет уничтожение окна. И предложение Донала о прохождении обратного вызова - это надежный способ обработки имени proc для вызова нажатием кнопки без жесткого кодирования. –