Ruby TkButton won't run proc - ruby

I have a ruby program that uses the TK gui package and I am having trouble with TkButton, specifically the command part. I am trying to run a method that's in the same class when the button is clicked. My code is below. I'm very new to Ruby but not programming in general. When the button is clicked in the gui I get an Application error that says "Error: NameError: unknown option..." where it identifies the method call in the button as the error cause. Can someone explain what I'm doing wrong? I'm using RubyMine to develop.
Code:
require 'tk'
require 'test/unit'
require_relative 'calc'
require_relative 'calcTest'
class CalcUIK
def test_add
calc = Calc.new
expected = Calc.add tk6.get().to_i,tk6.get().to_i
tk8['textvariable'] = 'Result: ' + expected
end
hello = TkRoot.new do
title "Hello World"
# the min size of window
minsize(400,400)
end
tk1 = TkLabel.new(hello) do
text 'Super Calculator'
foreground 'red'
pack { padx 15; pady 15; side 'left'}
end
tk5 = TkLabel.new(hello) do
text 'Enter two numbers to math'
foreground 'blue'
pack { padx 15; pady 15; side 'left'}
end
tk6 = TkEntry.new(hello) do
foreground 'blue'
pack { padx 15; pady 15; side 'left'}
end
tk7 = TkEntry.new(hello) do
foreground 'blue'
pack { padx 15; pady 15; side 'left'}
end
tk8 = TkLabel.new(hello) do
textvariable
foreground 'blue'
pack { padx 15; pady 15; side 'left'}
end
tk2 = TkButton.new(hello){
text 'Add'
command (proc {self.test_add})
pack('padx'=>'20')
pack('side'=>'left')
}
end
Tk.mainloop
PS I know that this code is kind of dumb but it is just a dummy program to set some more important things up. The issue I need to resolve is why the button click is not executing the test_add method. Thanks.

You've defined an instance method on your class called test_add, but in the context in which your "Add" button is defined, self refers to the class CalcUIK. Edit - now that I think about it, I think since self occurs within a block given to TkButton.new, self refers to the new instance of TkButton, which is trying to receive the test_add method, but doesn't recognize it as a valid option. Define the proc as proc { CalcUIK.new.test_add } to generate a new instance that will run the method.
I would also recommend moving all of the TkRoot, TkButton, etc. calls either outside the class entirely, or move them into an initialize method on CalcUIK. Right now, they are run as the class is evaluated, but it's very unusual to have code that is unrelated to the class executed within the context of the class definition.

Related

Music and image failed to initialize

