Rechtsklick auf gtk.Button?

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ok, gelöst. Musste ``button_press_event`` nehmen, und dort dann nur auf ``event.type == 3`` reagieren.

Danke fürs zuhören ;)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

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
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

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)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

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()
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Knilch
User
Beiträge: 7
Registriert: Montag 17. Dezember 2007, 02:00
Kontaktdaten:

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Knilch
User
Beiträge: 7
Registriert: Montag 17. Dezember 2007, 02:00
Kontaktdaten:

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
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

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)
Knilch
User
Beiträge: 7
Registriert: Montag 17. Dezember 2007, 02:00
Kontaktdaten:

Vielen Dank! Funktioniert bestens :)

mfG, Knilch
scrawl
User
Beiträge: 40
Registriert: Mittwoch 20. August 2008, 17:04
Kontaktdaten:

/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.
Antworten