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.
Related
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()
I've made a program in python with Tkinter that allows you to free draw and choose different colors. I decided to make a button that would close the window instead of clicking the exit button in the top right corner. My question is how do I make the window close when the button is pressed?
If you are using a main loop for your application, then you can use the .destroy() method to release all the resources associated with the window and close the application. You call this method within the command function for your button like so:
from tkinter import *
root = Tk()
frame = Frame(root)
frame.pack(side=LEFT)
button = Button(frame, text="Exit", command=exit)
button.pack()
root.mainloop()
def exit():
root.destroy()
That should close your window. Optionally, the destroy() method may also be used at the end of your main loop if the X button of your application won't close the window immediately.
See these examples for more info:
http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.destroy-method
http://effbot.org/tkinterbook/tkinter-hello-again.htm
I have an issue with accessing to Tkinter button objects.
My idea that 2nd button is disabled if first button wasn't pressed.
If 1st button is pressed TopLevel window pops up with input fields.
When 3rd button is pressed works my function.And I'd like to change text of 4th button and destroy 3rd button.
I can't do that from my function
self.win = tk.Toplevel()
self.win.geometry('350x200')
self.win.transient(root)
self.win.grab_set()
self.btn_cancel = tk.Button(master=self.win, text='Отмена',
command=self.win.destroy).grid(row=8, column=1)
self.btn_conn = tk.Button(master=self.win, text='Проверить',
command=self.entry_db_check).grid(row=8, column=0)
def entry_db_check(self):
<my code is here>
After all manipulation 2nd button must be active.
I saw that it should work so
self.btn_cancel.destroy()
self.btn_conn['text']='OK'
Should I switch to frames instead of TopLevel window to make it work?
Hello I am trying to make a simple recorder in Python 2.7 using Tkinter as the GUI, I want to be able to record when the button is pressed then save the recording when the button is released, I know how to make the button and have already done so, but I don't know how to make it run a program when pressed and another when released, is it possible?
Also I'm not sure how to actually record from the microphone and save it using pyaudio, any help with this is appreciated but I'm sure I can figure this out myself when I have overcome the main issue.
You can bind an event to the click of the left mouse button <Button-1> and to the release of the left mouse button <ButtonRelease-1>. Here's an example:
import Tkinter as tk
root = tk.Tk()
def clicked(event):
var.set('Clicked the button')
def released(event):
var.set('Released the button')
var = tk.StringVar()
var.set('Nothing to see here')
label = tk.Label(root, textvar=var)
label.pack()
but = tk.Button(root, text='Button')
but.bind("<Button-1>", clicked)
but.bind("<ButtonRelease-1>", released)
but.pack()
root.mainloop()
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.