Seite 1 von 1

Rechtsklick auf gtk.Button?

Verfasst: Freitag 2. Mai 2008, 11:44
von Leonidas
Hi,

Ich versuche gerade ein Kontext-Menü aufzumachen, wenn man auf einen Button rechtsklickt, nur stellt sich heraus, dass der gtk.Button scheinbar keine Signals für Rechtsklick bereitstellt. Weiß hier jemand, wie man das lösen kann?

Verfasst: Freitag 2. Mai 2008, 11:58
von Leonidas
Ok, gelöst. Musste ``button_press_event`` nehmen, und dort dann nur auf ``event.type == 3`` reagieren.

Danke fürs zuhören ;)

Verfasst: Freitag 2. Mai 2008, 11:59
von Trundle
Das kann man mit dem ``button-press-event``-Signal machen, das jedes Widget hat.

Code: Alles auswählen

def on_button_press(widget, event):
    if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
        # Rechtsklick
        pass

button.connect('button-press-event', on_button_press)
Edit: Zu lahm.

Verfasst: Freitag 2. Mai 2008, 13:37
von Leonidas
Ja, danke trotzdem :)

gtk.gdk.BUTTON_PRESS muss ich nicht testen, wenn ich den Callback nur für ``button-press-event`` nutze, nehme ich mal an. Ich habe gehofft, dass es eine symbolische Konstante für die rechte Maustaste gibt, aber das scheint leider nicht der Fall zu sein.

Naja, das nächste Ziel wird sein, das Kontextmenü anzuzeigen. Mal sehen wie das hinhaut.

Verfasst: Freitag 2. Mai 2008, 14:37
von EnTeQuAk
Sollte das mit dem Kontextmenü klappen währe ich dir sehr verbunden wenn du eventuell einen kleinen Eintrag im Codesnippets-Forum machen könntest. Ich denke, sowas kann man immer mal brauchen :=)


Gruß, Christopher

Verfasst: Freitag 2. Mai 2008, 19:57
von Trundle
Leonidas hat geschrieben:gtk.gdk.BUTTON_PRESS muss ich nicht testen, wenn ich den Callback nur für ``button-press-event`` nutze, nehme ich mal an.
Das Signal wird auch bei Doppelklicks ausgelöst, das ist dann ``gtk.gtk._2BUTTON_PRESS``.
Leonidas hat geschrieben:Naja, das nächste Ziel wird sein, das Kontextmenü anzuzeigen. Mal sehen wie das hinhaut.
Das geht dann einfach mit

Code: Alles auswählen

menu.popup(None, None, None, event.button, event.time)

Verfasst: Freitag 2. Mai 2008, 23:01
von Leonidas
Ah, besten Dank, funktioniert prima.

Das ganze in Aktion (wenn man davon absieht, dass die MenuItems alle nur Dummies sind):

Code: Alles auswählen

context_menu = gtk.Menu()
enabled_item = gtk.CheckMenuItem('Enabled')
configure_item = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
context_menu.append(enabled_item)
context_menu.append(configure_item)
context_menu.show_all()
context_menu.popup(None, None, None, event.button, event.time)

Verfasst: Freitag 2. Mai 2008, 23:17
von Leonidas
Uh, hab mich jetzt wieder mal ausmanövriert - wenn der Button nicht ``sensitive`` ist, dann wird auch der ``button_press_event`` nicht aufgerufen. Das ist ja schade, denn so kann ich Buttons übers Kontextmenü abschalten, aber nicht wieder aktivieren. Schlicht weil das Kontextmenü nicht erscheint :?

Edit: Bin nicht der einzige dem das passiert ist.

Verfasst: Samstag 3. Mai 2008, 10:36
von Trundle
Man könnte den Button in eine `gtk.EventBox` packen. Wenn man jetzt ``button.set_sensitive(False)`` aufruft, einfach noch die EventBox über dem Button platzieren (mit ``event_box.set_above_child(True)``).

Hier mal ein Beispiel, das einen Button auf Mausklick abwechselnd ``sensitiv`` und ``insensitiv`` setzt:

Code: Alles auswählen

import gtk

def on_button_press(widget, event, other_widget):
    if isinstance(widget, gtk.Button):
        widget.set_sensitive(False)
        other_widget.set_above_child(True)
    else:
        widget.set_above_child(False)
        other_widget.set_sensitive(True)


