Tkinter partially click through-able? (Windows only) - python

I am writing an application that hovers a ruler over all other on-screen content. I have made the tkinter window and associated canvas transparent using:
root.overrideredirect(True) #This hides the window outline/controls
root.state('zoomed') #This scales the window to fill the page
root.configure(background=bgColor) #Set bg color of window (used to make transparent \/)
root.wm_attributes("-transparentcolor", bgColor) #Necessary for transparent, window
root.lift()#Lifting window above all others
root.wm_attributes("-topmost", True)#Hold window on top of all other windows
I am able to click through this application where transparent before compiling with pyinstaller to an exe. However after compiling to an exe this is no longer possible.
I attempted the solution shared here: Tkinter see through window not affected by mouse clicks
However this makes the entire window click through-able, meaning that I can no longer interact with the non-transparent portions of the top window (which I have to be able to do).
hwnd = win32gui.FindWindow(None, "Digital Ruler") # Getting window handle
# hwnd = root.winfo_id() getting hwnd with Tkinter windows
# hwnd = root.GetHandle() getting hwnd with wx windows
lExStyle = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
lExStyle |= win32con.WS_EX_TRANSPARENT | win32con.WS_EX_LAYERED
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE , lExStyle )
I need to be able to move/interact with any colored sections of the root window but need to be able to click through any transparent sections... So far I have only been able to completely seize the mouse or completely miss it.

I also have met this problem...
after a lot try, I found that if distribute the exe file with the manifest file which also generated by pyinstaller, the click through feature will work as expected.

Related

Python/Tkinter: erratic behaviour using root.overridedirect(True)

The following code disables the tkinter title bar, creates a replacement title bar, and enables the user to re-position the app on the screen by selecting and holding the replacement title bar and moving the mouse.
import tkinter as tk
root = tk.Tk()
root.geometry("1275x675+50+70")
root.overrideredirect(True) # remove tkinter title bar
def movewindow(event): # event bound to new title bar
root.geometry(f'+{event.x_root}+{event.y_root}')
titlebar = tk.Frame(root,borderwidth = 0, bg="lightblue",
width=1275,height=30)
titlebar.place(x=0,y=0)
titlebar.bind("<B1-Motion>",movewindow)
root.mainloop()
The code works perfectly in my main monitor. But if I move the app to my second monitor, it will disappear. Strangely, if I click anywhere on the second monitor it will re-appear, and after that, the app can be moved seamlessly across both monitors.
I should note that, when I click on the titlebar and begin to move the app, the cursor jumps to the left, so that I'm moving the app with the mouse pointer at the left hand corner of the title bar. The trouble begins the moment the mouse pointer leaves the main monitor.
If I initialize the root geometry on startup to +1600 instead of +50, the app will launch in the second monitor. And it can then be moved seamlessly between both monitors. Unfortunately, I want the app to launch in the main monitor, so that is not a workable fix.
Is there any fix that could be applied here?

How to pop-up minimized program at Taskbar python

What I want to pop-up is minimized at taskbar.
But when I run below code, not minimized program pop-up, one more program run, and it cannot be clicked or seen and simply exists in the taskbar.
import win32gui, win32con
hwnd = win32gui.FindWindow(None, "League of Legends")
win32gui.SetForegroundWindow(hwnd)
win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
What I expected : minimized program pop-up
Firstly make sure that you are locating the right window using this Finder tool. If you do not have Visual Studio, you can also download Winspector
Next, what you can try is to swap the arguments, for e.g
hwnd = win32gui.FindWindow("League of Legends", None)
Arguments for .FindWindow is className followed by windowName which can be found here
Moreover, you can set specific flags for your window to show.
For example if the initial state is minimized, you can show it by using the SW_SHOWNORMAL flag. Usage is as such,
win32gui.ShowWindow(hwnd, win32con.SW_SHOWNORMAL)
(SW_SHOW) Activates the window and displays it in its current size and position.
(SW_SHOWNORMAL) Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.

How can I deactivate mouse motion (<Motion-1>) on windows taskbar while I am dragging my frameless window?

I am working on a Frameless window for modern GUI with Tkinter. I have implemented a drag window feature but It is also working when window is behind of the taskbar, it is a big problem when I am trying to recover my window from behind of taskbar. So I want to disable the drag feature when the mouse reaches on taskbar's border.
def drag(event):
act = str(event.type)
if act == 'Motion':
global _app
#_app is a reference to root in other py file
t = _app.geometry().split('+')[1:]
xval = int(t[0])
yval = int(t[1])
_app.geometry('+'+
str(xval + event.x -400)+
'+'+str(yval + event.y -20))
#window size is fixed i.e. 800x480
When you makes a window border-less using overrideredirect() method, then this method says to operating system's windows manager to just ignore your tkinter's GUI window.
When you do this then the windows manager now takes no any responsibility for your GUI window. Each and every task like window dragging, minimization and maximization, closing event etc should be handled by you manually.
Now to solve you dragging problem on windows taskbar there are two ways.
1) As I told you before that do everything manually, then you should to locate your windows taskbar manually and then modify your drag function to prevent your mouse motion after the borders of your taskbar.
2) The simplest way is to make your GUI window a top level window by which you will able to drag your window onto the taskbar without any window hiding problem.
To make the window top level you should just set an Attribute i.e. topmost = True.
root.attributes('-topmost',1)

Change app icon while using tkinter (Python 3.6 MacOS)

Here is a little window I made practising tkinter and I know how to change the icon next to the title as I did in code, but I would like some help changing the app icon in my MacOS dock because right now it is the python launcher icon. If anyone could help me that would be great. Also, I know there is nothing in the windows but I don't need that at the moment.
#Import the tkinter module
import tkinter
#Create a window
window = tkinter.Tk()
#Title the window
window.title("Welcome to ECS, we are excited to have you in class")
#Change the window size
window.geometry("400x100")
#Icon next to the title
window.wm_iconbitmap('33mm33.icns')
#Here is where I would like to be able to change the application icon
#Draw the windows and start the application
window.mainloop()

Tkinter window with both title bar and windows taskbar

I have searched wide and far for this question, but noone seems to know. I create a simple tkinter window (tcl 8.5) in python 2.7 and want it maximized, just as if I would hit the maximize button in top right corner. Using the -fullscreen option is not an option since it removes the title bar.
I tried the following:
import Tkinter
root = Tkinter.Tk()
root.overrideredirect(True)
# Set window to be size of screen
root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(), root.winfo_screenheight()))
The problem is that the window is now below the Windows taskbar and some of my elements are therefore not shown. An easy hack would be to set height to screenheight-some_constant, or calculate some_constant based on data from the operating system. However, this seems like an extremely ugly hack.
Is there any way to maximize a window in tkinter in a clean way where the window is above the (Windows) taskbar and still has a title bar?
i know this is an old question but i have tested the following code on an XP system (32bit) with python 2.7.6, using TCL version 8.5 and tk version 8.5.
code:
import Tkinter as tk
root = tk.Tk()
root.state("zoomed")
root.mainloop()
this does start the window maximised on the primary monitor.
it does have pitfalls - i have been unable to make it maximise on another monitor, but does work reliably without covering the title bar or taskbar.
and as you want to keep the title bar i would leave out the overrideredirect.

Categories