i'd like to hide a FileChooserDialog when i delete its window.
I can just hide it from the the 'Cancel' Button but when i close it from its window it doen't respond and then it crashes.
View the crash here
The crash happens when i do this, in sequence:
I open it (it works fine)
I try to close it from the window 'X' button: the buttons 'OK' and 'CANCEL' disappear and FileFilter too
I re-try to close it. Now the window become white: it seems it doesn't respond.
I re-try to close it. It is closed.
I try to re-open the FileChooserDialog just closed. It doesn't work anymore and the shell now tells me what it's wrong.
My code is simple:
self.__apri_FileChooserDialog = Gtk.FileChooserDialog(title='', \
parent=None, \
action=Gtk.FileChooserAction.OPEN, \
buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, \
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
self.__salva_FileChooserDialog.connect("delete-event", self.nascondi)
def nascondi(self, widget, args=()):
widget.get_window().hide_on_delete()
def nascondi(self, widget, args=()):
widget.get_window().hide_on_delete()
For some reason you get the GdkWindow of the dialog widget here, and try to call a method that GdkWindow does not have. That cannot work...
In any case hide_on_delete() is, as far as I know, a bit useless in python (because the number of arguments does not match the signal). Fortunately doing it yourself is not difficult. Try this:
def on_delete_event (widget, event):
widget.hide()
return True
self.__salva_FileChooserDialog.connect("delete-event",
on_delete_event)
Related
consider the following code:
from tkinter import *
root=Tk()
root.geometry('700x700')
frame=Frame(root)
frame.pack(fill=BOTH,expand=True)
def opencanvas():
canvas=Canvas(frame,bg='red')
canvas.place(x=50,y=50,height=300,width=300)
button2=Button(frame,text='exit',command=canvas.place_forget)
button2.place(x=5,y=10)
button1=Button(frame,text='open',command=opencanvas)
button1.place(x=5,y=10)
mainloop()
this program opens a frame in a tkinter window and a 'open' button in the frame.when pressing 'open',a canvas opens and a button named 'exit' appears in frame at the same place of the open button.exit button hides canvas.
when clicking the 'exit' button,i want to disappear the 'exit' button automatically after performing its operation(ie,hiding canvas). what should i do to work this?
I want to insert some commands inside opencanvas() which disappears the button2 right after it pressed.
nb: the two buttons should place at same place and have same dimensions.
Use button1.place_forget() or .grid_forget() or .pack_forget() depending on which geometry manager you use. If you use these, then the button is hidden. To get the button back use .place() etc...
If you want to, you could use button1.destroy() but this deletes the button permanently, and if you have to make that button again, you have to initialise from start.
Use button.place_forget() for your code to hide the button and then, button1.place(x=5,y=10) to show your button
I found the answer for my question.It can be done by using lambda inside button command as follows.
button2=Button(frame,text='exit',command=lambda:[canvas.place_forget(),button2.place_forget()])
lambda function executes the commands one by one.
I am having a problem with Tkinter detecting the wrong cursor position when the application is in fullscreen mode on macOS.
I have created a Python 3 application with a Tkinter GUI on macOS (Mojave). The application works well until the green full screen button is pressed. After this the menu bar is hidden as expected, but the window only expands to 2560x1395 on a 2560x1440 display. The interface also detects the mouse cursor above where it appears on the screen, which makes the application impossible to use. I have tried forcing the application to expand to the full height of 1440, but it immediately changes back to 1395.
Here is a minimal case demonstrating the problem:
import tkinter as tk
def test():
print("Test")
root = tk.Tk()
tk.Button(root, text="Test", width=20, command=test).pack()
root.mainloop()
While in normal windowed mode, clicking the button causes "Test" to be printed. While in full screen the user must click below the button for the click to be registered. Exiting the application while in full screen mode also causes a segmentation fault.
In my application, clicking where the red dot is causes the OptionMenu to open:
The applications which support macOS properly opens in a separate Desktop tab when used in fullscreen. As far as I observed this is not case with tkinter, the window expands to fit completely with the screen size onto the main Desktop tab.
Why there is an offset when in fullscreen mode?
The offset is of the titlebar which hides in fullscreen mode but doesn't register and shifts all the widgets accordingly. That's why mouse clicks register + 24 (height of the titlebar) from the click. To avoid this we use root.attributes('-fullscreen', 1).
To exit fullscreen we can use <Escape> bind as Escape key in most application is to exit from fullscreen like in Safari. You can also use a Button.
root.bind('<Escape>', lambda e: root.attributes('-fullscreen', 0))
I couldn't find an event handler for fullscreen mode on Mac so I used <Configure> with condition root.attributes('-fullscreen') to check if the user clicked for fullscreen or not.
This is what I come up with.
from tkinter import *
root = Tk()
Button(root, width=20, text='Hello').pack()
def full_screen(evt=None):
# checks if the window is in fullscreen
if root.attributes('-fullscreen'):
root.attributes('-fullscreen',1)
# Remove the borders and titlebar
root.overrideredirect(True)
root.overrideredirect(False)
root.bind('<Configure>', full_screen)
# Escape bind to exit fullscreen.
root.bind('<Escape>', lambda e: root.attributes('-fullscreen', 0))
root.mainloop()
This issue is known for 6 months now, and Apple is doing nothing about it, now the fun fact is the logic display is fine (if you record your screen or if you screen share it doesn't happen) it only happens on the physical screen, and it only happens on MBP 16"
I am now over the fact that there is a hardware issue with the (some) MBP 16" video cards and Apple is just playing dumb.
If it helps, having your screen without scale or with "double" scale works fine, it's in the 3 intermediate scales that the issue presents itself
Still quite new at python , i'm learning tkinter.
I would like to use keyboard events rather than mouse events for some fonction.
However keyboard events do not work although mouse events do.
here is a very simple example of what is not working. Using button 1 with the mouse and pressing key 'z on the keyboard should do the same, but the keyboard does nothing. I have tried to read tkinter documentation but didn't find the answer.
thanks for your help
from tkinter import *
class Pipi(Frame):
def __init__(self,master=None):
Frame.__init__(self,width=400,height=400,bg='red')
self.pack()
self.bind("<z>",self.do)
self.bind("<Button-1>", self.do)
def do(self,event):
print('la vie est belle')
root=Tk()
Pipi(root)
root.mainloop()
This is due to Frame widget not having the focus. With the mouse event, it works seemingly different. There can be a couple of workarounds:
Grabbing the focus before the event happens
binding to something else
To achieve the first, simply add:
self.focus_set()
somewhere inside __init__.
To achieve the second, replace:
self.bind("<z>",self.do)
with:
self.master.bind('<z>', self.do)
Trying to create a pop up canvas that will pop up when I hit the certain key combination and then it will display images that can be scrolled through using the arrow keys and then closed out with the escape key. This is all going on top of a canvas that has a map drawn on it that I can use the the arrow keys to move around the map. Since I'm having many issues with this that are all pretty much interrelated I figured I would just asking them all with one post instead of doing separate posts, it may come in very handy to have all the information in one place for other people as well.
Currently, I have tried several approaches to solve the problem, I do see one other possible option just a couple minutes ago since I finally got online this morning but it didn't seem to want to work.
Question 1: Where do you form the pop up canvas? In the original
def __init__(self, parent):
or do you normally wait until the time of the switch over to the pop up to form the pop canvas? I have tried it both ways and have seen problems with both approaches. Forming it at the start up causes the pop up to pop up on the screen right from the get go. I have seen on effbot.org that supposedly using the state='hidden' attribute exists but when I try to use it all I get is an error that says I can only use 'disabled' or 'normal'.
Question 2: So how do you hide the popup until you want to use it, if you create the pop up at the start of the program versus waiting until the pop up key combo is pushed?
I have tried sizing the pop up to 0x0 but I still see single pixel on the screen until I hit the key combo.
I have tried waiting until key combo is hit to bring up the pop up and that works fine until I get ready to change to the second image.
On effbot.org I saw and have tried several different combinations to try to 'disable' without destroying(which I don't want to do) the canvas underneath when the pop up comes up. The trouble I have is when I go and push an arrow key the underneath canvas still has the focus and it moves the map instead of change the image on the pop up. I have tried several of the effbot combinations...
self.canvas.config(state='disabled')
self.canvaspopup = Canvas(self, width=800, height=614)
self.canvaspopup.pack_propagate(0)
self.canvaspopup.place(x=284,y=52)
self.png = Label(self.canvaspopup)
self.png.pack()
self.canvaspopup.focus_set()
I have also tried
self.canvas.bind('<FocusOut>')
self.canvaspopup.bind('<FocusIn>')
And still no luck, the underneath canvas still has the focus and I'm still moving the map instead of advancing the image in the pop up. I am guessing given it was on the Events and Bindings page on effbot.org that I saw FocusIn/Out being talked about that I should put that in the .bind statement and not in the .config.
Question 3: How do I get the pop up to take the focus, pretty much should only need keyboard focus and no mouse focus?
I know I want to keep the pop up handy as I want to be able to click on the underlying map in different locations and have the program go to the internet and pull up data for those locations so the pop up is something that will be used several times throughout any one run of the program. I know from what I've seen I can use
self.canvaspopup.destroy()
But this destroys the canvas so I would have to recreate it again. So if I put the pop up creation at the beginning of the program...I'm screwed and can't recreate it. Which leads right back to Question 2.
Definitely a mess. I have most everything working fine, its just the interaction, and knowing the proper way of handling this kind of situation that has me stumped.
Since you are using place, you can use place_forget to hide the popup. For the focus, you use focus_set.
Here's an example:
import tkinter as tk
class PopupCanvas(tk.Canvas):
def __init__(self, parent, *args, **kwargs):
tk.Canvas.__init__(self, parent, *args, **kwargs)
self.parent = parent
self.text_item=self.create_text(10, 10, anchor="nw")
self.bind("<Left>", self.handle_left)
self.bind("<Right>", self.handle_right)
self.bind("<Escape>", self.hide)
def handle_left(self, event=None):
self.itemconfigure(self.text_item, text="You clicked left")
def handle_right(self, event=None):
self.itemconfigure(self.text_item, text="You clicked right")
def show(self, event=None):
self.place(relx=.5, rely=.5, anchor="center")
self.focus_set()
def hide(self, event=None):
self.place_forget()
self.parent.focus_set()
root = tk.Tk()
label = tk.Label(root, text="Press 'p' to pop up a canvas, <escape> to hide it\n" +
"Press left and right arrows when the popup is visible")
canvas = tk.Canvas(root, width=400, height=400)
popup = PopupCanvas(canvas, width=200, height=200, background="pink")
label.pack(side="top", fill="x")
canvas.pack(side="top", fill="both", expand=True)
canvas.focus_set()
canvas.bind("<p>", popup.show)
root.mainloop()
I want my window to be invisible most of the time, but get to top of
the screen on hotkey and hide again if the user switches to another
application.
In my hotkey handler I use
self.Show()
self.Raise()
self.Iconize(False)
and in my activate message handler
self.Hide()
self.Iconize(True)
but the window pops up on top of the screen, but remains deactivated:
it's title bar colour is a inactive one, and it flashes in the taskbar
as a window requiring my attention and it doesn't get EVT_ACTIVATE. I
tried to add self.SetFocus, but no effect.
And if I use
self.Show()
self.SetFocus()
in hotkey handler and in my activate message handler
self.Hide()
and it works okay if I deactivate my window by clicking to another
window, but if I press Alt-Tab and then invoke my window with a hotkey
it doesn't appear on top of the screen but just flashes in the
taskbar. Also I made an ability to hide it by pressing a button on it,
and if I hide it this way, it also doesn't show correctly afterwards
as in the case with Alt-Tab
you have to use a window manager to activate windows. I'm using wmctrl for that purpose (cannot find the same func. through kwin's dbus for kde).