how to change the values in a combobox dynamically in Ruby Tk - ruby

The idea is quite simple: I have 2 comboboxes. The second one should refreseh its values depending on the chose from the first one.
# combobox 1:
$shape = TkVariable.new
$combobox_1 = Tk::Tile::Combobox.new(parent) { textvariable $shape; values ['IPE', 'HEA']}
# combobox 2:
$size = TkVariable.new
$combobox_2 = Tk::Tile::Combobox.new(parent) { textvariable $size; values $size_list}
# action
$combobox_1.bind("<ComboboxSelected>") {
case $shape
when 'IPE' then $size_list = [80, 100, ...]
when 'HEA' then $size_list = [90, 130, ...]
end
}
But nothing happens. combobox 2 doesn't seem to realize that its values have been changed. how can I solve this problem?

This will not work, you used this variable to create the combo box, but changing it will not change the combobox.
I suppose what you are looking for is set
when 'IPE' then $combobox_2.values([80, 100, ...])

Related

How to set a scroll in a comboboxtext

When I use comboboxtext with a lot of options, I can see that there is no scroll. I can go up and down with the mouse, moving it or with the central button, but the typical scroll widget to move faster up and down does not appear anywhere.
How can I make the scroll widget appear in the options of the comboboxtext?
require 'gtk3'
Material2 = Gtk::ComboBoxText.new()
for i in (0..100)
string = "material " + i.to_s
Material2.append_text(string)
end
$MenuPrincipal = Gtk::Table.new(60, 60, true)
$MenuPrincipal.attach(Material2, 0, 60, 0, 10, $options, $options, 0, 0)
$window = Gtk::Window.new
$options = Gtk::AttachOptions::EXPAND | Gtk::AttachOptions::SHRINK
$window.add($MenuPrincipal)
$window.show_all
Gtk.main
Thanks in advance
You need to change (or add) line in the css style:
* {
-GtkComboBox-appears-as-list: 1;
}
If you don't have control over user's style see my answer about modifying labels' style from code (example is in python).
I have not found how to achieve it without modifying style but maybe there is some hidden gem in ruby bindings.

Function to creates buttons

