Keyboard Shortcut doesn't work in ruby-gtk2 TextView - ruby

I'm practicing on a GUI based on Gtk and Ruby. I planned to make a little window that has a TextView and a button. When you input text in the TextView and press the button, it calls the Twitter gem's method and tweets to Twitter.
After that succeeded, I wanted to make a keyboard short-cut to do this: like, when you hit Ctrl+Enter it Tweets.
Here's part of the source code I have written. (Only around the GUI)
# require "gtk2"
# require "twitter"
## error classes and methods first
class Error_pop
def initialize(text)
#pop = Gtk::Dialog.new(
"Error",
nil,
Gtk::Dialog::MODAL,
[Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK]
)
#pop.default_response = Gtk::Dialog::RESPONSE_OK
#pop.set_size_request(400, 100)
#label = Gtk::Label.new("#{ text }")
#table = Gtk::Table.new(3, 1, false)
#table.attach_defaults(#label, 0, 1, 0, 2)
#pop.vbox.add(#table)
end
attr_accessor :pop, :table, :label
end
module Tueet
def tueet(text, account)
begin
account.rest_api.update(text) # calls gem: twitter
rescue => reason
error_pop = Error_pop.new(reason)
error_pop.pop.show_all
error_pop.pop.run do |response|
if response == Gtk::Dialog::RESPONSE_OK
end
end
error_pop.pop.destroy
return text
else
return nil
end
end
module_function :tueet
end
## making gui
window = Gtk::Window.new(Gtk::Window::TOPLEVEL)
window.title = "Tweet Box"
window.set_size_request(300, 150)
window.resizable = false
window.signal_connect('delete_event') do
Gtk.main_quit
false
end
inputter = Gtk::TextView.new
inputter.editable = true
inputter.wrap_mode = Gtk::TextTag::WRAP_WORD_CHAR
inputter_event = Gtk::EventBox.new # for key binding
inputter_event.events = Gdk::Event::KEY_PRESS_MASK
tweetbutton = Gtk::Button.new("tweet")
table = Gtk::Table.new(4, 9, true)
table.attach(inputter, 0, 9, 0, 3, Gtk::FILL||Gtk::EXPAND, Gtk::FILL||Gtk::EXPAND, 5, 5)
table.attach(tweetbutton, 3, 6, 3, 4)
inputter_event.add(table)
window.add(inputter_event)
inputter_event.realize
## signals and stuff
text = nil
tweetbutton.signal_connect('clicked') do
text = inputter.buffer.text
returned_text = Tueet.tueet(text, client[0]) # client[n] holds the authorized account information
inputter.buffer.text = String(returned_text)
end
inputter_event.signal_connect('key-press-event') do |wdt, evt|
key = Gdk::Keyval.to_name(evt.keyval)
p ("KeyPress: #{ key }was pressed") # these lines
p evt.state # are for
p evt.keyval # debugging
if key == 'Return' && # when "Ctrl + Return", do Tueet.tueet
( evt.state & Gdk::Window::CONTROL_MASK ==
Gdk::Window::ModifierType::CONTROL_MASK )
Tueet.tueet(text, client[0])
end
end
window.show_all
Gtk.main
And, this doesn't work. When I press Ctrl + Enter, it simply linebreaks inside the TextView.
Only, when doing this:
inputter = Gtk::TextView.new
inputter.editable = false # <- making this false
inputter.wrap_mode = Gtk::TextTag::WRAP_WORD_CHAR
makes the keybinding work, but disables me to input what I want to tweet to the TextView.
How can I work this out? I wonder how many GUI applications do this.

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

Use GTK3 progress bars in Ruby

This is my code:
require "gtk3"
builder_file = "#{File.expand_path(File.dirname(__FILE__))}/example.ui"
builder = Gtk::Builder.new(:file => builder_file)
window = builder.get_object("window")
window.signal_connect("destroy") { Gtk.main_quit }
progressbar=builder.get_object("progressbar1")
progressbar.set_fraction(0.5)
button = builder.get_object("button1")
button.signal_connect("clicked") {
for i in(0..4)
sleep(1)
puts "query " + (i+1).to_s + " done"
a=(i+1)/5.to_f
puts a
progressbar.set_fraction(a)
end
}
Gtk.main
sleep is just a placeholder for a web query that takes about 1 second. When I execute this code on my machine, the console output is fine, but the progress bar stays empty until it jumps to full after five seconds, which is not what I want. How can I make use of the progress bar?
The integration of the event loop of the GUI tool (Gtk, Tk, etc) and Ruby annoys beginners including me. I know two ways.
1.add thread
require 'gtk3'
win = Gtk::Window.new('Sample')
win.signal_connect('destroy') { Gtk.main_quit }
box = Gtk::Box.new(:vertical)
pb = Gtk::ProgressBar.new
pb.set_fraction(0.5)
b = Gtk::Button.new(label: 'Button')
b.signal_connect('clicked') do
Thread.new do
5.times do |i|
sleep 1
pb.fraction = (i + 1) / 5.0
end
end
end
win.add box
box.pack_start pb
box.pack_start b
win.show_all
Gtk.main
2.use GLib::Timeout
b.signal_connect('clicked') do
i = 0.0
GLib::Timeout.add(1000) do |a|
i += 0.2
pb.fraction = i
i < 1.0 # return false and stop when i >= 1.0
end
end

