Right Click Menu (context menu) using PyGTK - python

So I'm still fairly new to Python, and have been learning for a couple months, but one thing I'm trying to figure out is say you have a basic window...
#!/usr/bin/env python
import sys, os
import pygtk, gtk, gobject
class app:
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("TestApp")
window.set_default_size(320, 240)
window.connect("destroy", gtk.main_quit)
window.show_all()
app()
gtk.main()
I wanna right click inside this window, and have a menu pop up like alert, copy, exit, whatever I feel like putting down.
How would I accomplish that?

There is a example for doing this very thing found at http://www.pygtk.org/pygtk2tutorial/sec-ManualMenuExample.html
It shows you how to create a menu attach it to a menu bar and also listen for a mouse button click event and popup the very same menu that was created.
I think this is what you are after.
EDIT: (added further explanation to show how to respond to only right mouse button events)
To summarise.
Create a widget to listen for mouse events on. In this case it's a button.
button = gtk.Button("A Button")
Create a menu
menu = gtk.Menu()
Fill it with menu items
menu_item = gtk.MenuItem("A menu item")
menu.append(menu_item)
menu_item.show()
Make the widget listen for mouse press events, attaching the menu to it.
button.connect_object("event", self.button_press, menu)
Then define the method which handles these events. As is stated in the example in the link, the widget passed to this method is the menu that you want popping up not the widget that is listening for these events.
def button_press(self, widget, event):
if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
#make widget popup
widget.popup(None, None, None, event.button, event.time)
pass
You will see that the if statement checks to see if the button was pressed, if that is true it will then check to see which of the buttons was pressed. The event.button is a integer value, representing which mouse button was pressed. So 1 is the left button, 2 is the middle and 3 is the right mouse button. By checking to see if the event.button is 3, you are only responding to mouse press events for the right mouse button.

Related

How to detect which key was pressed on keyboard/mouse using tkinter/python?

I'm using tkinter to make a python app and I need to let the user choose which key they will use to do some specific action. Then I want to make a button which when the user clicks it, the next key they press as well in keyboard as in mouse will be detected and then it will be bound it to that specific action. How can I get the key pressed by the user?
To expand on #darthmorf's answer in order to also detect mouse button events, you'll need to add a separate event binding for mouse buttons with either the '<Button>' event which will fire on any mouse button press, or '<Button-1>', (or 2 or 3) which will fire when that specific button is pressed (where '1' is the left mouse button, '2' is the right, and '3' is the middle...though I think on Mac the right and middle buttons are swapped).
import tkinter as tk
root = tk.Tk()
def on_event(event):
text = event.char if event.num == '??' else event.num
label = tk.Label(root, text=text)
label.place(x=50, y=50)
root.bind('<Key>', on_event)
root.bind('<Button>', on_event)
root.mainloop()
You can get key presses pretty easily. Without knowing your code, it's hard to say exactly what you will need, but the below code will display a label with the last key pressed when ran and should provide enough of an example to show you how to adapt it to your program!
from tkinter import Tk, Label
root=Tk()
def key_pressed(event):
w=Label(root,text="Key Pressed: "+event.char)
w.place(x=70,y=90)
root.bind("<Key>",key_pressed)
root.mainloop()

Tkinter Button doesn´t change it´s relief after pressing it

Why does my tkinter Button stays in the "sunken" relief after I press it?
import tkinter
from tkinter import messagebox as msgbox
class GUI(object):
def __init__(self):
self.root = tkinter.Tk()
self.root.geometry("200x200")
self.root.title("Test")
self.testButton = tkinter.Button(self.root, text="Click Me!")
self.testButton.bind("<Button-1>", self.click)
self.testButton.bind("<ButtonRelease-1>", self.release)
self.testButton.pack()
def release(self, event):
event.widget.config(relief=tkinter.RAISED)
def click(self, event):
result = msgbox.askokcancel("Continue?", "Do you want to continue?")
if result:
print("Okay")
else:
print("Well then . . .")
print(event.widget.cget("relief"))
print()
if __name__ == "__main__":
test = GUI()
test.root.mainloop()
The console shows that the relief is "raised" but on the GUI it stays in the "sunken" relief , why?
The GUI after pressing the Button
Your callback is printing "raised" because your code is run before the default button bindings, so the button relief is in fact raised at the point in time when your function is called.
I'm pretty sure this is what is causing the button to stay sunken:
you click on the button, and a dialog appears. At this point the button is raised because tkinter's default binding has not yet had a chance to run 1, and it is the default bindings which cause the button to appear sunken
a dialog appears, which steals the focus from the main window.
you click and release the button to click on the dialog. Because the dialog has stolen the focus, this second release event is not passed to the button
at this point the processing of the original click continues, with control going to the default tkinter binding for a button click.
the default behavior causes the button to become sunken
at this point, your mouse button is not pressed down, so naturally you can't release the button. Because you can't release the button, the window never sees a release event.
Because the button never sees a button release event, the button stays sunken
1 For a description of how tkinter handles events, see this answer: https://stackoverflow.com/a/11542200/7432. The answer is focused on keyboard events, but the same mechanism applies to mouse buttons.

