Activity Indicator in Tkinter? - python

Each OS has an activity indicator. OS X and iOS has a flower that lights up and fades each pedal in a circular pattern. Windows has a spinning blue disk thing. Android has a gray disk thing (I think it can be in a variety of other colors, too - IDK, I don't use Android much.)
What's the best way to use these icons in Tkinter? Is there some built in widget that provides this? Is there maybe a variable that I can point an Image widget at to get it to display this icon (and animate it?)
I know Tkinter provides a Progress Bar, which has an indeterminate mode. I don't want to use that - I need something that fits in a small square area, not a long rectangular area. The activity indicator as described in the first paragraph will be perfect.
Or is my best option going to be to just roll my own canvas animation?

This should be enough for what you trying to do. I would than create my own animation or download from the internet frame by frame which you want to display. Canvas are more for interactivity with the user thats why I am using a label for displaying the images...
import tkinter as tk
class Activity(tk.Label):
def __init__(self, master = None, delay = 1000, cnf = {}, **kw):
self._taskID = None
self.delay = delay
return super().__init__(master, cnf, **kw)
# starts the animation
def start(self):
self.after(0, self._loop)
# calls its self after a specific <delay>
def _loop(self):
currentText = self["text"] + "."
if currentText == "....":
currentText = ""
self["text"] = currentText
self._taskID = self.after(self.delay, self._loop)
# stopps the loop method calling its self
def stop(self):
self.after_cancel(self._taskID)
# Depends if you want to destroy the widget after the loop has stopped
self.destroy()
class AcitivityImage(Activity):
def __init__(self, imagename, frames, filetype, master = None, delay = 1000, cnf = {}, **kw):
self._frames = []
self._index = 0
for i in range(frames):
self._frames.append(tk.PhotoImage(file = imagename+str(i)+'.'+str(filetype)))
return super().__init__(master, delay, cnf, **kw)
def _loop(self):
self["image"] = self._frames[self._index]
# add one to index if the index is less then the amount of frames
self._index = (self._index + 1 )% len(self._frames)
self._taskID = self.after(self.delay, self._loop)
root = tk.Tk()
root.geometry("500x500")
# create a activity image widget
#root.b = AcitivityImage("activity", 3, "png", root)
#root.b.pack()
# create the activity widget
root.a = Activity(root, 500, bg = "yellow")
root.a.pack()
# start the loop
root.a.start()
#root.b.start()
# stop the activity loop after 7 seconds
root.after(7000, root.a.stop)
#root.after(8000, root.b.stop)
root.mainloop().

Related

python tkinter tooltip on modal window

I searched for ways of implementing tooltips for an application and I found in some comment or answer in this site some while ago a link to this page.
I've been using this class since then and I've been happy with the result.
But recently I noticed that the tooltips came up behind modal windows, when they refer to widgets on that modal window.
Below in the code downloaded from that GitHub link, where I just made the changes of replacing from tkinter import * with import tkinter as tk, and using the prefix tk throughout the code accordingly.
"""Tools for displaying tool-tips.
This includes:
* an abstract base-class for different kinds of tooltips
* a simple text-only Tooltip class
"""
import tkinter as tk
class TooltipBase:
"""abstract base class for tooltips"""
def __init__(self, anchor_widget):
"""Create a tooltip.
anchor_widget: the widget next to which the tooltip will be shown
Note that a widget will only be shown when showtip() is called.
"""
self.anchor_widget = anchor_widget
self.tipwindow = None
def __del__(self):
self.hidetip()
def showtip(self):
"""display the tooltip"""
if self.tipwindow:
return
self.tipwindow = tw = tk.Toplevel(self.anchor_widget)
# show no border on the top level window
tw.wm_overrideredirect(1)
try:
# This command is only needed and available on Tk >= 8.4.0 for OSX.
# Without it, call tips intrude on the typing process by grabbing
# the focus.
tw.tk.call("::tk::unsupported::MacWindowStyle", "style", tw._w,
"help", "noActivates")
except tk.TclError:
pass
self.position_window()
self.showcontents()
self.tipwindow.update_idletasks() # Needed on MacOS -- see #34275.
self.tipwindow.lift() # work around bug in Tk 8.5.18+ (issue #24570)
def position_window(self):
"""(re)-set the tooltip's screen position"""
x, y = self.get_position()
root_x = self.anchor_widget.winfo_rootx() + x
root_y = self.anchor_widget.winfo_rooty() + y
self.tipwindow.wm_geometry("+%d+%d" % (root_x, root_y))
def get_position(self):
"""choose a screen position for the tooltip"""
# The tip window must be completely outside the anchor widget;
# otherwise when the mouse enters the tip window we get
# a leave event and it disappears, and then we get an enter
# event and it reappears, and so on forever :-(
#
# Note: This is a simplistic implementation; sub-classes will likely
# want to override this.
return 20, self.anchor_widget.winfo_height() + 1
def showcontents(self):
"""content display hook for sub-classes"""
# See ToolTip for an example
raise NotImplementedError
def hidetip(self):
"""hide the tooltip"""
# Note: This is called by __del__, so careful when overriding/extending
tw = self.tipwindow
self.tipwindow = None
if tw:
try:
tw.destroy()
except tk.TclError: # pragma: no cover
pass
class OnHoverTooltipBase(TooltipBase):
"""abstract base class for tooltips, with delayed on-hover display"""
def __init__(self, anchor_widget, hover_delay=1000):
"""Create a tooltip with a mouse hover delay.
anchor_widget: the widget next to which the tooltip will be shown
hover_delay: time to delay before showing the tooltip, in milliseconds
Note that a widget will only be shown when showtip() is called,
e.g. after hovering over the anchor widget with the mouse for enough
time.
"""
super(OnHoverTooltipBase, self).__init__(anchor_widget)
self.hover_delay = hover_delay
self._after_id = None
self._id1 = self.anchor_widget.bind("<Enter>", self._show_event)
self._id2 = self.anchor_widget.bind("<Leave>", self._hide_event)
self._id3 = self.anchor_widget.bind("<Button>", self._hide_event)
def __del__(self):
try:
self.anchor_widget.unbind("<Enter>", self._id1)
self.anchor_widget.unbind("<Leave>", self._id2) # pragma: no cover
self.anchor_widget.unbind("<Button>", self._id3) # pragma: no cover
except tk.TclError: # pragma: no cover
pass
super(OnHoverTooltipBase, self).__del__()
def _show_event(self, event=None):
"""event handler to display the tooltip"""
if self.hover_delay:
self.schedule()
else:
self.showtip()
def _hide_event(self, event=None):
"""event handler to hide the tooltip"""
self.hidetip()
def schedule(self):
"""schedule the future display of the tooltip"""
self.unschedule()
self._after_id = self.anchor_widget.after(self.hover_delay,
self.showtip)
def unschedule(self):
"""cancel the future display of the tooltip"""
after_id = self._after_id
self._after_id = None
if after_id:
self.anchor_widget.after_cancel(after_id)
def hidetip(self):
"""hide the tooltip"""
try:
self.unschedule()
except tk.TclError: # pragma: no cover
pass
super(OnHoverTooltipBase, self).hidetip()
def showcontents(self):
"""content display hook for sub-classes"""
# See ToolTip for an example
raise NotImplementedError
class Hovertip(OnHoverTooltipBase):
"""A tooltip that pops up when a mouse hovers over an anchor widget."""
def __init__(self, anchor_widget, text, hover_delay=1000):
"""Create a text tooltip with a mouse hover delay.
anchor_widget: the widget next to which the tooltip will be shown
hover_delay: time to delay before showing the tooltip, in milliseconds
Note that a widget will only be shown when showtip() is called,
e.g. after hovering over the anchor widget with the mouse for enough
time.
"""
super(Hovertip, self).__init__(anchor_widget, hover_delay=hover_delay)
self.text = text
def showcontents(self):
label = tk.Label(self.tipwindow, text=self.text, justify=tk.LEFT,
background="#ffffe0", relief=tk.SOLID, borderwidth=1)
label.pack()
Now some code illustrating the problem I'm having:
class PopupWindow:
def __init__(self, parent):
self.parent = parent
self.gui = tk.Toplevel(self.parent)
self.gui.geometry("100x30")
self.gui.wait_visibility()
self.ok_button = tk.Button(self.gui, text="OK", command=self.on_ok_button)
self.ok_button.pack()
Hovertip(self.ok_button, text="OK button", hover_delay=500)
def on_ok_button(self):
self.gui.destroy()
def show(self):
self.gui.grab_set()
# Hovertip(self.ok_button, text="OK button", hover_delay=500)
self.gui.wait_window()
return 0
class App(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
button = tk.Button(parent, text="Button -- no hover delay", command=self.button)
button.pack()
Hovertip(button, "This is tooltip\ntext for button.", hover_delay=0)
def button(self):
window = PopupWindow(self.parent)
window.show()
if __name__ == '__main__':
root = tk.Tk()
App(root)
root.mainloop()
You'll notice that the tooltip for the OK button in the modal window appears behind the window (I'm changing the geometry of the window for otherwise it would be so small that we wouldn't actually notice this).
Of course this becomes a problem in a real window with several widgets the tips for some of them will not be seen at all.
Apparently there are two ways around the problem: one is to delete the line self.gui.wait_visibility() in the __init__ of the PopupWindow class;
the other is to delete the self.gui.grab_set() in the show() method.
With any of these the window is no longer modal (if I get the meaning right: I mean I want the window to stay on top and prevent changes in the parent window while it exists).
The commented line in the show method was my tentative of working around it by defining the tooltip after the grab_set so that it might come on top, but it doesn't work either.
I suppose there must be an way of doing this properly using this class for tooltips.
How can I do it?
Thanks.
I found a solution.
Apparently, someone had the same problem, although with a different class for tooltips.
I refer to this question and answer.
The solution is to add the line tw.wm_attributes("-topmost", 1) somewhere in the showtip method of the TooltipBase class.
I did it as a last line, but I'm not sure it doesn't work some other place; I know it doesn't if immediately after tw.wm_overrideredirect(1).

After() not reaching next iteration in splash window

I have a splash window in a tkinter application, which is a child class of Toplevel. My target is to show a GIF moving, thus I am trying with a recurrent .after() function to update a Label. My code for the Splash window is:
import tkinter as tk
class Splash(tk.Toplevel):
def __init__(self, parent):
tk.Toplevel.__init__(self, parent)
self.overrideredirect(True)
self.parent = parent
frames = [tk.PhotoImage(file="myfile.gif",format = 'gif -index %i' %(i)) for i in range(89)] #it has 89 frames
def animate(ind, label):
frame = frames[ind]
ind += 1
if ind>88: #With this condition it will play gif infinitely
ind = 0
label.configure(image=frame)
label.update()
self.after(110, animate, ind, label)
label = tk.ttk.Label(self)
label.pack(expand=1)
self.after(0, animate, 0, label)
self.parent.overrideredirect(True)
self.update()
self.lift()
Now: I tried to also put a print function before the next after call, and I could see that it reached that step. However, if I place a print(str(ind)) at the beginning of the animate function, I see only the first index appearing.
How can I actually loop in a Toplevel window in the correct way?
EDIT:
To add context to this, I have the main class App where I do the following:
from ttkthemes import ThemedStyle, ThemedTk
import GUI.splash as sp
class App:
def __init__(self, ...):
self.interface = ThemedTk()
self.interface.iconify()
splash = sp.Splash(self.interface)
...
self.interface.after(3000, splash.destroy) #Thanks #CoolCloud
self.interface.deiconify()
self.interface.mainloop()
EDIT 2:
I have tried with a minimum reproducible example:
import tkinter as tk
class Splash(tk.Toplevel):
def __init__(self, parent):
tk.Toplevel.__init__(self, parent)
self.overrideredirect(True)
self.parent = parent
frames = [tk.PhotoImage(file="C:/temp/splash.gif",format = 'gif -index %i' %(i)) for i in range(89)] #it has 89 frames
def animate(ind, label):
frame = frames[ind]
ind += 1
if ind>88: #With this condition it will play gif infinitely
ind = 0
label.configure(image=frame)
label.update()
self.after(110, animate, ind, label)
label = tk.Label(self)
label.pack(expand=1)
self.after(0, animate, 0, label)
self.update()
self.lift()
class App:
def __init__(self):
self.interface = tk.Tk()
self.interface.iconify()
splash = Splash(self.interface)
self.interface.after(3000, splash.destroy)
self.interface.deiconify()
self.interface.mainloop()
if __name__ == "__main__":
App()
It looks like the actual problem is the size of my underlying window, or at least that's what I would think, since in my case I load multiple frames (one on top of the other one) and switch between them depending on an OptionMenu. Maybe this is too much, however it works much better than destroying and rebuilding everything.
Btw, keeping my app heavy as it is, is there a better way to produce a splash screen to load my interface and show a gif moving as in my minimal example? The gif can be downloaded here: https://images.app.goo.gl/Bpi6EvpJgodiQs2e7

tkinter.TclError: image "pyimage" doesn't exist with Button wrapper class

A common problem with Tkinter is that in order to use images in Labels and Buttons, you need a reference to the PhotoImage object... somehow.
I have written a wrapper class around Button to add my own functionalities, because I want to use GIFs instead of images, and I want to be able to switch between gifs when I press the button (or use a keyboard hotkey). The first GIF runs fine and loops perfectly. When I switch to the second GIF, I get the error message, saying _tkinter.TclError: image "pyimage48 ... pyimage55" doesn't exist. It looks like the following:
from tkinter import *
from PIL import ImageTk, Image
class AnimatedButton(Button)
def __init__(self, master, size, img_paths):
self.size = size
self.seq_count = len(img_paths) # Number of gif files
self.sequences = []
for path in img_paths:
gif, delay = loadGif(path)
# Create a tuple of all frames in a gif, with the delay between frames. Store this tuple in self.sequences
self.sequences.append(([ImageTk.PhotoImage(frame) for frame in gif], delay))
self.delay = self.sequences[0][1]
self.current_sequence = self.sequences[0][0]
self.image = self.current_sequence[0]
self.seq_id = 0 # Sequence counter
self.frame_id = 0 # Frame counter
Button.__init__(self, master, image=self.image, width=size, height=size)
self.cancel = self.after(self.delay, self.play)
def play(self):
self.image = self.current_sequence[self.frame_id]
self.config(image=self.image)
# More stuff below to loop through the frames etc.
What is strange is that I don't have any of this with my other Button class, MyButton, also a wrapper class.
class MyButton(Button):
def __init__(self, master, size, img_paths):
self.image_count = len(img_paths)
self.image_id = 0
self.size = size
self.images = []
for path in img_paths:
try:
im = Image.open(path)
except:
print("Could not open file {}".format(path))
photo_image = ImageTk.PhotoImage(im, image_mode)
self.images.append(photo_image)
self.image = self.images[0]
Button.__init__(self, master, image=self.image, width=size,
height=size)
Most Google searches came up with the fact that you shouldn't use two tkinter.Tk() calls, but I am only using one (Yes, I made sure).
Any ideas are very much appreciated!
Thanks to the hint by stovfl in the comments above, I was missing [0] in play():
Correct code should be:
def play(self):
self.image = self.current_sequence[self.frame_id][0]
self.config(image=self.image)
# More stuff below to loop through the frames etc.

Python Tkinter enter event

i'm new on Tkinter and i'm trying to make an animated button.
I'm using the enter-leave events but the click on button it's not responding very well.
My code is:
imagePath = "Resources/"
imagelist = ["boton_1.gif","boton_2.gif","boton_3.gif","boton_4.gif","boton_5.gif","boton_6.gif",
"boton_7.gif","boton_8.gif","boton_9.gif","boton_10.gif","boton_11.gif","boton_12.gif",
"boton_13.gif","boton_14.gif","boton_15.gif","boton_16.gif"]
giflist = []
for imagefile in imagelist:
photo = PhotoImage(file=imagePath+imagefile)
giflist.append(photo)
self.photo=giflist[0]
button = Button(buttonFrame, image=self.photo,background='orange',activebackground='lightsalmon',
command=lambda: controller.show_frame(ListPlayerPage))
button.pack(pady=5)
def enter(event):
self.clickOnButton1 = True
for i in range(1,8):
button.config(image=giflist[i])
button.update()
time.sleep(0.1)
if self.clickOnButton1 == False:
break
while (self.clickOnButton1):
for i in range (9,15):
button.config(image=giflist[i])
button.update()
time.sleep(0.08)
if self.clickOnButton1 == False:
break
def leave(event):
self.clickOnButton1 = False
button.config(image=self.photo)
button.update()
button.bind("<Enter>",enter)
button.bind("<Leave>",leave)
Thanks!!
Part of the problem is definitely related to the fact you're calling sleep. As a good rule of thumb you should never call sleep in the main thread of a GUI. It prevents the GUI from processing all events, including screen refreshes.
Generally speaking, you should also avoid calling update. It can result in nested event loops, if during the processing of update you end up calling a method that again calls update.
Here's a really simple example of solution that creates a button that can be animated. It uses after to iterate over a list of text strings, one new string every half second. This example will animate forever, but you can easily have it show each item only once. This modifies the text to make the example shorter, but you can easily modify it to change images instead of text.
import Tkinter as tk # use tkinter for python 3.x
class AnimatedButton(tk.Button):
def __init__(self, *args, **kwargs):
tk.Button.__init__(self, *args, **kwargs)
self._job = None
def cancel_animation(self):
if self._job is not None:
self.after_cancel(self._job)
self._job = None
def animate(self, textlist):
text = textlist.pop(0)
textlist.append(text)
self.configure(text=text)
self._job = self.after(500, self.animate, textlist)
You use it like any other Button, but you can call animate to start animation and cancel_animate to cancel it:
button = AnimatedButton(root, width=10)
data = ["one","two","three","four","five","six"]
button.bind("<Enter>", lambda event: button.animate(data))
button.bind("<Leave>", lambda event: button.cancel_animation())
I followed the Bryan Oakley example and found a nice solution!
First of all, this is an animated button with a bit complex animation. I have 16 images. The firts one is the base image. Then i have eight images that are the first part of the animation. The rest of the images are the loop part of the animation.
When you put the mouse over the button, the animation starts.
Here is the code!:
import Tkinter as tk # use tkinter for python 3.x
root = tk.Tk()
root.geometry("300x200")
class AnimatedButton(tk.Button):
def __init__(self, *args, **kwargs):
tk.Button.__init__(self, *args, **kwargs)
self._job = None
self.i = 1
def cancel_animation(self,image):
self.configure(image=image)
self.i = 1
if self._job is not None:
self.after_cancel(self._job)
self._job = None
def animate(self, imagelist):
image = imagelist[self.i]
self.i+=1
if self.i == (len(imagelist)-1):
self.i = 9
self.configure(image=image)
self._job = self.after(80, self.animate, imagelist)
imagePath = "Resources/"
imagelist = ["boton_1.gif","boton_2.gif","boton_3.gif","boton_4.gif","boton_5.gif","boton_6.gif",
"boton_7.gif","boton_8.gif","boton_9.gif","boton_10.gif","boton_11.gif","boton_12.gif",
"boton_13.gif","boton_14.gif","boton_15.gif","boton_16.gif"]
giflist = []
for imagefile in imagelist:
photo = tk.PhotoImage(file=imagePath+imagefile)
giflist.append(photo)
image = giflist[0]
button = AnimatedButton(root,image = image)
button.bind("<Enter>", lambda event: button.animate(giflist))
button.bind("<Leave>", lambda event: button.cancel_animation(image))
button.pack()
root.mainloop()
Thank's!!!

How can I show/hide toolbar depending on mouse movements and mouse position inside window?

Hi Iam using Python and GTK+. In my GUI I have 2 toolbars I want show first toolbar only if user moves mouse than hide it again after few seconds as for second toolbar I want to show it when user is on particular x,y coordinates.How can I achieve it ?
EDIT:
Iam creating some kind of media player so I want toolbars to disapear while user is not using mouse in case of playerMenu toolbar or if user doesn't move it to specific location in case of ribbonBar toolbar .Iam using GTK+ here is my code for toolbars:
class Player(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
def build_UI(self):
container=Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
ribbonBar=Gtk.Toolbar()
playerMenu=Gtk.Toolbar()
def mouse_moved(self):
#TO-DO here I should check cordinates for example I want to see if mouse.y=window.height-50px and I would like to show ribbonaBar
#after that Gdk.threads_add_timeout(1000,4000,ribbonBar.hide)
#TO-DO here I show playerMenu toolbar if mouse is moved
# smt like playerMenu.show()
#after that I would call Gdk.threads_add_timeout(1000,4000,playerMenu.hide)
# to hide it again after 4 seconds
I should connect my window to some mouse event but I don't know the event name and how can I get mouse.x and mouse.y?
Why do you want to do this? Trying to use widgets that disappear when you're not moving the mouse is rather annoying, IMHO.
But anyway...
To toggle the visibility of a widget use the show() and hide() methods, or map() and unmap() if you don't want the other widgets in your window to move around. To handle timing, use gobject.timeout_add(), and you'll need to connect() your window to "motion_notify_event" and set the appropriate event masks: gtk.gdk.POINTER_MOTION_MASK and probably gtk.gdk.POINTER_MOTION_HINT_MASK. The Event object that your motion_notify callback receives will contain x,y mouse coordinates.
At least, that's how I'd do it in GTK2; I don't know GTK3.
If you want more specific help you need to post some code.
I see that you've posted some code, but it doesn't have a lot of detail... But I understand that GTK can be a bit overwhelming. I haven't used it much in the last 5 years, so I'm a bit rusty, but I just started getting into it again a couple of months ago and thought your question would give me some good practice. :)
I won't claim that the code below is the best way to do this, but it works. And hopefully someone who is a GTK expert will come along with some improvements.
This program builds a simple Toolbar with a few buttons. It puts the Toolbar into a Frame to make it look nicer, and it puts the Frame into an Eventbox so we can receive events for everything in the Frame, i.e., the Toolbar and its ToolItems. The Toolbar only appears when the mouse pointer isn't moving and disappears after a few seconds, unless the pointer is hovering over the Toolbar.
This code also shows you how to get and process mouse x,y coordinates.
#!/usr/bin/env python
''' A framed toolbar that disappears when the pointer isn't moving
or hovering in the toolbar.
A response to the question at
http://stackoverflow.com/questions/26272684/how-can-i-show-hide-toolbar-depending-on-mouse-movements-and-mouse-position-insi
Written by PM 2Ring 2014.10.09
'''
import pygtk
pygtk.require('2.0')
import gtk
import gobject
if gtk.pygtk_version < (2, 4, 0):
print 'pygtk 2.4 or better required, aborting.'
exit(1)
class ToolbarDemo(object):
def button_cb(self, widget, data=None):
#print "Button '%s' %s clicked" % (data, widget)
print "Button '%s' clicked" % data
return True
def show_toolbar(self, show):
if show:
#self.frame.show()
self.frame.map()
else:
#self.frame.hide()
self.frame.unmap()
def timeout_cb(self):
self.show_toolbar(self.in_toolbar)
if not self.in_toolbar:
self.timer = False
return self.in_toolbar
def start_timer(self, interval):
self.timer = True
#Timer will restart if callback returns True
gobject.timeout_add(interval, self.timeout_cb)
def motion_notify_cb(self, widget, event):
if not self.timer:
#print (event.x, event.y)
self.show_toolbar(True)
self.start_timer(self.time_interval)
return True
def eventbox_cb(self, widget, event):
in_toolbar = event.type == gtk.gdk.ENTER_NOTIFY
#print event, in_toolbar
self.in_toolbar = in_toolbar
#### self.show_toolbar(in_toolbar) does BAD things :)
if in_toolbar:
self.show_toolbar(True)
return True
def quit(self, widget): gtk.main_quit()
def __init__(self):
#Is pointer over the toolbar Event box?
self.in_toolbar = False
#Is pointer motion timer running?
self.timer = False
#Time in milliseconds after point stops before toolbar is hidden
self.time_interval = 3000
self.window = win = gtk.Window(gtk.WINDOW_TOPLEVEL)
width = gtk.gdk.screen_width() // 2
height = gtk.gdk.screen_height() // 5
win.set_size_request(width, height)
win.set_title("Magic Toolbar demo")
win.set_border_width(10)
win.connect("destroy", self.quit)
#self.motion_handler = win.connect("motion_notify_event", self.motion_notify_cb)
win.connect("motion_notify_event", self.motion_notify_cb)
win.add_events(gtk.gdk.POINTER_MOTION_MASK |
gtk.gdk.POINTER_MOTION_HINT_MASK)
box = gtk.VBox()
box.show()
win.add(box)
#An EventBox to capture events inside Frame,
# i.e., for the Toolbar and its child widgets.
ebox = gtk.EventBox()
ebox.show()
ebox.set_above_child(True)
ebox.connect("enter_notify_event", self.eventbox_cb)
ebox.connect("leave_notify_event", self.eventbox_cb)
box.pack_start(ebox, expand=False)
self.frame = frame = gtk.Frame()
frame.show()
ebox.add(frame)
toolbar = gtk.Toolbar()
#toolbar.set_border_width(5)
toolbar.show()
frame.add(toolbar)
def make_toolbutton(text):
button = gtk.ToolButton(None, label=text)
#button.set_expand(True)
button.connect('clicked', self.button_cb, text)
button.show()
return button
def make_toolsep():
sep = gtk.SeparatorToolItem()
sep.set_expand(True)
#sep.set_draw(False)
sep.show()
return sep
for i in xrange(5):
button = make_toolbutton('ToolButton%s' % (chr(65+i)))
toolbar.insert(button, -1)
#toolbar.insert(make_toolsep(), -1)
for i in xrange(1, 9, 2):
toolbar.insert(make_toolsep(), i)
button = gtk.Button('_Quit')
button.show()
box.pack_end(button, False)
button.connect("clicked", self.quit)
win.show()
frame.unmap()
def main():
ToolbarDemo()
gtk.main()
if __name__ == "__main__":
main()

Categories