I am trying to make a python application that requires disabling the window resize and fullscreen mode on a Mac. I used root.resizable(False,False) to do the work, it does stop the window from resizing. But for disabling the fullscreen mode, only if you iconify it first and then deiconify it. I wonder why and is there a workaround?
According to the tk documentation, this is probably a bug in the window manager. Keep in mind that resizable is a wm command.
Most existing window managers appear to have bugs that affect the operation of the wm command. For example, some changes will not take effect if the window is already active: the window will have to be withdrawn and de-iconified in order to make the change happen.
Related
I'm having a problem with changing the background of this part of the window:
How do I change it?
As I see you are using windows.
This color is set by the theme you are currently using. It is the same for every window.
So I cross out the possibility of only using the Tkinter module for this.
Tkinter is responsible for what is in the window but the window manager decides about the border. For example in Ubuntu the window would look totally different.
I guess, you would need some windows specific calls for that.
You can remove the border with root.overrideredirect(1) if I remember correctly.
PS: put "windows" into the tags of this question.
I'm currently working with Tkinter and Python 2.7 on Linux and I was wondering if there was a way to remove the TK() window border frame and title bar without using overrideredirect(1).
I have my own close button and overrideredirect(1) presents me with a few issues that I can't accept:
GUI always on top
can't iconify then deiconify properly
no keyboard input so can't type into fields (see python tkinter overrideredirect; cannot receive keystrokes (Linux))
I can't use attributes("-fullscreen", True) as the titlebar and borders remain.
The window decoration is all handled by the window manager so what you are trying to do is find a way to tell the window manager to decorate your window differently from a standard application window. Tk provides overrideredirect to have the window manager completely ignore this window but we can also use Extended Window Manager Hints to declare the intended use of this toplevel window to the window manager. This is done for instance for tooltip and splashscreen windows to allow the manager to provide minimal decoration and possibly special animations.
In your case, adding a 'splash' hint should do what you want
root = tk.Tk()
root.wm_attributes('-type', 'splash')
You will need Tk 8.5 or above for this.
You must give your root window name before your command.
Like this:
from tkinter import *
root=Tk()
root.wm_attributes('-fullscreen','true')
root.mainloop()
I'm building a console app, and would like to capture keystrokes in real time. The following code works perfectly until another window gets focus. From that point on, I'm not able to get back to a state where I can capture keystrokes and other events again with only the console visible.
import tkinter as tk
app = tk.Tk()
def handleKeypress(event):
key = event.char
if(key == 'q'):
app.destroy()
else:
print(key)
app.bind_all('<Key>', handleKeypress)
app.withdraw()
app.mainloop()
I've tried using various methods (grab and focus) to redirect the focus to my app. The best I was able to do was to get the Tkinter window visible and in focus with deiconify(), but I was not able to hide it again to make it as though the console is the only window.
Adding the following results in the Tkinter window appearing and disappearing repeatedly:
def lostFocus(event):
app.deiconify()
app.focus_force()
app.withdraw()
app.bind_all('<FocusOut>', lostFocus)
How can I go back to the state the application was in right after launch? Or even better, how can I force it to get all events without having to make the Tkinter window visible and in focus?
You can't do what you want. Tkinter is designed -- as are most GUI toolkits -- to only process events when it has the focus. That's the whole point of focus: for the OS to know where to send events.
The fact that it works initially is probably a bug in tkinter. Though, perhaps it can be explained by the fact that the window initially has focus, and when you withdraw the window the OS doesn't move the focus
The only way to restore focus is to make the window visible.
My python application launches a subprocess that creates a pyglet window. When the pyglet window opens, it is in front of all other windows, and takes keyboard focus. I'd like my pyglet window to open in the background, and not take focus. Is this possible?
Stripped-down version of the code I'm using:
import pyglet
pyglet.window.Window()
pyglet.app.run()
I'm using Windows 7, in case that makes a difference..
Reversing focus is OS specific:
pyglet does not provide OS specific window control. So most likely you will have to use an ad-hoc trick for quick&dirty solutions or try to approach it with extensions like pywin32 using Windows API and/or COM to list through the stack of taskbar applications to reverse stealing of focus. You can also try to create your own window (container - which you can manipulate) first - in order to delegate its context to pyglet.
Delaying stealing of focus
On the other hand if according to your program logic you just want to delay actual showing of you application you can play with visibility:
import pyglet
w = pyglet.window.Window()
w.set_visible(False)
pyglet.app.run()
So if you don't want to play with delegation of window context, you can probably do the following:
start your application w/o showing the window
find the focus of the current active window by getting its handle/id
show your window
give back the focus to the previous window
The above assumes working with windows API. I think MSDN had examples on focus changing.. If you know PID of your current window (main application) this should simplify the step 2.
I am thinking this might be more of a windows / window manager issue than your app - will something like this http://pcsupport.about.com/od/windowsxp/ht/stealingfocus02.htm help ??
I am writing a wxPython application that remains open after closing all of its windows - so you can still drag & drop new files onto the OSX dock icon (I do this with myApp.SetExitOnFrameDelete(False)).
Unfortunately if I close all the windows, the OSX menubar will only contain a "Help" menu. I would like to add at least a File/Open menu item, or just keep the menubar of the main window. Is this somehow possible in wxPython?
In fact, I would be happy with a non-wxPython hack as well (for example, setting the menu in pyobjc, but running the rest of the GUI in wxPython). wxPython development in OSX is such a hack anyway ;)
UPDATE: I managed to solve this problem using the tip from Lyndsey Ferguson. Here's what I have done:
On startup I create a window which I show and hide immediately. I set its position to (-10000,-10000) so that it does not flicker on the screen (aargh, what a dirty hack!)
I create an empty EVT_CLOSE event handler in that window so that it cannot be closed.
It seems that destroying a window resets the OSX menu, but hiding does not... So when the last window is closed, I need to show and hide this window again (hiding is necessary so that the user cannot switch to this window using the Window menu or Cmd-`)
Yeah, this is really ugly... I will be very grateful if someone comes up with a prettier solution.
UPDATE 2: Actually it can be solved in a much easier way: if we do not close the last window, only hide it. And ensure that it does not respond to menu events anymore.
Nowadays you can use wx.MenuBar.MacSetCommonMenuBar() to set the menu bar (which you have to create) that should be used when no windows are open.
If you just want a default macOS menu bar to be used (with the application and Window menus already there), this appears to be the minimal code:
menubar = wx.MenuBar()
wx.MenuBar.MacSetCommonMenuBar(menubar)
This will let your app respond to Command+Q out-of-the-box, too.
The wx.MenuItem IDs wx.ID_ABOUT and wx.ID_EXIT are special as menu items with those IDs are moved to the macOS Application menu. The docs actually refer to the application menu as the "Apple" menu (e.g. the menu described in the wx.MenuBar.OSXGetAppleMenu() function's docs is the application menu), possibly for historical reasons.
Can you create a hidden window that is offscreen somewhere? It is a hack, but I remember having to do a lot of hacks to make my wxPython-based application work correctly on Mac OS X.
Note:You'll have to disable the close button and set up that hidden window so that it doesn't show up in the Window menu.
Aside:Have you considered factoring out your GUI portion of your Python application and using PyObjC on Mac OS X? You'll get more native behaviours...