我正在构建一个 Ruby 应用程序,它由负责程序逻辑的代码和用于 GUI 的代码组成。代码的两个部分都拆分为类并在单独的线程中运行。
Ruby Gtk 库的文档记录很差。我想知道如何实时更新特定的 Gtk 元素(例如,标签中的文本,在窗口中)。我想每秒更新一个特定元素。
我还想了解线程如何交换数据。我试过使用队列库。当我使用它时,我在控制台中遇到错误:
undefined local variable or method `queue' for #<TimerWindow:0xa36d634 ptr=0xb4201178>
程序代码:
require_relative 'notifications'
require_relative 'settings_reader'
require 'gtk3'
require "thread"
q = Queue.new
class TimerWindow < Gtk::Window
def initialize
@label = ""
super
init_ui
end
def init_ui
fixed = Gtk::Fixed.new
add fixed
button = Gtk::Button.new :label => "Quit"
button.set_size_request 80, 35
button.signal_connect "clicked" do
@label.set_text q.pop
end
fixed.put button, 50, 50
set_title "Tomatono"
signal_connect "destroy" do
Gtk.main_quit
end
set_border_width 10
@label = Gtk::Label.new "HEY"
fixed.put @label, 20, 20
set_default_size 250, 200
set_window_position :center
show_all
end
end
class Timer
def initialize
# Current time in seconds
@time = 0
settings = Settings_Reader.new
@work_time = Integer(settings.work_time) * 60
@break_time = Integer(settings.break_time) * 60
@work_text = settings.work_text
@return_text = settings.return_text
@break_text = settings.break_text
@work_notif_header = settings.work_notif_header
@break_notif_header = settings.break_notif_header
@status_notif_header = settings.status_notif_header
@work_status = settings.work_status
@break_status = settings.break_status
end
def launch
while true
work_time()
break_time()
end
end
def work_time()
puts @work_text
notification = Notif.new(@work_notif_header, @work_text)
notification.post
@time = 0
sleep(1)
while @time < @work_time
@time += 1
puts "#{min_remaining()} minutes remaining" if (@time % 60) == 0
if (@time % 60) == 0
notification = Notif.new(@work_notif_header, "#{@work_status} #{@time / 60} minutes.")
notification.post
end
q << @time
sleep(1)
end
end
def break_time
puts @break_text
@time = 0
sleep(1)
while @time < @break_time
@time += 1
puts "#{min_remaining()} minutes remaining" if (@time % 60) == 0
notification = Notif.new(@break_notif_header, "#{@break_status} #{@time / 60} minutes.")
notification.post
q << @time
sleep(1)
end
end
def reset
end
def stop_time
end
def min_remaining()
(1500 - @time) / 60
end
end
app = Thread.new {
timer = Timer.new
timer.launch
}
gui = Thread.new {
Gtk.init
window = TimerWindow.new
#window.update
Gtk.main
}
app.join
gui.join
每当我按下“退出”按钮时,我希望标签文本更改为在 Timer 类中设置的 q 变量中设置的值(在 while 循环中)。但它会抛出一个变量不存在的错误。它不应该是全球性的吗?