def main():
    window = gtk.Window()
    button = gtk.Button('Klick mich!')
    event_box = gtk.EventBox()
    event_box.add(button)
    event_box.set_above_child(False)
    event_box.connect('button-press-event', on_button_press, button)
    button.connect('button-press-event', on_button_press, event_box)
    window.add(event_box)
    window.show_all()
    gtk.main()


if __name__ == '__main__':
    main()

Verfasst: Samstag 3. Mai 2008, 14:08
von Leonidas
Ah, perfekt, das hilft mir schon mal sehr weiter. Werds später in mein Programm einbauen. Hmm, der Code ist ja so ziemlich genau das was ich brauche :) Besten Dank.

Verfasst: Montag 5. Mai 2008, 18:44
von Knilch
Hallo,
ich habe ein aehnliches Problem. Allerdings moechte ich, dass ein Menue beim Rechtsklick auf ein Status-Icon erscheint.
In der Doc steht Folgendes:
def popup(parent_menu_shell, parent_menu_item, func, button, activate_time, data=None)

button : the mouse button which was pressed to initiate the event.
Allerdings verstehe ich nicht wirklich was bei 'button' eingesetzt werden muss; Bei dem Wert 1 funktioniert es zumindest wenn man mit der linken Maustaste darauf klickt.

Ich bin noch recht frisch in Python eingestiegen; Tut mir Leid falls das vielleicht irgendwas total Offensichtliches ist :?

mfG, Knilch

Verfasst: Montag 5. Mai 2008, 18:52
von Leonidas
Hallo Knilch, willkommen im Forum,
Da kommt ``event.button`` hin. Du musst ``popup()`` im Callback von ``button-press-event`` aufrufen, diesem wird vom Toolkit ein ``event``-Objekt übergeben (siehe Trundles Code, Zeile 3).

Verfasst: Montag 5. Mai 2008, 19:42
von Knilch
Hallo,
anscheinend funktioniert das mit dem button-press-event bei gtk.StatusIcon nicht, da ich folgende Ausgabe erhalte:
stat_icon.connect("button-press-event",on_button_press)
TypeError: <gtk.StatusIcon object at 0x82e3324 (GtkStatusIcon at 0x837ac40)>: unknown signal name: button-press-event
mfG, Knilch

Verfasst: Montag 5. Mai 2008, 19:59
von Trundle
Knilch hat geschrieben:Hallo,
anscheinend funktioniert das mit dem button-press-event bei gtk.StatusIcon nicht, da ich folgende Ausgabe erhalte:
stat_icon.connect("button-press-event",on_button_press)
TypeError: <gtk.StatusIcon object at 0x82e3324 (GtkStatusIcon at 0x837ac40)>: unknown signal name: button-press-event
Das liegt daran, dass `gtk.StatusIcon` nicht von `gtk.Widget` erbt. Aber `gtk.StatusIcon` kennt das Signal ``popup-menu``, das genau dafür gedacht ist.

Beispiel:

Code: Alles auswählen

def on_popup_menu(status_icon, button, time):
    menu = gtk.Menu()
    # ...
    menu.popup(None, None, None, button, time)
status_icon.connect('popup-menu', on_popup_menu)

Verfasst: Montag 5. Mai 2008, 20:11
von Knilch
Vielen Dank! Funktioniert bestens :)

mfG, Knilch

Verfasst: Montag 15. September 2008, 14:21
von scrawl
/Edit: Verdammt, es heißt ja event.button und nicht event.type, jetzt hab ich mich von deinem zweiten Post irritieren lassen Leonidas :?
gelöst

Hm, bei mir will das grade irgendwie nicht :?
Ich benutz den Code hier:

Code: Alles auswählen

self.view.connect_object("button-press-event", self.button_press, item_menu)
def button_press(self, widget, event):
	if event.type == 3:
	       # right click
		print "test"
		widget.popup(None, None, None, event.button, event.time)
self.view ist eine gtk.TreeView.
Ich krieg aber weder "test" ausgegeben noch das Menu aufgepoppt :(
Nur wenn ich das if event.type == 3: auskommentiere, funktioniert es, aber dann halt auch bei einem einfachen Klick.
Woran kann das liegen?
print event.type liefert mir komischerweise auch nur "<enum GDK_BUTTON_PRESS of type GdkEventType>" und nichts wie 2 oder 3.