I am new to Ruby and I would like to receive input from users with Ruby TK. The Internet has too little information about this. So I am here to search for a solution. Below is the current method that I am using.
TkSpinbox.new(left) do
to 100
from 1
value = TkVariable.new()
increment value += 1
command (proc{
puts value
})
pack("side" => "bottom", "padx"=> "50", "pady"=> "54")
end
I have no idea how to get the value inside the spinbox and return it to another place. This is the screenshot of the GUI.
There are a couple of little changes you can make to that code snippet which will let you access the spinbox value correctly:
The increment method takes one argument, the amount to increment the value by every time you click a button. So you can replace increment value += 1 with just increment 1.
You don't need the value = TkVariable.new() line, because the TkSpinbox keeps track of its value itself. (If you did want to set an initial value, you would use e.g. self.value = 10.)
After making those changes, this is the final code snippet:
TkSpinbox.new(left) do
to 100
from 1
increment 1
# Equivalent to your proc({...}) usage here, but this is better Ruby style
command do
puts value
end
pack("side" => "bottom", "padx"=> "50", "pady"=> "54")
end
And here's how it looks when you click the increment button several times:
To use the value from some other control like a button, you can assign your TkSpinbox to a variable and access its value from another command block:
# Assign spinbox to a variable named `spinbox`
spinbox = TkSpinbox.new(left) do
to 100
from 1
increment 1
command do
puts value
end
pack("side" => "bottom", "padx"=> "50", "pady"=> "54")
end
TkButton.new(left) do
text "Do something with the value"
command do
# Now `spinbox` is usable from other controls
# (The value may be a string, so we use .to_i to convert to an integer)
puts spinbox.value.to_i * 100
end
pack("side" => "top")
end
Related
I'm trying to generate a table while changing the background color of a cell under a condition. I've resorted coming to here for help. Here's an example of what I'm trying to do:
idx = 0
pdf.table(myTable) do
style(row(0), :background_color => 'ff00ff')
style(column(0))
while idx <= totalRows
if cells[idx,3] == "No go"
style(cells[idx,3], :background_color => 'fF0000')
else
style(cells[idx,3], :background_color => '00FF22')
end
idx += 1
end
end
Call #style correctly
In version 0.2.2 of prawn-table, the #style method is defined on a cell, or an array of cells, so you need to get that first. The argument is merely a hash of the keys and values for the styles you want. For example, row(0) is an array of cells, so you can style it with a magenta background like this:
pdf.table(myTable) do
row(0).style(:background_color => 'ff00ff')
end
You can refer to the full source code of #style at
https://github.com/prawnpdf/prawn-table/blob/0.2.2/lib/prawn/table/cells.rb#L139 and
https://github.com/prawnpdf/prawn-table/blob/0.2.2/lib/prawn/table/cell.rb#L227
column(0)
I am not sure what you want the line style(column(0)) to do, so I can't advise on that.
Condition when "No go"
It looks like you want the while loop to apply a condition to the fourth column, so that cells whose content is 'No go' are red, while the rest are green.
For this, you can use the iterator built-in to the #style method, instead of your while loop. It could look like this:
column(3).style do |cell|
if cell.content == "No go"
cell.style(:background_color => 'ff0000')
else
cell.style(:background_color => '00ff22')
end
end
If you wanted something slightly different you should know enough now to vary the code.
I created a list of optionMenus via a for loop. I need to tie my optionMenu selection to the optionMenu it came from. The for loop, I think, is making it so I am unable to tie the two values together.
def get_selection(choice):
popUp_list.append(choice)
if num >= 1 and num <5:
for num in range(1,5):
choice = StringVar(root2)
choices = {'Application', 'File', 'Website'}
choice.set('Choose Type')
popUpMenu = OptionMenu(root2, choice, *choices, command = Controller.get_selection)
popUpMenu.grid(row=num, column=0)
I know it would be easier to hard code the option menus, but for reasons I don't want to get in to, the for loop is necessary. Not for this part specifically, but for another part of my code. It's just easier to use this example here.
When an option is selected from the menus, I am able to pull the values and that works great. However, if a user makes a first selection and then wants to update their selection, I have no way to capture that. It creates a "new" selection, not tied to the optionMenu. So the new option does not replace the old option. It just creates a new selection.
Is there a way to pass the popUpMenu number through the Controller .get_selection function? When trying to pass another variable doing something on the lines of:
def get_selection(choice, num):
popUp_list.append(choice)
print(num)
popUpMenu = OptionMenu(root2, choice, *choices, command = lambda: Controller.get_selection(choice, num))
I get the error below and I'm not able to get the option selection. I'm not sure what to put as the first value. Inputting choice does not work.
self.__callback(self.__value, *args)
TypeError: () takes 0 positional arguments but 1 was given
I was able to solve this. I updated my code to :
if num >= 1 and num <5:
for num in range(1,5):
choice = StringVar(root2)
choices = {'Application', 'File', 'Website'}
choice.set('Choose Type')
popUpMenu = OptionMenu(root2, choice, *choices, command = lambda choice = choice, num = num: (Controller.get_selection(choice, num)))
So, making your command statement like:
command = lambda choice = choice, num = num: (Controller.get_selection(choice, num)))
allows you to pass variables into your function.
With the following statement
print #b>#d?("S";#b+=1): #b<#d?("N";#b-=1):""
I want S to be output to the screen and then the value of b incremented if the val of b is higher than d. Otherwise check if b is lower than d and decrement b.
However, it seems that the value of b + 1 is printed instead. What is going on here?
In ruby methods, always the last line is returned by default. Change your code to
print #b>#d?(#b+=1; "S"): #b<#d?(#b-=1; "N"):""
In order to do what you want as an output.
The value of b+1 is the last thing returned here: ("S";#b+=1), thus, it is what gets evaluated by print. Let us try a simpler example:
x = 0
# => 0
puts (true ? ("X is incremented #{x+=1}"; "Only this is printed though") : "Never here")
# Only this is printed though
# => nil
x
# => 1
Although the first statement is executed, which increments x, only the last statement is passed as an argument to puts.
My question is, how can I search through an array and replace the string at the current index of the search without knowing what the indexed array string contains?
The code below will search through an ajax file hosted on the internet, it will find the inventory, go through each weapon in my inventory, adding the ID to a string (so I can check if that weapon has been checked before). Then it will add another value after that of the amount of times it occurs in the inventory, then after I have check all weapon in the inventory, it will go through the all of the IDs added to the string and display them along with the number (amount of occurrences). This is so I know how many of each weapon I have.
This is an example of what I have:
strList = ""
inventory.each do |inv|
amount = 1
exists = false
ids = strList.split(',')
ids.each do |ind|
if (inv['id'] == ind.split('/').first) then
exists = true
amount = ind.split('/').first.to_i
amount += 1
ind = "#{inv['id']}/#{amount.to_s}" # This doesn't seem work as expected.
end
end
if (exists == true) then
ids.push("#{inv['id']}/#{amount.to_s}")
strList = ids.join(",")
end
end
strList.split(",").each do |item|
puts "#{item.split('/').first} (#{item.split('/').last})"
end
Here is an idea of what code I expected (pseudo-code):
inventory = get_inventory()
drawn_inv = ""
loop.inventory do |inv|
if (inv['id'].occurred_before?)
inv['id'].count += 1
end
end loop
loop.inventory do |inv|
drawn_inv.add(inv['id'] + "/" + inv['id'].count)
end loop
loop.drawn_inv do |inv|
puts "#{inv}"
end loop
Any help on how to replace that line is appreciated!
EDIT: Sorry for not requiring more information on my code. I skipped the less important part at the bottom of the code and displayed commented code instead of actual code, I'll add that now.
EDIT #2: I'll update my description of what it does and what I'm expecting as a result.
EDIT #3: Added pseudo-code.
Thanks in advance,
SteTrezla
You want #each_with_index: http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-each_with_index
You may also want to look at #gsub since it takes a block. You may not need to split this string into an array at all. Basically something like strList.gsub(...){ |match| #...your block }
In my code I have a hash, each one with a set value of 0, after running through the code, I would like it to display "1", but it only displays a 0. Can anyone help, and please explain my error and why it didn't work.
puts "Hello!, and welcome to the 'Coin Calculator V1.0', please enter a value."
coin_value = gets.to_i
coin_num = {"quarters" => 0,"dimes" => 0,"nickels" => 0,"pennies" => 0}
if coin_value>25
coin_value-25
coin_num["quarters"]+1 // **basically, how do I add an integer value to the old integer?
puts coin_num["quarters"]
end
coin_num["quarters"] = coin_num["quarters"] + 1
which can be shortened using the += operator (addition assignment):
coin_num["quarters"] += 1
Neither of your arithmetic expressions changes anything.
coin_value - 25
That evaluates to 25 less than coin_value; if you printed it out or assigned it somewhere, you would see that. But since you don't do anything with the value, it just gets thrown away and nothing happens. Certainly, coin_value doesn't change.
Similarly,
coin_num["quarters"] + 1
evaluates to one more than the current value of coin_num["quarters"], but doesn't change anything.
If you want to change the value of a variable - any variable, whether a simple scalar like coin_value or an element of a Hash or Array - you have to use an assignment statement. You need an =, and the variable you want to change has to be on the left hand side of that =:
coin_value = coin_value - 25
coin_num['quarters'] = coin_num['quarters'] + 1
Ruby does define shorthand operators for modifying a variable using a simple expression involving that same variable's previous value:
coin_value -= 25
coin_num['quarters'] += 1
But you're still using = - it's just part of a compound assignment operator now.