Tkinter application topmost, even over fullscreen - python

I'm using tkinter on Ubuntu.
I'd like my application to be on top of the screen, all the time. I'm aware of, and am currently using, wm_attributes("-topmost", 1). I've discovered that this is equal to right clicking on the menu bar of an application and selecting 'Always On Top', which works fine for most applications. However, this doesn't work when full-screen applications are launched (specifically, TF2). In such cases, my widget lies behind the game.
I'm also aware of overrideredirect(True), and this stays on top of the game even over full-screen, but this is not viable as the menu bar and being able to move the window are central to my application.
Is there a way to have tkinter remain on top of every application, including those that are full-screen? Basically the functionality of overrideredirect, but keeping the menu bar and the ability to move the window.

Related

Python/Tkinter - How Would I Make a Window More "Important" Than Other Application Windows

I'd like to know how I can have my window as a priority over other application windows.
For instance, even if my window was on top of an existing application window, and I happened to click on the existing application window, I don't want my window to hide behind the existing window, I want it to stay visible (in the foreground) at all times. Is this possible?
(Using overrideredirect, by the way)
For windows you can use topmost
root.wm_attributes("-topmost", 1)

PyGTK Window always on top of all 'always on top` windows

I created a PyGTK application which needs to be always on top. The transparent window redirects mouse clicks to the window below and therefore gets out of focus once you click into an underlaying window. This is the intended behaviour. In fact it should just show a little image that's always above everything.
This works well unless you use something like the libreoffice fullscreen presentation. The presentation window is marked as always on top as well and hence my window goes into the background. Even if I take it to front using Alt+Tab and then click onto the underlaying libreoffice slide (which is neccessary) my window goes into the background again.
This is a really specific question and the solution should work on both Linux and Windows. I have no idea what I should do. I just found many questions on how to have a windows always on top but none of them covering my problem.
Long story short: How can I put my window always on top of every window that is always on top as well?
Simple Answer: You can use 'Always on Top' in windows with by using AutoHotKey scripts.
Follow these steps:
Install AutoHotKey
Create a new AHK scripts following the images
Add this code ^SPACE:: Winset, Alwaysontop, , A
Next, double-click your script to run it. You’ll know it’s running
because a green “H” logo appears in your system tray to let you know
it’s running as a background process.
Now press Ctrl+Space to set any currently active window to be always
on top. Press Ctrl+Space again set the window to no longer be always
on top.

The proper way to display multiple windows in tkinter?

I am currently working on a project using Python and tkinter.
The problem is that I don't know what's the proper way to display multiple windows, or screens, I don't know how to call them. Let me explain better.
When the application starts the login screen appears. After that, if I click register, I want to go to the register screen, but I don't want it to be a separate window (I don't want to have 2 windows displayed at the same time), but rather another window with different content ?!
How should I handle properly this situation? Create a second window using Toplevel and hiding the first (can I do that?) or changing the widgets of the first?
Code I've written so far
You can do that- just call window.withdraw() on the Toplevel you need to hide after creating a new Toplevel. Changing the widgets in the first is also an option- if you like, you could always try a Notebook widget and disable manual flipping or just put each "screen" in a frame and grid_ or pack_forget them to remove them from the window.

How to change the OSX menubar in wxPython without any opened window?

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

Can you auto hide frames/dialogs using wxPython?

I would like to create an application that has 3-4 frames (or windows) where each frame is attached/positioned to a side of the screen (like a task bar). When a frame is inactive I would like it to auto hide (just like the Windows task bar does; or the dock in OSX). When I move my mouse pointer to the position on the edge of the screen where the frame is hidden, I would like it to come back into focus.
The application is written in Python (using wxPython for the basic GUI aspects). Does anyone know how to do this in Python? I'm guessing it's probably OS dependent? If so, I'd like to focus on Windows first.
I don't do GUI programming very often so my apologies if this makes no sense at all.
As far as I know, there's nothing built in for this.
When the window is hidden, do you want it completely invisible or can a border of a few pixels be showing? That would be an easy way to get a mouse hover event. Otherwise you might have to use something like pyHook to get system-wide mouse events to know when to expand your window.
The events EVT_ENTER_WINDOW and EVT_LEAVE_WINDOW might also be useful here to know when the user has entered/left the window so you can expand/collapse it.
Expanding/collapsing can just be done by showing/hiding windows or resizing them. Standard window functions, nothing fancy.
By the way, you might want to use wx.ClientDisplayRect to figure out where to position your window. That will give you a rectangle of the desktop that does NOT include the task bar or any other toolbars the user has, assuming you want to avoid overlapping with those things.
Personally, I would combine the EVT_ENTER_WINDOW and EVT_LEAVE_WINDOW that FogleBird mentioned with a wx.Timer. Then whenever it the frame or dialog is inactive for x seconds, you would just call its Hide() method.
I think you could easily just make a window that is the same size as the desktop then do some while looping for an inactivity variable based on mouse position, then thread off a timer for loop for the 4 inactivity variables. I'd personally design it so that when they reach 0 from 15, they change size and position to become tabular and create a button on them to reactivate. lots of technical work on this one, but easily done if you figure it out

Categories