PyQt4: Changing button icon on action

I'm trying to change buttons icon on specific action. (Clicked, Disabled etc.)
So as an example lets take a button press, If i have a button:
btn = QtGui.QPushButton(" ", self)
btn.resize(100, 100)
btn.move(0, 0)
btn.setIcon(QtGui.QIcon(""))
btn.setIconSize(QtCore.QSize(100, 100))
How can i change its icon when clicked? Do i need to make a clicked signal?
btn.clicked.connect(self.some_function_that_shows_new_icon)
If so, how can i make disabled signal or any other button condition available?
Example:
btn.disabled.connect(self.some_function_that_shows_new_icon)
(Signal that will detect if buttons disabled or not, One above doesn't work)
QIcons can have multiple images for different modes and states. You add multiple QPixmaps to the same QIcon and specify the mode and state for that image.
icon = QIcon()
icon.addPixmap(QPixmap('normal.png'))
icon.addPixmap(QPixmap('disabled.png'), QIcon.Disabled)
icon.addPixmap(QPixmap('clicking.png'), QIcon.Active)
icon.addPixmap(QPixmap('on.png'), QIcon.Normal, QIcon.On)
btn.setIcon(icon)
It depends on whether clicking the button is changing the state of the button (eg. toggling it on or off). If you're using the button to toggle the state of something else, this won't work.

tkinter: How to automatically scroll using middle mouse button?

right now I have an implementation where I'm using my middle mouse button for two operations:
Zooming (in and out) by rolling the wheel and
Scrolling the wheel button to scroll(pan) left, right, top and bottom. But in this feature, I have press and hold the scroll button continuously, only then can I scroll.
What I wish to do is:
Press and release the middle mouse button to enter scrolling mode.
Then, simply, move the mouse left and right and, top and bottom, to scroll in the respective directions.
Once done, press and release the middle mouse button to come out of this mode.
It is just like how it is implemented in MS Word or Chrome browser.
Help!
Here's a quick simple thing of what I believe you're after.
import tkinter as tk
root = tk.Tk()
pressed = False
def onClick(event):
global pressed
pressed = not pressed # toggle pressed when clicked
print('Pressed')
def onMove(event):
if pressed:
print(event.x, event.y)
root.bind('<Button-2>', onClick)
root.bind('<Motion>', onMove)
root.mainloop()

What can block mousePressEvent or Event Filter Mouse Click Events?

I can't seem to get any mouse clicks in a QTreeWidget. I have tried...
...overriding mousePressEvent, but it never runs at all. Not even to log a message.
...using an event filer. It works for everything but mouse clicks.
...using delegates. Their editor events work fine, but only when over an item, which isn't enough
...making sure everything is being added to layouts. I used QTCreator and the output is using layout.addWidget(). I am also adding the widget instance to a layout in the main window.
I was able to use the answer to register the widget as an event filter for the QTreeWidget like so:
# In __init___
# self.tree is the QTreeWidget
self.tree.viewport().installEventFilter(self)
def eventFilter(self, target, event):
"""
This widget is an event filter for the tree, so this function is triggered
automatically
"""
# Print on right-click
if (event.type() == QEvent.MouseButtonPress and
event.button() == Qt.RightButton):
print("Right Click")
# Don't block/accept the event
return False
because what you can see (and click) on QTreeWidget is actually it's viewport(). You sholud install event filter on it's viewport() instead.

Categories

Resources