如何使用tk连续更新ruby中的图形窗口

时间:2014-03-24 16:44:53

标签: ruby tk

我正在寻找一种动态的方式'在ruby / tk中以实时方式更新变量(以及正在显示的内容)。有人可以帮助修改下面的代码,使我在运行程序时能够通过直接从一段ruby代码中为其赋值来更新blah_text的值吗?

require 'tk'
require 'tkextlib/tile'
root = TkRoot.new()
blah_text="yolo"
blah = Tk::Tile::Label.new(root) {text blah_text}.grid
Tk.mainloop()

e.g:

magic-procedure 
{
  while (1)
  {
    reads some comma delimited text from a filehandle
    based on the above assigns some value to blah_text_from_file
  }
}

require 'tk'
require 'tkextlib/tile'
root = TkRoot.new()
blah_text=blah_text_from_file
blah = Tk::Tile::Label.new(root) {text blah_text}.grid
Tk.mainloop()

期望的效果:

tk窗口使用我们分配给' blah_text_from_file'的值继续更新文本。直到我们关闭它

1 个答案:

答案 0 :(得分:0)

我相信以下代码可以产生您想要的效果,并且还可以处理Unicode。

在关闭Tk窗口之前,它会通过读取您写入特定文件的字符来不断更新显示的文本。

使用以下代码创建“ continuous_update.rb”:

# coding: utf-8

require 'tk'
require 'tkextlib/tile'

def lambda_clock_tick
  @lambda_clock_tick ||= Kernel.lambda do
    v_clock.value = v_clock + 1
# For later, schedule another clock tick:
    milliseconds = 1000
    Tk.after milliseconds, lambda_clock_tick
  end
end

def lambda_stream_read
  @lambda_stream_read ||= Kernel.lambda do
    entire_contents = nil
    raw = stream.gets entire_contents
    unless raw.nil?
      s = raw.chomp
      v_accumulator.value += s unless s.empty?
    end
# For later, schedule another read:
    milliseconds = 500
    Tk.after milliseconds, lambda_stream_read
  end
end

def main
  l_clock
  l_accumulator # Keep before reading the stream.
  v_clock.value = 1
  lambda_clock_tick.call
  lambda_stream_read.call
  Tk.mainloop
end

def stream
  @stream ||= begin
    filename = File.expand_path 'continuously_update_stream.txt', __dir__
    File.open filename, 'rb:UTF-8:UTF-8'
  end
end

# Tk objects:

def f_content
  $f_content ||= begin
    f = Tk::Tile::Frame.new root
    f.padding '4 4 4 4' # Left, Top, Right, Bottom.
    f.grid sticky: :wnes
  end
end

def l_accumulator
  @l_accumulator ||= begin
    pixels = 200
    l = Tk::Tile::Label.new f_content
    l.textvariable v_accumulator
    l.wraplength pixels
    l.grid
  end
end

def l_clock
  @l_clock ||= begin
    l = Tk::Tile::Label.new f_content
    l.textvariable v_clock
    l.grid sticky: 'w'
  end
end

def root
  $root ||= begin
# Tell Tk which encoding to use:
    Tk::Encoding.encoding = ''.encoding
    TkRoot.new
  end
end

def v_accumulator
  @v_accumulator ||= TkVariable.new ''
end

def v_clock
  @v_clock ||= TkVariable.new ''
end

main

使用以下代码在同一目录中创建“ continuous_update_testbed.rb”:

# coding: utf-8

def console_filehandle
  @console_filehandle ||= begin
    filename = 'con:' # If not on Windows, change this.
    File.open filename, 'r:UTF-8:UTF-8'
  end
end

def console_read
  console_filehandle.readline.chomp
end

def main
  stream # Initialize output file.
  transfer_unicode
  transfer_ascii_from_console
end

def stream
  @stream ||= begin
    filename = File.expand_path 'continuously_update_stream.txt', __dir__
    File.open filename, 'w:UTF-8:UTF-8'
  end
end

def stream_write(s)
  stream.puts s
# See:
#   http://bugs.ruby-lang.org/issues/9153
#   http://stackoverflow.com/questions/6701103/understanding-ruby-and-os-i-o-buffering

  stream.flush
end

def transfer_ascii_from_console
  until 'stop' == (line = console_read)
    stream_write line
  end
end

def transfer_unicode
# Avoid Unicode problems on Windows console keyboard.
# See:
#  http://stackoverflow.com/questions/388490/how-to-use-unicode-characters-in-windows-command-line
#  http://utf8everywhere.org/
#  http://www.honeybadger.io/blog/data-and-end-in-ruby/

  DATA.each_line {|e| stream_write e}
end

main

# The following is "Hello" in Greek:
__END__
γεια σας

运行方法如下:

  1. cmd控制台中,启动测试平台程序;
  2. 在另一个cmd控制台中(使用相同的工作目录),启动另一个程序(即图形程序);和
  3. 在第一个控制台(即测试平台程序的控制台)中输入一些随机单词。

在Windows 7上使用Tk 8.5.12和Ruby 2.2.5进行了测试。