Connect function to a QPushButton press - ruby

I want to execute a user defined function after a button was pressed. I don't know how to use the connect function correctly to achieve the behavior specified in the code snippet.
#!/usr/bin/env ruby
require 'Qt4'
def do_sth
print "did something"
end
app = Qt::Application.new(ARGV)
btn = Qt::PushButton.new('Button')
btn.resize(75, 30)
btn.setFont(Qt::Font.new('Times', 18, Qt::Font::Bold))
# A button click will close the application.
#Qt::Object.connect(btn, SIGNAL('clicked()'),app, SLOT('quit()'))
#
# FIXME How to execute the function do_sth if the button was pressed?
Qt::Object.connect(btn, SIGNAL('clicked()'),app, SLOT('do_sth()'))
btn.show()
app.exec()

Thanks for your hint, it worked the way you suggested.
#!/usr/bin/env ruby
require 'Qt4'
class Qo < Qt::Object
slots 'do_sth()'
slots 'bla()'
def do_sth
puts "did something"
end
def bla
puts "blabla"
end
end
qobj = Qo.new
app = Qt::Application.new(ARGV)
btn = Qt::PushButton.new('Button')
btn.resize(75, 30)
btn.setFont(Qt::Font.new('Times', 18, Qt::Font::Bold))
Qt::Object.connect(btn, SIGNAL('clicked()'),qobj, SLOT('do_sth()'))
Qt::Object.connect(btn, SIGNAL('pressed()'),qobj, SLOT('bla()'))
btn.show()
app.exec()

Related

How to click context in RecyclerView by using Appium, Ruby

How to click an element in RecyclerView by using Appium, Ruby. I tried using all ways but not able to click
I have tried all possible ways
require 'selenium-cucumber'
require 'appium_lib'
def alert1
$driver.find_element(xpath: "/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.ScrollView/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.Button[2]")
end
def alert2; $driver.find_element(xpath: "/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.ScrollView/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.Button[2]") end
def phoneNumber; $driver.find_element(id: "com.accushield.familyapp:id/phone_number") end
def sendCode; $driver.find_element(id: "com.accushield.familyapp:id/send_code") end
def confirmationCode; $driver.find_element(id: "com.accushield.familyapp:id/confirmation_code") end
def submitCode; $driver.find_element(id: "com.accushield.familyapp:id/submit_confirmation_code") end
def dashboardScreen1; $driver.find_element(xpath: "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.support.v7.widget.RecyclerView/android.widget.FrameLayout[1]/android.view.ViewGroup").click end
Then(/^do user Login with OTP$/) do
alert1.click
alert2.click
phoneNumber.send_keys("8131234567")
sendCode.click
confirmationCode.send_keys("123456")
submitCode.click
sleep 40
#residentClick.click
#$driver.find_element(xpath: "//android.widget.ImageView[#index='1']").click
dashboardScreen1.click
#if dashboardScreen.displayed?
# puts "User has signed in successfully"
# else
# puts "User sign in got failed"
# end
I need to click any element in recycler view. Please find the image for elements
https://i.stack.imgur.com/cmJ23.png

Send messages to a global buffer in Ruby

