pygobject creating a drag and drop source - python

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.

Related

Can a Gtk.Entry (part of a Gtk.SpinButton) "have-focus" if it's in a Gtk.Menu?

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()

Why does the destroy signal not reach the children of a Gtk.ScrolledWindow?

Please consider this python code for a simple GTK window:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
def on_destroy(widget):
print("Destroying {}".format(widget))
def on_click(button, scroll):
scroll.destroy()
scroll = Gtk.ScrolledWindow()
scroll.connect("destroy", on_destroy)
button = Gtk.Button.new_with_label("Self-destruct")
scroll.add(button)
button.connect("destroy", on_destroy)
button.connect("clicked", on_click, scroll)
window = Gtk.Window()
window.add(scroll)
window.connect("destroy", Gtk.main_quit)
window.set_size_request(200, 75)
window.show_all()
Gtk.main()
When pressing the button, I would expect to get two output lines reporting that the ScrolledWindow and the button got destroyed. In reality I only get one line reporting about the ScrolledWindow, the destroy signal never reaches the button. If I replace the ScrolledWindow with a normal Box, the destroy signal reaches the button. Why is this?
I really can't tell you much more than this code which does delete the button. Hopefully, you can adapt it to your needs. It does seem like the button unattaches itself from the Viewport and attaches itself to nothing, because the button's destroy handler runs on app shutdown, and causes weird errors. It would be interesting to post this on the Gtk mailing list for any other thoughts.
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
def on_destroy(widget, viewport):
print("Destroying {}".format(widget))
viewport.get_child().destroy()
def on_button_destroy(widget):
print("Destroying button {}".format(widget))
def on_click(button):
scroll = button.get_parent().get_parent()
scroll.destroy()
scroll = Gtk.ScrolledWindow()
button = Gtk.Button.new_with_label("Self-destruct")
scroll.add(button)
viewport = button.get_parent()
button.connect("destroy", on_button_destroy)
scroll.connect("destroy", on_destroy, viewport)
button.connect("clicked", on_click)
window = Gtk.Window()
window.add(scroll)
window.connect("destroy", Gtk.main_quit)
window.set_size_request(200, 75)
window.show_all()
Gtk.main()

Have a popup window stay centered on parent - Glade, GTK, Python

Can anyone tell me how I can have a preference pop-up stay centered on parent window even while moving the parent window? Thank you :)
Here is a very simple example, the preference window is centered and while moving it the parent will also move (but will depend on window manager):
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class AppWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Python Example")
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,spacing=6)
self.add(box)
button1 = Gtk.Button("Information")
button1.connect("clicked", self.on_button_clicked)
box.add(button1)
treeview = Gtk.TreeView()
treeview.set_size_request(640,480)
box.add(treeview)
def on_button_clicked(self, widget):
preferences_window = Gtk.Window (Gtk.WindowType.TOPLEVEL)
preferences_window.set_title ("Preferences Window")
preferences_window.set_modal (True)
preferences_window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
preferences_window.set_transient_for(self)
preferences_window.show_all()
preferences_window.connect("delete-event", preferences_window.destroy);
win = AppWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
Resulting in:

How to override default right-click menu in Gtk FileChooserWidget

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!

Python: How do I get Gtk.scrolledwindow to scroll to a selection in Gtk.Treeview

How do I get Gtk.scrolledwindow to scroll to a selection in Gtk.Treeview.
I am writing a touch screen kiosk app that has up and down button to move a selection in a treeview.
It doesn't it doesn't scroll down the scrolledwindow when the selection goes off the screen.
My idea to get around this is when the down button is pressed for the selection to move down one (as it already does) and then for the scrolledwindow to scroll to the selection on treeview but I'm unable to work out how.
I'm using Gtk3
Can anyone give me any ideas?
See: http://lazka.github.io/pgi-docs/Gtk-3.0/classes/TreeView.html#Gtk.TreeView.scroll_to_cell
Do not add you treeview to the scrolled window with "add_with_viewport". See http://mailman.daa.com.au/cgi-bin/pipermail/pygtk/2009-January/016440.html
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Auto Scroll")
self.set_size_request(400, 200)
self.liststore = Gtk.ListStore(str, str)
for n in range(40):
self.liststore.append(["Info", "http://lazka.github.io/pgi-docs/Gtk-3.0/classes/TreeView.html"])
treeview = Gtk.TreeView(model=self.liststore)
for n, name in enumerate(["Name", "Link"]):
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Text", renderer_text, text=n)
treeview.append_column(column_text)
scrolled_window = Gtk.ScrolledWindow()
self.add(scrolled_window)
scrolled_window.add(treeview)
def main(self):
Gtk.main
win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
After you've moved the selection call gtk_tree_view_scroll_to_cell on the selected path.

Categories

Resources