Sometimes, you need a Gtk label, styled like a web link that opens an URL when you click. I need this widget for the
todo-summarizer Gtk2 GUI and I don't like the look and feel of the Gtk
LinkButton widget.
So, I wrote a custom
ClickableLabel widget that handle the URL, opens your system's default web browser, shows the destination URL either in a
tooltip or a
status label and change the mouse cursor change when you hover it.
This code was inspired by two articles written in perl/gtk2 you can found here :
part1 and
part2.
The main issue in this class is that
Gtk::Label can't handle mouse events, so you have to use a
Gtk:EventBox and use
#pack_start to make the whole thing visible.
The last thing to implement is the mouse cursor change : just remember than you can only set the cursor of a
Gdk::Window (not a
Gtk one).
Here the complete source of this new widget :
# A clickable Gtk::Label styled as a web link
#
# parent: The parent widget (or box...)
# text: The text of the label
# uri: The uri your browser will open if you click
# status_label: An optional label to print the destination
# URI when you hover the label. If no status_label
# is provided, URI is printed in a tooltip
class ClickableLabel < Gtk::Label
def initialize(parent, text, uri, status_label = nil)
super() # Avoid the 'uninitialize GLib::Object' issue
self.set_markup("<span color=\"blue\"><u>%s</u></span>"%text)
eb = Gtk::EventBox.new()
eb.add(self)
eb.signal_connect('button-press-event') do
open uri
end
parent.pack_start(eb) # Make the whole thing visible
# Do not try to change the cursor here, self.window
# returns nil because the widget isn't actualy created.
eb.signal_connect('enter-notify-event') do
if status_label
status_label.set_text(uri)
end
# The default cursor is actually Gdk::Cursor::Type::ARROW
cur = Gdk::Cursor.new(Gdk::Cursor::Type::HAND1)
# Get the underlying Gdk::Window of the label and change
# its mouse cursor
self.window.set_cursor(cur)
end
if status_label
eb.signal_connect('leave-notify-event') do
status_label.set_text('')
end
else
self.set_tooltip_text(uri)
end
end
# From http://stackoverflow.com/a/14053693
# Should be tested
def open(link)
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
system "start #{link}"
elsif RbConfig::CONFIG['host_os'] =~ /darwin/
system "open #{link}"
elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
system "xdg-open #{link}"
end
end
end
You can use this with our without a status label to show the destination URL :
txt="My blog's URL"
url="https://dailycommit.blogspot.com"
# Without a status label, destination is in a tooltip
ClickableLabel.new(vbox, txt, uri)
# With a status label, destination is printed on mouse hover
ClickableLabel.new(vbox, txt, uri, status)
Comments
Post a Comment