I know global variables aren't encouraged in Ruby but this is what I have been asked to do so you'll just have to go with me on this. I have a game that outputs messages to the command window successfully through the STDOUT. My task is to modify the class so that the messages are not only displayed to the STDOUT channel but also written to a buffer. This is so when I add an additional Sinatra method to the end of the file, the buffer is displayed in a browser (i.e localhost:4567).
So effectively, with the Sinatra gem called, running the spec.rb from a command window should result in the messages being displayed in the Web server in addition to the command window. But I do not know where to start in terms of outputting my messages to the buffer.
I'm pretty sure there is a very simple answer to this but my knowledge of ruby is not great. My thinking is I need to add a line to each activity concatenating the output of each to the global variable $buffer but how do I do this? Obviously following that, I need to write a Sinatra method that displays the contents of the global variable in the web browser.
Hope that makes sense.
I have two files, spec.rb and gen.rb. This is my code so far:
spec.rb
require "gen.rb"
module ImpossibleMachine
# Input and output constants processed by subprocesses
DOWN_ARROW = 1
UP_ARROW = 2
RIGHT_ARROW = 3
REPEAT_ARROW = 4
END_PROCESS = 5
START_CURRENT = 6
# RSpec Tests
describe Game do
describe "#start The impossible machine game" do
before(:each) do
#process = []
#output = double('output').as_null_object
#game = Game.new(#output)
end
it "sends a welcome message" do
#output.should_receive(:puts).with('Welcome to the Impossible Machine!')
#game.start
end
it "sends a starting message" do
#output.should_receive(:puts).with('Starting game...')
#game.start
end
it "should perform lifts_lever_turns_wheel activity which returns REPEAT_ARROW" do
#output.should_receive(:puts).with("Input: #{UP_ARROW}, Activity: Heave_ho_squeek_squeek")
#process[1] = #game.lifts_lever_turns_wheel(UP_ARROW)
#process[1].should == REPEAT_ARROW
end
it "should perform turns_tap_on_pulls_down_seesaw activity which returns DOWN_ARROW" do
#output.should_receive(:puts).with("Input: #{REPEAT_ARROW}, Activity: Drip_drip_creek_creek")
#process[2] = #game.turns_tap_on_pulls_down_seesaw(REPEAT_ARROW)
#process[2].should == DOWN_ARROW
end
it "should perform pulls_down_seezaw_starts_current activity which returns START_CURRENT" do
#output.should_receive(:puts).with("Input: #{DOWN_ARROW}, Activity: Creek_creek_buzz_buzz")
#process[2] = #game.pulls_down_seezaw_starts_current(DOWN_ARROW)
#process[2].should == START_CURRENT
end
it "should perform starts_current_pushes_grove activity which returns RIGHT_ARROW" do
#output.should_receive(:puts).with("Input: #{START_CURRENT}, Activity: Buzz_buzz_pow_wallop")
#process[3] = #game.starts_current_pushes_grove(START_CURRENT)
#process[3].should == RIGHT_ARROW
end
it "sends a finishing message" do
#output.should_receive(:puts).with('...Game finished.')
#game.finish
end
end
end
end
gen.rb
require 'sinatra'
$buffer = ""
# Main class module
module ImpossibleMachine
# Input and output constants processed by subprocesses. MUST NOT change.
DOWN_ARROW = 1
UP_ARROW = 2
RIGHT_ARROW = 3
REPEAT_ARROW = 4
END_PROCESS = 5
START_CURRENT = 6
class Game
attr_reader :process, :output
attr_writer :process, :output
def initialize(output)
#output = output
puts "[#{#output}]"
end
# All the code/methods aimed at passing the RSpect tests are below.
def start
#output.puts'Welcome to the Impossible Machine!'
#output.puts'Starting game...'
end
def lifts_lever_turns_wheel(input)
#input = input
#output.puts 'Input: 2, Activity: Heave_ho_squeek_squeek'
return REPEAT_ARROW
end
def turns_tap_on_pulls_down_seesaw(input)
#input = input
#output.puts 'Input: 4, Activity: Drip_drip_creek_creek'
return DOWN_ARROW
end
def pulls_down_seezaw_starts_current(input)
#input = input
#output.puts 'Input: 1, Activity: Creek_creek_buzz_buzz'
return START_CURRENT
end
def starts_current_pushes_grove(input)
#input = input
#output.puts 'Input: 6, Activity: Buzz_buzz_pow_wallop'
return RIGHT_ARROW
end
def finish
#output.puts'...Game finished.'
end
end
end
# Main program
module ImpossibleMachine
#process = []
g = Game.new(STDOUT)
# All code added to output the activity messages to the command line window is below.
g.start
#process[0] = g.lifts_lever_turns_wheel(2)
#process[1] = g.turns_tap_on_pulls_down_seesaw(#process[0])
#process[2] = g.pulls_down_seezaw_starts_current(#process[1])
#process[3] = g.starts_current_pushes_grove(#process[2])
g.finish
end
# Any sinatra code added to output the activity messages to a browser should be added below.
# End program
managed to get this to work after hours!
At the top add/adjust to:
require 'stringio'
$buffer= StringIO.new
in the main program:
g = Game.new($buffer)
g.start
#process[0] = g.lifts_lever_turns_wheel(2)
etc......
g.finish
puts $buffer.string #this sends it to stdout
then just add in the sinatra coding at the bottom which will also use $buffer.string
possibly not the best or smartest way to do it but it uses the global buffer they wanted and gets it to sinatra and the cmd line.
I think you could just create some sort of buffer object in your main program and pass it in the game, just like you pass in STDOUT. Then you could call write methods on the passed in object inside the game.

FXRuby intercept window close

