The gtk FileChooserWidget shows a context menu on right-click with "add to bookmarks", "show hidden files", and "show size column" options. I would like to override this menu with a custom menu.
Creating a menu on right-click from other gtk widgets (window, eventbox) is easy and there are a lot of tutorials out there showing how to do it.
I can't seem to get events from a gtk filechooser widget, however. The "on_button_press_event" callback in the following code never gets called:
#!/usr/bin/env python
import gtk
class file_chooser_test():
def __init__(self):
window = gtk.Window()
window.connect("delete_event", lambda w,e: gtk.main_quit())
chooser = gtk.FileChooserWidget()
chooser.set_size_request(600, 400)
chooser.add_events(gtk.gdk.BUTTON_PRESS_MASK)
chooser.connect("button-press-event", self.on_button_press_event)
window.add(chooser)
window.show_all()
gtk.main()
def on_button_press_event(self, widget, event=None):
print "event is: ", event
if __name__ == "__main__":
test = file_chooser_test()
Can anyone shed any light on how to override the default right-click menu on the GTK FileChooserWidget?
Thanks!
Related
I'm making an application that can change certain parameters through a Gtk.Menu. I have a Gtk.MenuButton that pops down a Gtk.Menu with other submenus in it. One of those submenus has Gtk.MenuItems with Gtk.SpinButtons in them. I have gotten the Gtk.SpinButtons to receive input by bringing their associated Gdk.Windows to the front of the Z-order with Gdk.Window.show(), but I can't get the Gtk.Entry part of the Gtk.SpinButton to receive keyboard focus.
I have tried to use Gtk.Widget.grab_focus() and other related methods to no avail. It does highlight the Gtk.Entry text, and I can type in new text, but if I click away or press enter, it doesn't actually update/change the Gtk.SpinButton value. I have connected to the "change-value" and "value-changed" signals but typing anything into the Gtk.SpinButton doesn't fire them.
I've found out that a widget can be the "focus widget" but not have the "global input focus" if its toplevel Gtk.Window doesn't also have the global focus. Therefore, I'm stuck. Is there any way around this? Can I make the Gtk.SpinButton entry field have the keyboard focus if it's in a Gtk.Menu?
Here is a minimal example:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
class Menu(Gtk.Menu):
def __init__(self):
Gtk.Menu.__init__(self)
menu_item = Gtk.MenuItem(label="Submenu")
menu_item2 = Gtk.MenuItem(label="Item")
self.append(menu_item)
self.append(menu_item2)
submenu = Gtk.Menu()
sub_mi = Gtk.MenuItem()
spin_button = Gtk.SpinButton()
spin_adj = Gtk.Adjustment(value=0,lower=0, upper=10, step_increment=1)
spin_button.set_adjustment(spin_adj)
sub_mi.add(spin_button)
submenu.append(sub_mi)
menu_item.set_submenu(submenu)
spin_button.connect("realize", self.on_realize)
spin_button.connect("map-event", self.on_map_event)
submenu.connect("button-release-event", self.on_button_release)
submenu.connect("enter-notify-event", self.on_enter)
self.show_all()
def on_realize(self, spin_button):
spin_button.add_events(Gdk.EventMask.STRUCTURE_MASK)
def on_map_event(self, spin_button, event):
for win in spin_button.get_window().get_children():
win.show()
def on_button_release(self, menu, event):
return True
def on_enter(self, menu, event):
mouse = event.get_device()
mouse.ungrab(event.time)
win = Gtk.Window()
win.set_default_size(100, 20)
win.connect("destroy", Gtk.main_quit)
mb = Gtk.MenuButton()
win.add(mb)
menu = Menu()
mb.set_popup(menu)
win.show_all()
Gtk.main()
I realize this is convoluted, and there's probably a better solution (like not using a Gtk.Menu for this...), but I've come up with a workaround anyway.
Since I can't activate or fully focus the Gtk.SpinButton I am just forcing it to update the text field whenever there is a leave-notify-event fired from it.
spin_button.connect("leave-notify-event", self.on_leave)
def on_leave(self, spin_button, event):
value = spin_button.get_text()
spin_button.set_value(float(value))
spin_button.update()
I'm having trouble figuring out how to close a python tkinter window menu when clicking on the root of the menu, ie."File".
I was hoping there was just a command option available when instantiating the menu but it appears as though that is not the case. Also I know that there is an unpost method I can use to get rid of the menu but I don't know how I would trigger it on root menu click.
Edit:
Since Bryan said that my menus should be acting the same as any other menus in my os I decided to put together an example of how I'm doing menus. Maybe I am doing something wrong here but on ubuntu in every other program if I click on the root of the menu it will close it again. In this program it does not close when clicking on the root, only when clicking elsewhere on the screen does the menu close.
import tkinter as tk
import tkinter.messagebox
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("App Here")
self.window_menu = tk.Menu(self)
self.filemenu = tk.Menu(self.window_menu, tearoff=0)
self.build_window_menu()
self.config(menu=self.window_menu)
def build_window_menu(self):
self.window_menu.add_cascade(label="File", menu=self.filemenu)
self.filemenu.add_command(label='alert', command=self._handle_menualert)
def _handle_menualert(self):
tk.messagebox.showwarning(
"Menu Stuff",
"I am menu alert!"
)
if __name__ == '__main__':
app = App()
app.mainloop()
from gi.repository import Gtk, Gdk
def drag_data_get_cb(widget, drag_context, selection_data, info, time):
print selection_data.get_data_type()
print widget.get_text()
return widget.get_text()
def drag_begin_cb(widget, dragcontext):
print dragcontext, widget
return dragcontext
label = Gtk.Label()
label.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.COPY)
label.set_text("Drag Me!")
label.connect("drag_data_get", drag_data_get_cb)
label.connect("drag_begin", drag_begin_cb)
window = Gtk.Window()
window.add(label)
window.connect("delete_event", Gtk.main_quit)
window.set_default_size(300, 250)
window.show_all()
Gtk.main()
ive been hitting my head against a wall over this for a few days now,
can anyone tell me why this doesnt allow me to drag text into other widgets? neither of the drag events fire at all
It says in this tutorial that you cannot use widgets without windows, such as Gtk.Label as drag and drop sources. You can replace the label with a button for instance:
label = Gtk.Button.new_with_label("Drag Me!")
in order for this example to work.
I am new to Python GTK programming. In my UI i have a button. On click of that i have to open a popup which has a three button and some label. I have to pass some variables from main window to popup window. on click of buttons on the popup window I have to update this variable. Then once i close this popup window I need the updated value of the variables in main window.
1. Can I do this in Python GTK.
2. If yes how will i go about achieving it.
3. Can I use glade file for creating a glade file.
You probably need dialog boxes.
From pygtk :
import gtk
label = gtk.Label("Nice label")
dialog = gtk.Dialog("My dialog",
None,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
dialog.vbox.pack_start(label)
label.show()
checkbox = gtk.CheckButton("Useless checkbox")
dialog.action_area.pack_end(checkbox)
checkbox.show()
response = dialog.run()
dialog.destroy()
I'd like to be able to put a gtk.ProgressBar in my gtk.Menu, but since menus only takes gtk.MenuItems and its subclasses, what I've done instead is take a plain gtk.MenuItem and tried adding my progress bar as a child to that. Since gtk.MenuItem is a subclass of gtk.Bin, it should be able to hold pretty much any widget.
Example:
menu = gtk.Menu()
item = gtk.MenuItem()
button = gtk.ProgressBar()
button.pulse()
button.show()
item.add(button)
item.show()
menu.append(item)
This runs just fine without pygtk complaining at all. However, my progress bar is simply not shown:
If I replace the progressbar with a gtk.Label, it's shown just fine.
Now to my questions:
How do I know which widgets it will take?
How do I trick it into letting me put other widgets in there?
This is a limitation of Ubuntu's Application Indicators, see this question at askubuntu.
Your example code works here(I tested it by modifying a pygtk example that I will paste below).
Maybe its an issue with the rest of your code or your theme?
#!/usr/bin/env python
# example menu.py
import pygtk
pygtk.require('2.0')
import gtk
class MenuExample:
def __init__(self):
# create a new window
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(200, 100)
window.set_title("GTK Menu Test")
window.connect("delete_event", lambda w,e: gtk.main_quit())
# Init the menu-widget, and remember -- never
# show() the menu widget!!
# This is the menu that holds the menu items, the one that
# will pop up when you click on the "Root Menu" in the app
menu = gtk.Menu()
### MODIFIED PART!! ###
item = gtk.MenuItem()
button = gtk.ProgressBar()
button.pulse()
button.show()
item.add(button)
item.show()
menu.append(item)
#### END MODIFIED PART ####
# This is the root menu, and will be the label
# displayed on the menu bar. There won't be a signal handler attached,
# as it only pops up the rest of the menu when pressed.
root_menu = gtk.MenuItem("Root Menu")
root_menu.show()
# Now we specify that we want our newly created "menu" to be the
# menu for the "root menu"
root_menu.set_submenu(menu)
# A vbox to put a menu and a button in:
vbox = gtk.VBox(False, 0)
window.add(vbox)
vbox.show()
# Create a menu-bar to hold the menus and add it to our main window
menu_bar = gtk.MenuBar()
vbox.pack_start(menu_bar, False, False, 2)
menu_bar.show()
# Create a button to which to attach menu as a popup
button = gtk.Button("press me")
button.connect_object("event", self.button_press, menu)
vbox.pack_end(button, True, True, 2)
button.show()
# And finally we append the menu-item to the menu-bar -- this is the
# "root" menu-item I have been raving about =)
menu_bar.append (root_menu)
# always display the window as the last step so it all splashes on
# the screen at once.
window.show()
# Respond to a button-press by posting a menu passed in as widget.
#
# Note that the "widget" argument is the menu being posted, NOT
# the button that was pressed.
def button_press(self, widget, event):
if event.type == gtk.gdk.BUTTON_PRESS:
widget.popup(None, None, None, event.button, event.time)
# Tell calling code that we have handled this event the buck
# stops here.
return True
# Tell calling code that we have not handled this event pass it on.
return False
# Print a string when a menu item is selected
def menuitem_response(self, widget, string):
print "%s" % string
def main():
gtk.main()
return 0
if __name__ == "__main__":
MenuExample()
main()