I was trying to make a multiple-choice music player using Gosu but the picture and music Iwanted would not initialize despite the program running, it showed a black screen. The single block of codes works:
require 'gosu'
require './input_functions'
class MW < Gosu::Window
def initialize
super 200, 135
#beth = Gosu::Image.new("media/beth.jpg")
#song = Gosu::Song.new("media/3rdmovement.mp3")
#song.play
end
def draw
#beth.draw(0, 0)
end
end
window = MW.new
window.show
But adding the multiple choice elements would not work(note: read_integer_in_range is defined in input function, the name itself is self explanatory). Full code:
require 'gosu'
require './input_functions'
class MW < Gosu::Window
def initialize
super 200, 135
#beth = Gosu::Image.new("media/beth.jpg")
#dimitri = Gosu::Image.new("media/dimitri.png")
#vil = Gosu::Image.new("media/vilva.png")
#song = Gosu::Song.new("media/3rdmovement.mp3")
#song2=Gosu::Song.new("media/2ndwaltz.mp3")
#song3=Gosu::Song.new("media/1stseason.mp3")
read_integer_in_range( "What song you want play
1st Spring
2nd Waltz
3rd movement", 1, 3)
choice = gets.chomp.to_i()
case choice
when 1
#song3.play
#vil.draw(0, 0)
when 2
#song2.play
#dimitri.draw(0, 0)
when 3
#song.play
draw_beth()
end
end
end
def draw_beth
#beth.draw(0, 0)
end
window = MW.new
window.show
All of the Png/Jpg and mp3 file works just fine..
I tried separating the draw_beth to call it in case but it did not work. I hope some passing by could help me with this one
As I can see, you are creating a music player with GUI, and if you are doing so, you shouldn't use gets function, instead you should track for the cursor's position and return a test value; for example:
def update
#locs = [mouse_x, mouse_y]
#cursor_choice_album = mouse_over_button(mouse_x, mouse_y)
end
def needs_cursor?; true; end
def mouse_over_button(mouse_x, mouse_y)
if ((mouse_x > 100 and mouse_x < 500) and (mouse_y < 500 and mouse_y > 100))
return 1
end
then you can use the case condition in the "button down ID" function

`no implicit conversion of nil into String` wih ruby2d

So for practice with ruby, I am creating a library on top of ruby2d, but one problem.
I keep getting an error, I think setting up a window, here is the full error:
C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/ruby2d-0.11.3/lib/ruby2d/window.rb:476:in `exist?': no implicit conversion of nil into String (TypeError)
from C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/ruby2d-0.11.3/lib/ruby2d/window.rb:476:in `add_controller_mappings'
from C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/ruby2d-0.11.3/lib/ruby2d/window.rb:629:in `ext_show'
from C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/ruby2d-0.11.3/lib/ruby2d/window.rb:629:in `show'
from C:/Users/Admin/Desktop/RubyProjects/RSGE/rsge_window.rb:19:in `mainloop'
from c:/Users/Admin/Desktop/RubyProjects/test.rb:4:in `<main>'
it shows that something is wrong in ruby2d (a graphics library for ruby)
here is the code for my test file that uses my library
require './RSGE/rsge'
root = Window.new(800, 800)
root.mainloop
and here is my window class:
require 'ruby2d'
require_relative 'rsge_colors'
class Window
def initialize (w, h)
#width = w.to_i
#height = h.to_i
#title = 'Blank Window'
#background = $WHITE
end
def config
set width: #width, height: #height
set background: #background
set title: #title
end
def mainloop
show
end
end
if your wondering what rsge_colors is, here it is
$RED = 'red'
$GREEN = 'green'
$BLUE = 'blue'
$ORANGE = 'orange'
$PURPLE = 'purple'
$YELLOW = 'yellow'
$WHITE = 'white'
$BLACK = 'black'
Why am I getting this error, and how can I fix it?
Thank you for any help you can give me!
Defining class Window looks like you're overriding Ruby2D::Window class.
I've never used this library, but looking the code for some of the games in the showcase, and also the "Get started" section, it looks like the dsl must be used in the root level of your ruby file.
In your case, it should be something like:
require 'ruby2d'
require_relative 'rsge_colors'
set width: 800, height: 800
set background: $WHITE
set title: 'Blank Window'
show
Probably there must be a way to encapsulate the code into classes or modules, but if you're just learning to use the gem, probably would be better to start with the basic stuff then move to refactor these type of things.

Program not running

I have been trying to execute the following code using the command prompt. However, when I try to run it I get the following
C:>circle
C:>
Basically, nothing happens. However, I cannot figure out why this is happening as I am still new to Gosu and Ruby in general. Any help would be much appreciated.
require "rubygems"
require "gosu"
class Circle
attr_reader :columns, :rows
def initialize(radius)
#columns = #rows = radius * 2
img = Gosu::Image.new(Circle.new(50))
img.draw(200, 200, ZOrder::TOP, 0.5, 1.0, Gosu::Color::RED)
clear, solid = 0x00.chr, 0xff.chr
lower_half = (0...radius).map do |y|
x = Math.sqrt(radius ** 2 - y ** 2).round
right_half = "#{solid * x}#{clear * (radius - x)}"
right_half.reverse + right_half
end.join
alpha_channel = lower_half.reverse + lower_half
# Expand alpha bytes into RGBA color values.
#blob = alpha_channel.gsub(/./) { |alpha| solid * 3 + alpha }
end
def to_blob
#blob
end
end
There are 2 problems:
You are running file with class definition. What you need to run if you want to look at that blob is is Circle.new(10).to_blob - where 10 is radius. You can place it in separate file and require class.rb.
initialize method will be run during Circle.new()call. And you have Circle.new called in your class:
img = Gosu::Image.new(Circle.new(50))
So it will lead to infinite recursion and will cause SystemStackError. AFAIK, there is no built-in empty image constructor in gosu (maybe I am wrong).

Cannot print a text with Gosu in Ruby

Im sitting here with what I think is a very simple bug I just can not figure out.. Im trying to learn how to make games with Gosu gem with Ruby, but have hit a speed bump. Here is my code.
require "gosu"
class Hello < Gosu::Window
def initialize width = 800, height = 600, fullscreen = false
super
self.caption = "Ruby Practise"
#image = Gosu::Image.from_text self. "My text to print".
Gosu.default_font_name.
100
end
def button_down id
close if id == Gosu::KbEscape
end
def update
end
def draw
#image.draw 0, 0, 0
end
end
Hello.new.show
There is something wrong but I do not know what. I have spent at least 1 hour on it.. It complains on the String, here is the output from terminal.
hello.rb:8: syntax error, unexpected tSTRING_BEG
#image = Gosu::Image.from_text self. "My text to print".
^
hello.rb:10: syntax error, unexpected tINTEGER
I do not what I am doing wrong, do some one know? It is probably something really simple..
Use commas to separate function arguments, not dots:
#image = Gosu::Image.from_text self, "My text to print",
Gosu.default_font_name,
100

ruby Tk app running in while loop displays twice and then stops responding

I'm pretty new to ruby and am trying to implement a Tk application that will display a window prompting for input at a certain interval. In between the interval I want the window to not display in any taskbars, etc. and so I've implemented the following code that seems to work perfectly the first time through, but after the window displays the second time and I enter text in the TkEntry and click the TkButton the window is dismissed and never returns. I've tried putting in some "puts" calls at key locations to see what is happening and it seems that it never even makes it past the call to "displayUi".
*EDIT:
I'm running ruby 1.9.3p385 (2013-02-06) [i386-mingw32] on a Windows 7 system (in case that makes any difference)
Any help (even if it's providing a different mechanism to accomplish the same goal) would be appreciated, but please keep in mind that I'm a ruby noobie. Thanks!
require "tk"
class Sample
attr_accessor :root, :active
#active = false
def initialize
# init
end
def entry (task)
# do some work here
#active = false
end
def displayUi ()
#active = true
if (#root.nil?)
#root = TkRoot.new { title "Sample App" }
else
# already running just restart
Tk.restart
end
TkLabel.new(#root) {
text 'Sample Text'
pack { padx 15; pady 15; side 'left' }
}
statusInput = TkEntry.new(#root) {
pack('side'=>'left', 'padx'=>10, 'pady'=>10)
}
statusInput.focus
response = TkVariable.new
statusInput.textvariable = response
TkButton.new(#root, :text => "Ok", :command => proc { entry(response.value); #root.destroy }) {
pack('side'=>'left', 'padx'=>10, 'pady'=>10)
}
Tk.mainloop
end
end
i=0
st = Sample.new
while (true)
if (!st.active)
st.displayUi()
end
sleep(1)
end

Resources