When trying to get the example python libvlc binding to to run, I get the following error:
ModuleNotFoundError: No module named 'evaluator'
Here is what I did:
sudo apt-get install vlc
sudo apt-get install python3-pip
pip3 install python-vlc
Download example for gtkvlc.py as gtkvlc.py and run
python3 gtkvlc.py /path/to/video.mp4
The offending lines are
from evaluator import Evaluator
e = Evaluator(globals(), locals())
e.popup()
How can I get this evaluator?
EDIT: removing the offending lines still leave the application working. What are these lines for?
I think you are running an old code of gtkvlc.py, try this code it is tested and work very well for Python3 and GTK3
import sys
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
gi.require_version('GdkX11', '3.0')
from gi.repository import GdkX11
import vlc
MRL = ""
class ApplicationWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Python-Vlc Media Player")
self.player_paused=False
self.is_player_active = False
self.connect("destroy",Gtk.main_quit)
def show(self):
self.show_all()
def setup_objects_and_events(self):
self.playback_button = Gtk.Button()
self.stop_button = Gtk.Button()
self.play_image = Gtk.Image.new_from_icon_name(
"gtk-media-play",
Gtk.IconSize.MENU
)
self.pause_image = Gtk.Image.new_from_icon_name(
"gtk-media-pause",
Gtk.IconSize.MENU
)
self.stop_image = Gtk.Image.new_from_icon_name(
"gtk-media-stop",
Gtk.IconSize.MENU
)
self.playback_button.set_image(self.play_image)
self.stop_button.set_image(self.stop_image)
self.playback_button.connect("clicked", self.toggle_player_playback)
self.stop_button.connect("clicked", self.stop_player)
self.draw_area = Gtk.DrawingArea()
self.draw_area.set_size_request(300,300)
self.draw_area.connect("realize",self._realized)
self.hbox = Gtk.Box(spacing=6)
self.hbox.pack_start(self.playback_button, True, True, 0)
self.hbox.pack_start(self.stop_button, True, True, 0)
self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.add(self.vbox)
self.vbox.pack_start(self.draw_area, True, True, 0)
self.vbox.pack_start(self.hbox, False, False, 0)
def stop_player(self, widget, data=None):
self.player.stop()
self.is_player_active = False
self.playback_button.set_image(self.play_image)
def toggle_player_playback(self, widget, data=None):
"""
Handler for Player's Playback Button (Play/Pause).
"""
if self.is_player_active == False and self.player_paused == False:
self.player.play()
self.playback_button.set_image(self.pause_image)
self.is_player_active = True
elif self.is_player_active == True and self.player_paused == True:
self.player.play()
self.playback_button.set_image(self.pause_image)
self.player_paused = False
elif self.is_player_active == True and self.player_paused == False:
self.player.pause()
self.playback_button.set_image(self.play_image)
self.player_paused = True
else:
pass
def _realized(self, widget, data=None):
self.vlcInstance = vlc.Instance("--no-xlib")
self.player = self.vlcInstance.media_player_new()
win_id = widget.get_window().get_xid()
self.player.set_xwindow(win_id)
self.player.set_mrl(MRL)
self.player.play()
self.playback_button.set_image(self.pause_image)
self.is_player_active = True
if __name__ == '__main__':
if not sys.argv[1:]:
print "Exiting \nMust provide the MRL."
sys.exit(1)
if len(sys.argv[1:]) == 1:
MRL = sys.argv[1]
window = ApplicationWindow()
window.setup_objects_and_events()
window.show()
Gtk.main()
window.player.stop()
window.vlcInstance.release()
Related
I have this code for creating my own password dialog in Gtk. I need to scale it up by 2-3 times for the display it's going to be used on. How do I do this?
#!/usr/bin/env python3
import gi
import sys
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
class EntryDialog(Gtk.Dialog):
def __init__(self, labeltext=None):
super().__init__(title="Password", modal=True, focus_on_map=True)
content = self.get_content_area()
self.timeout_id = None
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
spacing=15, margin=30)
content.add(vbox)
if labeltext is None:
labeltext = "Please enter a password:"
label = Gtk.Label(labeltext)
vbox.pack_start(label, True, True, 0)
hbox = Gtk.Box(spacing=1)
self.entry = Gtk.Entry()
self.entry.set_text("")
self.entry.set_max_length(256)
self.entry.set_invisible_char('•')
self.entry.set_visibility(False)
hbox.pack_start(self.entry, True, True, 0)
self.show = Gtk.ToggleButton(label="show")
self.show.set_active(False)
hbox.pack_start(self.show, True, True, 0)
vbox.pack_start(hbox, True, True, 0)
#self.entry.connect("activate", lambda x: print("Enter"))
self.show.connect("toggled", self.on_show_toggled)
self.add_buttons(
Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK
)
self.set_default_response(Gtk.ResponseType.OK)
self.entry.connect("activate", self.on_entry_enter)
def on_show_toggled(self, button):
active = button.get_active()
self.entry.set_visibility(active)
button.set_label("hide" if active else "show")
def on_entry_enter(self, button):
self.activate_default()
def get_password(self):
return self.entry.get_text()
def run_dialog(argv):
if len(argv) == 1:
win = EntryDialog()
elif len(argv) == 2:
win = EntryDialog(argv[1])
else:
print(f"Usage: {argv[0]} [<prompt text>]", file=sys.stderr)
sys.exit(2)
win.show_all()
result = win.run()
if result == Gtk.ResponseType.OK:
print(win.get_password())
else:
sys.exit(1)
if __name__ == '__main__':
run_dialog(sys.argv)
Using the GDK_SCALE environment variable was suggested on IRC. This works for my use-case, but it seems a poor solution for general use. In my case, this is what I had to change my program to this:
#!/usr/bin/env python3
import sys
import os
if __name__ == '__main__':
scale = os.environ.get('GDK_SCALE', '1')
scale = float(scale) * 2.5
os.environ['GDK_SCALE'] = str(scale)
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
class EntryDialog(Gtk.Dialog):
def __init__(self, labeltext=None):
super().__init__(title="Password", modal=True, focus_on_map=True)
content = self.get_content_area()
self.timeout_id = None
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
spacing=15, margin=30)
content.add(vbox)
if labeltext is None:
labeltext = "Please enter a password:"
label = Gtk.Label(label=labeltext)
vbox.pack_start(label, True, True, 0)
hbox = Gtk.Box(spacing=1)
self.entry = Gtk.Entry()
self.entry.set_text("")
self.entry.set_max_length(256)
self.entry.set_invisible_char('•')
self.entry.set_visibility(False)
hbox.pack_start(self.entry, True, True, 0)
self.show = Gtk.ToggleButton(label="show")
self.show.set_active(False)
hbox.pack_start(self.show, True, True, 0)
vbox.pack_start(hbox, True, True, 0)
#self.entry.connect("activate", lambda x: print("Enter"))
self.show.connect("toggled", self.on_show_toggled)
self.add_buttons(
Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK
)
self.set_default_response(Gtk.ResponseType.OK)
self.entry.connect("activate", self.on_entry_enter)
def on_show_toggled(self, button):
active = button.get_active()
self.entry.set_visibility(active)
button.set_label("hide" if active else "show")
def on_entry_enter(self, button):
self.activate_default()
def get_password(self):
return self.entry.get_text()
def run_dialog(argv):
if len(argv) == 1:
win = EntryDialog()
elif len(argv) == 2:
win = EntryDialog(argv[1])
else:
print(f"Usage: {argv[0]} [<prompt text>]", file=sys.stderr)
sys.exit(2)
win.show_all()
result = win.run()
if result == Gtk.ResponseType.OK:
print(win.get_password())
else:
sys.exit(1)
if __name__ == '__main__':
run_dialog(sys.argv)
Note that I had to make sure the environment variable was set before I imported the gi package.
I'm working on a GTK+ frontend for libvlc in python using python-vlc. So far I followed this guide, which is working fine, except that when I resize the window, the DrawingArea gets messed up as you can see in the picture (there's probably a word for that phenomenon I don't know).
I'm getting these warnings in the console, but am not sure if this is related:
[00007fce1c014eb0] main filter error: Failed to create video converter
[00007fce2807ff70] vdpau_avcodec generic error: Xlib is required for VDPAU
I already tried setting the background color of the window using the css styling for GTK+ but it had no effect.
I think this should not happen, am I missing something? I'm on wayland by the way.
Using Google and checking different examples I created code which fills background in DrawingArea with black color.
Assign drawing function to DrawingArea
self.draw_area = Gtk.DrawingArea()
self.draw_area.connect("draw", self.da_draw_event)
Function which fills area
def da_draw_event(self, widget, cairo_ctx):
cairo_ctx.set_source_rgb(0, 0, 0)
cairo_ctx.paint()
Full code
import sys
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
gi.require_version('GdkX11', '3.0')
from gi.repository import GdkX11
import vlc
MRL = ""
class ApplicationWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Python-Vlc Media Player")
self.player_paused=False
self.is_player_active = False
self.connect("destroy", Gtk.main_quit)
def show(self):
self.show_all()
def setup_objects_and_events(self):
self.playback_button = Gtk.Button()
self.stop_button = Gtk.Button()
self.play_image = Gtk.Image.new_from_icon_name(
"gtk-media-play",
Gtk.IconSize.MENU
)
self.pause_image = Gtk.Image.new_from_icon_name(
"gtk-media-pause",
Gtk.IconSize.MENU
)
self.stop_image = Gtk.Image.new_from_icon_name(
"gtk-media-stop",
Gtk.IconSize.MENU
)
self.playback_button.set_image(self.play_image)
self.stop_button.set_image(self.stop_image)
self.playback_button.connect("clicked", self.toggle_player_playback)
self.stop_button.connect("clicked", self.stop_player)
self.draw_area = Gtk.DrawingArea()
self.draw_area.set_size_request(300, 300)
self.draw_area.connect("realize",self._realized)
self.draw_area.connect("draw", self.da_draw_event)
self.hbox = Gtk.Box(spacing=6)
self.hbox.pack_start(self.playback_button, True, True, 0)
self.hbox.pack_start(self.stop_button, True, True, 0)
self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.add(self.vbox)
self.vbox.pack_start(self.draw_area, True, True, 0)
self.vbox.pack_start(self.hbox, False, False, 0)
def da_draw_event(self, widget, cairo_ctx):
#print('da_draw_event')
#print('widget:', widget)
#print('cairo_ctx:', cairo_ctx)
cairo_ctx.set_source_rgb(0, 0, 0)
cairo_ctx.paint()
def stop_player(self, widget, data=None):
self.player.stop()
self.is_player_active = False
self.playback_button.set_image(self.play_image)
def toggle_player_playback(self, widget, data=None):
"""
Handler for Player's Playback Button (Play/Pause).
"""
if self.is_player_active == False and self.player_paused == False:
self.player.play()
self.playback_button.set_image(self.pause_image)
self.is_player_active = True
elif self.is_player_active == True and self.player_paused == True:
self.player.play()
self.playback_button.set_image(self.pause_image)
self.player_paused = False
elif self.is_player_active == True and self.player_paused == False:
self.player.pause()
self.playback_button.set_image(self.play_image)
self.player_paused = True
else:
pass
def _realized(self, widget, data=None):
self.vlcInstance = vlc.Instance("--no-xlib")
self.player = self.vlcInstance.media_player_new()
win_id = widget.get_window().get_xid()
self.player.set_xwindow(win_id)
self.player.set_mrl(MRL)
self.player.play()
self.playback_button.set_image(self.pause_image)
self.is_player_active = True
if __name__ == '__main__':
if not sys.argv[1:]:
print("Exiting \nMust provide the MRL.")
sys.exit(1)
if len(sys.argv[1:]) == 1:
MRL = sys.argv[1]
window = ApplicationWindow()
window.setup_objects_and_events()
window.show()
Gtk.main()
window.player.stop()
window.vlcInstance.release()
As #furas pointed out in the comments, constantly drawing a black rectangle on the DrawingArea works very well. I use the following code inside a widget that derives from Gtk.DrawingArea:
def draw(self, c, *args):
rect = self.get_allocation()
win = self.get_window().get_position()
c.set_source_rgb(0, 0, 0)
c.rectangle(rect.x - win.x, rect.y - win.y, rect.width, rect.height)
c.fill()
self.connect("draw", draw)
Edit: See #furas answer for an even simpler approach.
So I want to have my small Python Gtk window have 2 switches. When one switch is ON, the other is turned OFF, and vice versa. I am not too sure how to control both switches. If anyone can lead me in the right direction, it'd be much appreciated.
#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class SwitcherWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Alt Switch Demo")
self.set_border_width(10)
hbox = Gtk.Box(spacing=10)
self.add(hbox)
switch1 = Gtk.Switch()
switch1.connect("notify::active", self.on_switch_activated)
switch1.set_active(True)
hbox.pack_start(switch1, True, True, 0)
switch2 = Gtk.Switch()
switch2.connect("notify::active", self.on_switch_activated)
switch2.set_active(False)
hbox.pack_start(switch2, True, True, 0)
if switch1.get_active():
switch2.set_active(False)
else:
switch2.set_active(True)
def on_switch_activated(self, switch, gparam):
builder = Gtk.Builder()
sw1 = builder.get_object("switch1")
sw2 = builder.get_object("switch2")
if switch.get_active():
state = "on"
sw2.set_active(False)
else:
state = "off"
print("Switch was turned", state)
win = SwitcherWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
I would bind the properties of both switches, inverted and sync'ed on creation:
#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject
class SwitcherWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Alt Switch Demo")
self.set_border_width(10)
hbox = Gtk.Box(spacing=10)
self.add(hbox)
switch1 = Gtk.Switch()
switch1.set_active(True)
hbox.pack_start(switch1, True, True, 0)
switch2 = Gtk.Switch()
switch2.set_active(False)
hbox.pack_start(switch2, True, True, 0)
switch1.bind_property("active", switch2, "active", GObject.BindingFlags.BIDIRECTIONAL | GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.INVERT_BOOLEAN)
win = SwitcherWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
The solution resides on this line of code:
switch1.bind_property("active", switch2, "active", GObject.BindingFlags.BIDIRECTIONAL | GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.INVERT_BOOLEAN)
Here you bind the "active" property of switch1 and switch2 with the binding flags: bidirectional, sync on create and invert boolean
You can implement a similar logic to what I wrote:
#!/usr/bin/env python
class Switch:
_State = False
def __init__(self, StartingPosition=False):
self._State = StartingPosition
def SwitchON(self):
self._State = True
def SwitchOFF(self):
self._State = False
def Switch(self):
self._State = not self._State
def GetInfo(self):
print(self._State)
class Switcher:
def __init__(self, switchDependencyList=[]):
self.SwitchDependencyList = switchDependencyList
if len(self.SwitchDependencyList) == 0:
return None
if not len(self.SwitchDependencyList) % 2:
return None
def SwitchByIndex(self, Index):
for i, switch in enumerate(self.SwitchDependencyList):
if i == Index:
switch.SwitchON()
else:
switch.SwitchOFF()
def GetInfo(self):
for switch in self.SwitchDependencyList:
switch.GetInfo()
sw1 = Switch()
sw2 = Switch()
SwitcherModule = Switcher([sw1, sw2])
SwitcherModule.SwitchByIndex(1)
SwitcherModule.GetInfo()
No need for anything as complex as the prelisted answers. gtk already has a radiobutton widget that does it all for you. Only thing is that when it is initialised you have no buttons set, so you have to pick one to set.
I want to use Gst from gi.repository instead regular gst.
https://wiki.ubuntu.com/Novacut/GStreamer1.0 here is the guide.
This is the code:
#!/usr/bin/env python
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gtk
from gi.repository import Gst
Gst.init(None)
class PlaybackInterface:
def __init__(self):
self.playing = False
# A free example sound track
self.uri = "http://cdn02.cdn.gorillavsbear.net/wp-content/uploads/2012/10/GORILLA-VS-BEAR-OCTOBER-2012.mp3"
# GTK window and widgets
self.window = Gtk.Window()
self.window.set_size_request(300,50)
vbox = Gtk.Box(Gtk.Orientation.HORIZONTAL, 0)
vbox.set_margin_top(3)
vbox.set_margin_bottom(3)
self.window.add(vbox)
self.playButtonImage = Gtk.Image()
self.playButtonImage.set_from_stock("gtk-media-play", Gtk.IconSize.BUTTON)
self.playButton = Gtk.Button.new()
self.playButton.add(self.playButtonImage)
self.playButton.connect("clicked", self.playToggled)
Gtk.Box.pack_start(vbox, self.playButton, False, False, 0)
self.slider = Gtk.HScale()
self.slider.set_margin_left(6)
self.slider.set_margin_right(6)
self.slider.set_draw_value(False)
self.slider.set_range(0, 100)
self.slider.set_increments(1, 10)
Gtk.Box.pack_start(vbox, self.slider, True, True, 0)
self.label = Gtk.Label(label='0:00')
self.label.set_margin_left(6)
self.label.set_margin_right(6)
Gtk.Box.pack_start(vbox, self.label, False, False, 0)
self.window.show_all()
# GStreamer Setup
Gst.init_check(None)
self.IS_GST010 = Gst.version()[0] == 0
self.player = Gst.ElementFactory.make("playbin2", "player")
fakesink = Gst.ElementFactory.make("fakesink", "fakesink")
self.player.set_property("video-sink", fakesink)
bus = self.player.get_bus()
#bus.add_signal_watch_full()
bus.connect("message", self.on_message)
self.player.connect("about-to-finish", self.on_finished)
def on_message(self, bus, message):
t = message.type
if t == Gst.Message.EOS:
self.player.set_state(Gst.State.NULL)
self.playing = False
elif t == Gst.Message.ERROR:
self.player.set_state(Gst.State.NULL)
err, debug = message.parse_error()
print "Error: %s" % err, debug
self.playing = False
self.updateButtons()
def on_finished(self, player):
self.playing = False
self.slider.set_value(0)
self.label.set_text("0:00")
self.updateButtons()
def play(self):
self.player.set_property("uri", self.uri)
self.player.set_state(Gst.State.PLAYING)
GObject.timeout_add(1000, self.updateSlider)
def stop(self):
self.player.set_state(Gst.State.NULL)
def playToggled(self, w):
self.slider.set_value(0)
self.label.set_text("0:00")
if(self.playing == False):
self.play()
else:
self.stop()
self.playing=not(self.playing)
self.updateButtons()
def updateSlider(self):
if(self.playing == False):
return False # cancel timeout
try:
if self.IS_GST010:
nanosecs = self.player.query_position(Gst.Format.TIME)[2]
duration_nanosecs = self.player.query_duration(Gst.Format.TIME)[2]
else:
nanosecs = self.player.query_position(Gst.Format.TIME)[1]
duration_nanosecs = self.player.query_duration(Gst.Format.TIME)[1]
# block seek handler so we don't seek when we set_value()
# self.slider.handler_block_by_func(self.on_slider_change)
duration = float(duration_nanosecs) / Gst.SECOND
position = float(nanosecs) / Gst.SECOND
self.slider.set_range(0, duration)
self.slider.set_value(position)
self.label.set_text ("%d" % (position / 60) + ":%02d" % (position % 60))
#self.slider.handler_unblock_by_func(self.on_slider_change)
except Exception as e:
# pipeline must not be ready and does not know position
print e
pass
return True
def updateButtons(self):
if(self.playing == False):
self.playButtonImage.set_from_stock("gtk-media-play", Gtk.IconSize.BUTTON)
else:
self.playButtonImage.set_from_stock("gtk-media-stop", Gtk.IconSize.BUTTON)
if __name__ == "__main__":
PlaybackInterface()
Gtk.main()
But i have:
Traceback (most recent call last):
File "./xy", line 134, in <module>
PlaybackInterface()
File "./xy", line 52, in __init__
self.player.set_property("video-sink", fakesink)
AttributeError: 'NoneType' object has no attribute 'set_property'
Error. How to use Gst.ElementFactory.make? It returns None?
use playbin instead of playbin2.
self.player = Gst.ElementFactory.make("playbin", "player")
ElementFactory.make returns none because there isn't playbin2 element in Gst-1.0. Playbin2 is in the Gst-0.1
I've got a gtk.Expander object, containing in its label a gtk.HBox, which packed a gtk.Image and a gtk.Label.
I want to launch a Webbrowser when the HBox is right-clicked.
Here is my code:
def launchBrowser(widget, host, event):
print event
print host
if event.type == gtk.gdk.BUTTON_PRESS:
if event.button == 3:
webbrowser.open(host, 1)
print "right click"
def addServer(self, loginfo):
main_expand = gtk.Expander()
main_led = gtk.Image()
if int(loginfo["main"]) == 0:
main_led.set_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_BUTTON)
else:
main_led.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_BUTTON)
main_srvname = gtk.Label(loginfo["srvname"])
expand_title = gtk.HBox(False, 2)
expand_title.pack_start(main_led, False, True, 0)
expand_title.pack_start(main_srvname, True, True, 0)
main_srvname.add_events(gtk.gdk.BUTTON_PRESS_MASK)
main_srvname.connect_object('event', self.launchBrowser, loginfo["host"])
main_srvname.emit('event', gtk.gdk.Event(gtk.gdk.BUTTON_PRESS_MASK))
main_expand.set_property("label-widget", expand_title)
Problem is that when I pass my cursor on this HBox, I correctly received the event. But when I clicked nothing happen. I think it's because the click event is intercept by the Expander.
Anyhelp is welcome =)
Thanks in advance!
EDIT:
I also tried that:
main_srvname = gtk.Label(loginfo["srvname"])
eventbox = gtk.EventBox()
eventbox.add(main_srvname)
eventbox.connect_object('button-press-event', self.launchBrowser, loginfo["host"])
# Titre de l'expand box
expand_title = gtk.HBox(False, 2)
expand_title.pack_start(main_led, False, True, 0)
expand_title.pack_start(eventbox, True, True, 0)
Not working either...
EDIT2:
As requested by Jeremy, here a self-contained code, just copy-paste it you lazyboy!
import pygtk
pygtk.require('2.0')
import gtk
class MainWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.set_default_size(300, 300)
self.addServer()
def launchBrowser(widget, host, event):
print event
if event.type == gtk.gdk.BUTTON_PRESS:
if event.button == 3:
print "click"
def addServer(self):
main_expand = gtk.Expander()
main_led = gtk.Image()
main_led.set_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_BUTTON)
main_srvname = gtk.Label("srvname")
main_srvname.add_events(gtk.gdk.BUTTON_PRESS_MASK)
main_srvname.connect_object('button-press-event', self.launchBrowser, "host")
expand_title = gtk.HBox(False, 2)
expand_title.pack_start(main_led, False, True, 0)
expand_title.pack_start(main_srvname, True, True, 0)
main_expand.set_property("label-widget", expand_title)
self.add(main_expand)
self.show_all()
def main():
MainWindow()
gtk.main()
if __name__ == '__main__':
main()
Small change in your code.
Add "button-press-event" on Expander widget instead of Label widget
import pygtk
pygtk.require('2.0')
import gtk
class MainWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.set_default_size(300, 300)
self.addServer()
def launchBrowser(self, widget, event, host, *args):
if event.type == gtk.gdk.BUTTON_PRESS:
if event.button == 3:
print "click"
# Normal behaviour of Expander on single click
expand = widget.get_expanded()
if not expand: widget.set_expanded(True)
else: widget.set_expanded(False)
def addServer(self):
main_expand = gtk.Expander()
main_led = gtk.Image()
main_led.set_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_BUTTON)
main_srvname = gtk.Label("srvname")
main_expand.add_events(gtk.gdk.BUTTON_PRESS_MASK)
main_expand.connect('button-press-event', self.launchBrowser, 'host')
expand_title = gtk.HBox(False, 2)
expand_title.pack_start(main_led, False, True, 0)
expand_title.pack_start(main_srvname, True, True, 0)
main_expand.set_property("label-widget", expand_title)
self.add(main_expand)
self.show_all()
def main():
MainWindow()
gtk.main()
if __name__ == '__main__':
main()