I'm trying to create a function to create a button (so keep the "clean" code).
Here is the code:
(
Window.closeAll;
~w = Window.new(
name: "Xylophone",
resizable: true,
border: true,
server: s,
scroll: false);
~w.alwaysOnTop = true;
/**
* Function that creates a button.
*/
createButtonFunc = {
|
l = 20, t = 20, w = 40, h = 190, // button position
nameNote = "note", // button name
freqs // frequency to play
|
Button(
parent: ~w, // the parent view
bounds: Rect(left: l, top: t, width: w, height: h)
)
.states_([[nameNote, Color.black, Color.fromHexString("#FF0000")]])
.action_({Synth("xyl", [\freqs, freqs])});
}
)
(
SynthDef("xyl", {
|
out = 0, // the index of the bus to write out to
freqs = #[410], // array of filter frequencies
rings = #[0.8] // array of 60 dB decay times in seconds for the filters
|
...
)
The error is: ERROR: Variable 'createButtonFunc' not defined.
Why?
Sorry but I'm a beginner.
Thanks!
Probably a little late to answer this, but I hope this might help someone else with the same question.
The reason you're getting that error is because you're using a variable name before you're declared it.
In other words, if you try to evaluate
variableName
on its own, you'll always get an error, because the interpreter can't match that name to anything else it knows. To solve this, you can use a global interpreter variable (a-z), an environment variable (like ~createButtonFunc), or declare var createButtonFunc earlier on in your code. Note that this last one means you won't be able to access that variable name after interpreting that chunk, which may or may not be a good thing. If you want to be able to access it later, I think it makes the most sense to write ~createButtonFunc.
By the way, you can just use w instead of ~w; single-letter variable names are global by default, and that's the idiomatic usage.
-Brian

AdjustsFontSizeToFitWidth && numberOfLines = 0 doesn't work together as expected

let nameBox = UILabel(x: 0, y: 0, w: sideSize, h: sideSize*2/4)
nameBox.text = skillName
nameBox.textAlignment = .Center
nameBox.numberOfLines = 0
nameBox.adjustsFontSizeToFitWidth = true
nameBox.addBorderLeft(size: 1, color: UIColor.blackColor())
nameBox.addBorderTop(size: 1, color: UIColor.blackColor())
nameBox.addBorderRight(size: 1, color: UIColor.blackColor())
container.addSubview(nameBox)
This is the code I have and its output is below.
As you can see it has modified everything perfectly except for Communication & Lumberjack. Why is it, and how can I solve it?
Looks like you need to set the lineBreakMode of the label to .ByWordWrapping.
Another thought is that you really want the font to be smaller. Perhaps this is prevented by the minimumScaleFactor property.
From the docs for adjustsFontSizeToFitWidth:
The default value for this property is false. If you change it to true, you should also set an appropriate minimum font size by modifying the minimumFontSize property.
This seems to be a documentation bug. minimumFontSize is deprecated.

Ruby WIN32OLE excel chart seriescollection values

I am trying to change the values of an Excel (actually PowerPoint) chart.
I tried doing this by passing an array but it doesn't seem to work.
Although as mentioned on this page it should work...: http://msdn.microsoft.com/en-us/library/office/ff746833.aspx
So how does my code looks like at the moment:
require 'win32ole'
mspp_app = WIN32OLE.new("Powerpoint.Application")
mspp = mspp_app.Presentations.Open(pathToFile)
slide = mspp.Slides(1)
shapes = slide.shapes
chartshape = shapes(3) #the chart happens to be shape n°3
chart = chartshape.chart
# now get the seriescollection
sc = chart.SeriesCollection
sc3 = sc.Item(3)
values = sc3.values #returns the current values as an array example: [1.0, 1.0, 5.0, 2.0]
# now set the values
sc3.values = [2.0, 2.0, 5.0, 1.0] # returns no error
# see if the values are set
values = sc3.values # returns an empty Array []
Anyone tried this before?
For manipulating the diagram data you have to change the underlying worksheet:
ws = myChart.Chart.ChartData.Workbook.Worksheets(1)
ws.Range("A2").Value = "Coffee"
ws.Range("A3").Value = "Soda"
ws.Range("A4").Value = "Tea"
ws.Range("A5").Value = "Water"
ws.Range("B1").Value = "Amount" # used as label for legend
ws.Range("B2").Value = "1000"
ws.Range("B3").Value = "2500"
ws.Range("B4").Value = "4000"
ws.Range("B5").Value = "3000"
It is important to change the SourceData-Range if dimension has changed. Take care of the different notion known from Excel: "=Tabelle1!A1:B5" instead of "A1:B5".
For english office version change "Tabelle1" to "Sheet1"
myChart.Chart.SetSourceData("=Tabelle1!A1:B5")
myChart.Chart.ChartData.Workbook.Close
Don't forget to close the worksheet afterwards.

wxPython: binding a dynamically created spinner to an event

I used the code below to create several spinners with a for loop.
Now, I can't figure out how to bind an event so that I know which spinner is being modified so that I can put the spinner value into the right variable.
If I can figure out which spinner is calling the handler I could map it to the correct variable.
Any thoughts? Is this even possible?
Thanks in advance!
import wx
class spinnerFrame(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent,id, "Spinner Frame", size = (300,200))
#constants
spnr_sz = (50,-1)
names = ('name1','name2','name3','name4','name5','name6')
sizer = wx.GridBagSizer(5, 5)
# TEXT FONT EXAMPLE
# m_text = wx.StaticText(panel, -1, "Hello World!")
# m_text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
# m_text.SetSize(m_text.GetBestSize())
#temp
sizer = wx.GridBagSizer(5, 5)
row = 0
for n in names:
row += 1
my_label = wx.StaticText(self, -1, n)
spinner = wx.SpinCtrl(self, -1, size = spnr_sz, min = 0, initial = 10 )
self.Bind(wx.EVT_SPINCTRL, self.OnCompute, spinner)
sizer.Add(my_label, (row,0))
sizer.Add(spinner, (row,1))
sizer.AddGrowableRow(7)
sizer.AddGrowableCol(4)
self.SetSizerAndFit(sizer)
self.Centre()
def OnCompute(self,event):
# a = spinner.GetValue()
# ????
if __name__=='__main__':
app = wx.App(True) # was False
frame = wx.Frame(None)
frame = spinnerFrame (parent=None, id = -1)
frame.Show()
app.MainLoop()
Yes, this is possible. The easiest way I know is to associate your unique name with each call to Bind, either by giving the spinner a name or using partial functions (or lambdas, but lambdas can end up being messy), and then check for the name in the handler. Examples of how to use the name are given in this previous SO question.

Resources