Signal timed ruby gtk image change without button_press_event, how to trigger looping

The line: pics.box.signal_connect("button_press_event"){pics.nuImage}, triggers nuImage and adds 1 to the picindex counter upon clicking, making the current image destroy, and next image show. I would like to make this automatic, like a slideshow without having to click. It needs to show a new image every x amount of seconds, using a sleep or something like GLib.timeout_add_seconds (), but I do not understand how to implement these options to continue looping without any user input. Thank you for your help, I am very new to ruby.
require 'gtk2'
class Pics
attr_accessor :pile, :picindex, :imgLoaded, :image, :box, :window, :time
def initialize
#window = Gtk::Window.new()
#window.signal_connect("destroy"){Gtk.main_quit}
pic1 = "1.jpg"
pic2 = "2.jpg"
pic3 = "3.jpg"
pic4 = "4.jpg"
#pile = [pic1, pic2, pic3, pic4]
#picindex = 0
self.getImage
#box = Gtk::EventBox.new.add(#image)
#time = true
end
def nuImage
#box.remove(#image)
#picindex = #picindex + 1
#picindex = 0 if #picindex == #pile.length
self.getImage
#box.add(#image)
#box.show
end
def getImage
#imgLoaded = #pile[#picindex]
img = Gdk::Pixbuf.new(#imgLoaded, 556, 900)
#image = Gtk::Image.new(img)
#image.show
end
end # class Pics
pics = Pics.new
pics.box.signal_connect("button_press_event"){pics.nuImage}
pics.window.set_default_size(556, 900)
pics.window.add(pics.box)
pics.window.show_all
Gtk.main
the following code is an implementation:
GLib::Timeout.add(1000) do
pics.nuImage if pics.time
true
end
pics.window.signal_connect("key_press_event") do |_window, event|
case event.keyval
when Gdk::Keyval::GDK_KEY_space
pics.time = !pics.time
end
end
more details: http://ruby-gnome2.sourceforge.jp/hiki.cgi?GLib%3A%3ATimeout
related: Ruby GTK Pixbuf timed image change

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

Strange treeview behaviour: strikeout text only if bold

I need to show some treeview item text striked out text into a QT treeview from Ruby.
After some reading on QT documentation and much coding, I found that only when rendering font in bold, also the strikeout was rendered.
So I wonder, where I'm doing wrong?
This is the code to achive the result shown above. Note as I set strikeout for every even row item.
I'm using Ruby 1.8.7 and Qt 4.6.2 and qt4ruby 4.4.3-6 on Mandriva Linux.
require 'Qt4'
require 'date'
class MyStandardItem < Qt::StandardItem
def initialize(str = nil)
super str
end
def data(role = Qt::UserRole + 1)
return super(role) unless role == Qt::FontRole
ret_val = Qt::Font.new()
#parameters for "fromString":font family, pointSizeF, pixelSize, QFont::StyleHint, QFont::Weight, QFont::Style, underline, strikeOut, fixedPitch, rawMode
ret_val.fromString "sans serif,-1,-1,0,0,0,0,0,0,0"
case role
when Qt::FontRole
ret_val.setStrikeOut(true) if (index.row % 2) == 0
if index.column == 1
ret_val.weight = Qt::Font.Bold
else
ret_val.weight = Qt::Font.Normal
end
return Qt::Variant.fromValue(ret_val)
end
return ret_val
end
end
Qt::Application.new(ARGV) do
treeview = Qt::TreeView.new do
model = Qt::StandardItemModel.new self
head = [MyStandardItem.new "Qt v. #{Qt.version}"]
head << MyStandardItem.new("Ruby v. #{VERSION}")
head << MyStandardItem.new("Qt4Ruby v. 4.4.3-6 (Mandriva)")
model.append_row head
(1..10).each do |i|
col0 = MyStandardItem.new 'some text'
col0.check_state = ((i % 3) == 0)? Qt.Checked : Qt.Unchecked
col0.checkable = true
col0.editable= false
col1 = MyStandardItem.new "line ##{i}"
col2 = MyStandardItem.new((Date.today + i).strftime '%d/%m/%y')
model.append_row [col0, col1, col2]
end
self.model = model
show
end
exec
end
Eventually I find an hackish trick to overcome this problem. Playing around after reading again the enum QFont::Weight description I tried to set
ret_val.weight = 51 # Qt::Font.Normal value is 50
instead of
ret_val.weight = Qt::Font.Normal
and magically the normal text appears striked out!
Maybe this strange behaviour is due to a bug on QT?

Resources