tcl / tk在不同的线程中创建/修改窗口小部件

时间:2013-12-19 17:10:33

标签: multithreading tcl tk

我想要做的是修改或创建一个在主线程中从不同线程创建的小部件,我读到tk不是安全线程,我无法完成此任务。我只想在尝试这样做时用尽我的选择。当我尝试创建一个小部件时,例如:

set threadID [thread::create {

    label .test -text "hello" 

    thread::wait
}]

我也试试这个:

label .test -text ""        
set threadID [thread::create]
thread::send $threadID [list .test configure -text "HEllo World"] 

这给我一个错误,说命令标签无效,那么有没有办法从不同的线程创建/修改一个小部件?

2 个答案:

答案 0 :(得分:2)

这是不可能的。如果您需要从不同的线程访问/修改小部件,我建议采用以下方法:

  • 使用单个GUI线程。将线程ID传递给所有必需的线程。
  • 使用thread::send将读/写命令发送到GUI线程(可能处于阻塞模式)。

您必须自行决定何时必须使用-async标志。

线程安全工具包很少见(如果可能的话),例如Java的Swing不是线程安全的。通常的方法是将消息发布到AWT-Thread中处理的事件队列(例如,使用SwingUtilities.invokeLater),就像这里一样。

答案 1 :(得分:1)

每个小部件都与单个解释器紧密相关,并且每个解释器都与单个线程紧密相关;你想要什么都行不通。

最简单的解决方法是将命令放在委托给GUI线程的其他线程中,以修改小部件:

pack [label .l]
thread::send $threadID "
    proc .l args {
        thread::send [thread::current] \[list .l {*}\$args\]
    }
"

之后,其他线程可以使用:

.l configure -text "Hello, World!"

它会起作用。好吧,主要是。 (-textvariable选项不会跨越线程而没有相当多的带有跟踪的魔法,并且图像也是解释器绑定的。)您也将无法在没有更多的情况下调整窗口小部件的几何管理工作,但这不是一个常见的问题。

另一种方法是在-use的框架中嵌入带有-container的顶层,但这不是我获得最大成功的选项。不过,它应该跨进程工作(好吧,无论如何在Unix / X11上),所以它也可以用于线程。