Hello All,
I have finished writing up a Ruby class to complete exactly what it is supposed to, but since it is Ruby, I have been running it through my terminal and I need this to be more user-friendly (i.e. have a GUI). So I googled this and came across Shoes, which seems to be a nice Ruby GUI toolkit, and exactly what I am looking for. However, despite my googling I can't seem to figure out how to use a Shoes GUI edit line to send an argument to the class I made. Here is the edit line
Shoes.app do
background white
para "Application Name"
stack(margin: 12) do
para "Message"
flow do
edit_line
button "Enter"
end
end
end
In short, is there some way to do a gets.chomp (or literally anything else that is similar) with this and set it equal to an instance variable?
Yes! Just assign the elements you want to keep track of to instance variables, and pass a block to the button (the block gets executed when the button is clicked). Try this:
Shoes.app do
background white
para "Application Name"
stack(margin: 12) do
#message = para "Message"
flow do
#edit_line = edit_line
button "Enter" do
#message.text = #edit_line.text
end
end
end
end
Related
I am working on a ruby app that needs to update text on the GUI at unknown times. The process I am using overlaps the text with text from the previous edit.
class_text is the element I need to edit. I have about 8 different places in the program that could potentially change the text. Sometimes when the text is changed the previous text does not get removed and instead the text overlaps itself.
$class_text.text = "Nothing scheduled to take attendance at this time."
This project was started by people before me and this is my first experience with Ruby. Thank you for any info you can send my way!
without more specific information I've just tested a bare minimum for a scenario similar to yours (using Red Shoes though) and this works:
Shoes.app do
#test_stack = stack do
#edit_box = edit_box
#edit_box.text = "first text"
#edit_text = para "second text"
end
button "change" do
#edit_box.text = "first replacement"
#edit_text.text = "second replacement"
end
end
You could also try clearing the element first.
hth
seba
Is there an attribute to create a modal window e.g. one that has complete focus.
we cannot use confirm/alert etc. and i'm assuming i create a window/dialog, but its asynchronous and exits after creation?
i.e. something like
dialog :title => '', :modal=>true do
googled, been through all ruby manuals and no reference to modal/focus?
checked out the source code and had a look for modal/keep focus type parameters - couldn't find anything?
i've come across suggests for Ruby/Tk (similar type of stuff) where people have to wait in a loop for close events and exit. this seems a bit cumbersome?
any thoughts out there?
thanks
Ben
Not entirely sure what you are trying to do here. Are you trying to launch another window alongside the main window? That is well supported:
Shoes.app do
para 'first app'
button "launch second" do
Shoes.app width: 180, height: 60 do
para 'I am a second app!'
end
end
end
Although that is an entirely new window, so it might not be what you want. If you want an all focus window that is essentially part of the app and greys out the main application, then no that is not possible :( Created an issue for modals though.
I want to make my own window, using Glade (3.14.2).
At a certain point in my program, I want to
1) Put up the window and let the user do stuff
2) Wait for it to close
3) Get values from the window object
4) Continue on in my code
So basically, I want to treat the window like a modal dialog - but one that I write and control.
I've tried for a few hours. The window appears just fine, as designed in Glade. The user can interact with it.
When the window closes, code that's been connected with signal_connect('destroy') executes.
But the code that invoked the window's show() method... does not continue executing after the window closes.
class GrammarNodeEditor
#this makes the class visual:
include GladeGUI
def initialize(raw_node = nil, &close_block)
#raw_node = raw_node || {type: :Sequence, data: []}
#original_data = #raw_node[:data]
#close_block = close_block
end
def show
puts "GNE Window Opening"
load_glade(__FILE__)
#builder["window1"].title = "Edit/Create Grammar Node"
#builder["window1"].signal_connect('destroy') {|*args|
#close_block.call(self)
puts "GNE WINDOW DESTROY"
}
show_window()
puts "Done showing window"
end
Here is how I invoke it:
rhs_editor = GrammarNodeEditor.new {|obj|
puts "In closeblck, obj is #{obj.inspect}"
#rhs = obj.raw_node
}
puts "About to call show in GR:Init"
rhs_editor.show
puts "Back from calling show in GR:Init"
Here is the output:
About to call show in GR:Init
GNE Window Opening
In closeblck, obj is #<GrammarNodeEditor:0x7b82a88 #raw_node={:type=>:Sequence, :data=>[]}, [more junk here]>
GNE WINDOW DESTROY
The first two lines of output appear after I open the window. The 3rd and 4th appear when I close the window.
Note that "Done showing window" and "Back from calling show in GR:Init" are not printed at all.
Just to make this a little more interesting, I want to be able to do this from within code that puts up another window. My top-level window has a button to create a new Rule. The Rule must be initialized with a Node, and then the Rule must be edited. So first I need to put up a Node-definition window (as shown above) and then, when I have a Node defined, I want to put up a Rule window that uses that Node.
So I think I need to call this code within either the initialize() or the show() method of the GrammarRuleWindow class (another Glade-defined window).
Can someone explain why my puts's aren't being printed, and how to make the control flow go on through them?
Thanks!
...So it turned out the problem was that I had created the window's .glade file directly in Glade, rather than using the VisualRuby IDE.
Creating the .glade in VR adds some stuff to the file that VR needs. Specifically, the file needs to contain the line
<signal name="destroy" handler="destroy_window" swapped="no"/>
before the first <child...> tag.
I'm new to WATIR testing (and do I love it!) and have run into a wall on how to refocus my WATIR script to a newly opened window.. Here's my (simplified) script....
#!/usr/bin/ruby
require 'rubygems'
require 'watir-webdriver'
browser=Watir::Browser.new
browser.goto("http://0:3050")
browser.text_field(:name,"userkey300203830").set("OKJHNB")
browser.button(:id, "interview48").click
puts "Expected Result:"
puts "A successful display of cars"
if browser.window(:title=>"300203830").exists?
puts " Test passed. New window opened!"
else
puts " Test Failed! No window found"
end
It all works right up to the end. After the key "interview48" is clicked, a new window is opened with the title "300203830". Looks like I find it but I just don't know how to now focus on that window.
browser.window(:title => "300203830").use do
# do something
end
More information: http://watir.github.io/docs/browser-popups/
Additionally for more than 2 windows you can use the following:
browser.windows[n].use
#n is variable for which window. n will access them in order of opened or tabs from left to right
browser.windows.last.use
browser.windows.first.use
You can use the above commands if you open a new window from first browser instance and would like to toggle between the two.
There are 3 primary selectors for windows:
:title - typically the easiest
:url - often used with a Regexp value
:element - a unique element might be the least brittle (new as of Watir 6.18!)
browser.window(title: 'new window')
browser.window(url: /my_page.html/)
browser.window(element: browser.div(id: 'my-element'))
Locating by index is no longer supported
More information: Watir Browser Windows
If there is only one other window you want to use, so as of Watir 6.18, the easiest way to work with that window is with Browser#switch_window. It can only be used if there are only 2 windows, and all it does is switch to the other one, no additional locating required.
browser.switch_window
Using Shoes, I would like to have a block executed upon window destruction. I thought I could use the finish event, but in the following piece of code, "Starting" is displayed, but "Finished" is never shown.
Shoes.app(:title => "Test") do
flow do
start do |obj|
alert("Starting")
end
finish do |obj|
alert("Finished")
end
button "Hello"
end
end
After doing some more researching...
It appears that the finish event in Shoes is currently only used for downloads.
In addition, it appears there is no onclose event currently, but it has been discussed.
http://article.gmane.org/gmane.comp.lib.shoes/2976
Apologies for answering my own question, but putting the knowledge out there for others.