I've created a 'confirm exit' dialog box to prompt the user when exiting. I've successfully connected it to an 'exit' menu command, but I also want to connect it to the window-close (X) button. How can I do this? I've had some experience with Java Swing, and to accomplish this task you had to add a window listener to the frame that would call this prompt. Is there something similar I must do here?
Do it like this:
require 'fox16'
include Fox
class MyApp < FXMainWindow
def initialize(app)
#app = app
super(app, "Test", :height => 150, :width => 350, :opts=> DECOR_ALL)
self.connect(SEL_CLOSE, method(:on_close))
end
def create
super
show(PLACEMENT_SCREEN)
end
def on_close(sender, sel, event)
q = FXMessageBox.question(#app, MBOX_YES_NO, "Sure?", "You sure?")
if q == MBOX_CLICKED_YES
getApp().exit(0)
end
end
end
FXApp.new do |app|
MyApp.new(app)
app.create
app.run
end

Qtdesinger, ruby and some action for buttons/widgets in generated code

I am developing an application using ruby and qt as front end. I used qtdesigner to draw gui and converted the code using rbuic4. But i am unable get any action for buttons placed on main programm. I created main.rb and called generated code using require './muprogramm.rb'. Here is the sample code for opening file dialog for button mbusb_close (object name)
require './muprogramm.rb'
require 'Qt4'
class Form < Qt::Widget
slots 'file_dialog()'
def initialize(parent = nil)
super
#ui = Ui_Frame.new
#ui.setupUi(self)
Qt::Object.connect(#ui.mbusb_close, SIGNAL('clicked()'), self, SLOT('file_dialog()'))
end
def file_dialog
f = Qt::FileDialog
text = File.new(f.getOpenFileName).read
##ui.editor_window.setText 'WikiBooks: Ruby'
end
end
a = Qt::Application.new(ARGV)
u = Ui_Frame.new
w = Qt::Frame.new
u.setupUi(w)
w.show
a.exec
The resource available in the net is vague. Any help is appreciated
Just use the subclass that you created directly:
require './muprogramm.rb'
require 'Qt4'
class Form < Qt::Widget
slots 'file_dialog()'
def initialize(parent = nil)
super
#ui = Ui_Frame.new
#ui.setupUi(self)
Qt::Object.connect(#ui.mbusb_close, SIGNAL('clicked()'), self, SLOT('file_dialog()'))
end
def file_dialog
f = Qt::FileDialog
text = File.new(f.getOpenFileName).read
##ui.editor_window.setText 'WikiBooks: Ruby'
end
end
a = Qt::Application.new(ARGV)
w = Form.new
w.show
a.exec

Thread Locking in Ruby (use of soap4r and QT)

[EDIT NOTE: Noticed I had put the mutex creation in the constructor. Moved it and noticed no change.]
[EDIT NOTE 2: I changed the call to app.exec in a trial run to
while TRUE do
app.processEvents()
puts '."
end
I noticed that once the Soap4r service started running no process events ever got called again]
[EDIT NOTE 3: Created an associated question here: Thread lockup in ruby with Soap4r
I'm attempting to write a ruby program that receives SOAP commands to draw on a monitor (thus allowing remote monitor access). I've put together a simple test app to prototype the idea. The graphic toolkit is QT. I'm having what I assume is a problem with locking. I've added calls to test the methods in the server in the code shown. The server side that I'm testing right now is:
require 'rubygems'
require 'Qt4'
require 'thread'
require 'soap/rpc/standaloneserver'
class Box < Qt::Widget
def initialize(parent = nil)
super
setPalette(Qt::Palette.new(Qt::Color.new(250,0,0)))
setAutoFillBackground(true)
show
end
end
class SOAPServer < SOAP::RPC::StandaloneServer
##mutex = Mutex.new
def initialize(* args)
super
# Exposed methods
add_method(self, 'createWindow', 'x', 'y', 'width', 'length')
end
def createWindow(x, y, width, length)
puts 'received call'
windowID = 0
puts #boxList.length
puts #parent
##mutex.synchronize do
puts 'in lock'
box = Box.new(#parent)
box.setGeometry(x, y, width, length)
windowID = #boxList.push(box).length
print "This:", windowID, "--\n"
end
puts 'out lock'
return windowID
end
def postInitialize (parent)
#parent = parent
#boxList = Array.new
end
end
windowSizeX = 400
windowSizeY = 300
app = Qt::Application.new(ARGV)
mainwindow = Qt::MainWindow.new
mainwindow.resize(windowSizeX, windowSizeY)
mainwindow.show
puts 'Attempting server start'
myServer = SOAPServer.new('monitorservice', 'urn:ruby:MonitorService', 'localhost', 4004)
myServer.postInitialize(mainwindow)
Thread.new do
puts 'Starting?'
myServer.start
puts 'Started?'
end
Thread.new do
myServer.createWindow(10,0,10,10)
myServer.createWindow(10,30,10,10)
myServer.createWindow(10,60,10,10)
myServer.createWindow(10,90,10,10)
end
myServer.createWindow(10,10,10,10)
Thread.new do
app.exec
end
gets
Now when I run this I get the following output:
Attempting server start
Starting?
received call
0
#<Qt::MainWindow:0x60fea28>
in lock
received call
0
#<Qt::MainWindow:0x60fea28>
This:1--
in lock
This:2--
out lock
At that point I hang rather than recieving the total of five additions I expect. Qt does display the squares defined by "createWindow(10,0,10,10)" and "createWindow(10,10,10,10)". Given that "This:1--" and "This:2--" show within a nexted in/out lock pair I'm assuming I'm using mutex horribly wrong. This is my first time with threading in Ruby.

Resources