繁体   English   中英

Tcl/Tk - 如何在单独的 function 仍在运行时保持其他按钮可用?

[英]Tcl/Tk - How to keep other buttons useable while separate function still running?

我对 Tcl/Tk 很陌生,过去几天一直在处理一个问题。 基本上我有一个用 C 编写的服务器和一个用 Tcl/Tk 编写的客户端 GUI。 到目前为止,它并没有做很多事情。 为了测试它,我启动了服务器,让它监听连接,然后运行我的 GUI。 当我单击其中一个按钮时,GUI 应该打开一个单独的顶层 window,其中嵌入了一个文本小部件。 (这部分有效。)然后,我的客户端连接到服务器并为其提供了一些设置,然后服务器决定发送回哪些信息。 服务器的响应是打印到第二个窗口的文本小部件的内容。

我现在要添加的是一个停止按钮。 现在,我的服务器设置为等待几秒钟,然后将相同的消息写入客户端。 这是在等待从我的客户端听到“停止”命令的循环中设置的。 我在 GUI 中有一个停止按钮,其中设置了一个命令,以便在单击时将该命令写入服务器。 但是,当我点击开始按钮并将消息写入客户端时,我的所有按钮都会被冻结。

基本上,我怎样才能继续允许我的服务器写入我的客户端,同时仍然保持我的 GUI 的 rest 可用? 我希望我的客户端在收到来自服务器的新消息时在我的单独 window 上的文本小部件上写一个新行,但我仍然希望主 GUI window 具有我的所有命令按钮独立运行。

一般来说,这取决于您所做的是 CPU 密集型(从普通文件读取算作 CPU 密集型)还是 I/O 密集型(在另一个进程中运行的东西算作 I/O 密集型;数据库尽管实际上并不需要,但调用通常在这里算作 CPU 密集型的)。 我只会提到正在发生的事情的摘要,因为您没有提供足够的信息。

对于 I/O 密集型代码,您希望将代码结构化为事件驱动的。 Tcl 对此有很好的工具,因为fileevent在 sockets、所有支持的平台上的终端和管道上都能很好地工作。 Tcl 8.6 的coroutine系统可以帮助防止所需的回调将您的代码变成一团乱麻!

对于 CPU 密集型代码,主要选项是在另一个线程中运行。 该线程将无法直接接触 GUI(反过来将可以自由响应),但将能够完成所有工作并将消息发送回主线程,并使用它想要完成的任何 UI 更新。 从技术上讲,您也可以使用 I/O 密集型代码来执行此操作,但它比使用协程更令人恼火。)将事情转移到子进程只是另一种变体,其中通信成本更高(但很多隔离是由操作系统)。


如果您正在处理 sockets,那么您可能是I/O 密集型的。 假设,直到你另有显示。 这是一个简单的例子:

proc gets_async {sock} {
    set sock [lindex $args end]
    fileevent $sock readable [info coroutine]
    while {[gets $sock data] < 0 && [fblocked $sock]} {
        yield
    }
    fileevent $sock readable {}
    return $data
}

proc handler {socket} {
    set n 0
    while {![eof $socket]} {
        # Write to the server
        puts $socket "this is message [incr n] to the server"
        # Read from the server
        puts [gets_async $socket]
    }
    close $socket
}

proc launchCommunications {host port} {
    set sock [socket $host $port]
    fconfigure $sock -blocking 0 -encoding utf-8
    coroutine comms($host:$port) handler $socket
}

请注意, gets_async很像coroutine::util getsTcllib中获取。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM