Python, tkinter How to allow clicks through app? - python

I am new to coding and python. I use tkinter to make an app and want to know how to allow your clicks to affect the apps and stuff behind my app without interacting with my app. My app is designed to turn the screen pink by adding a transparent overlay. I want to make the overlay visible but not affecting the other apps or pc.(https://i.stack.imgur.com/UW4tR.png)](https://i.stack.imgur.com/UW4tR.png)
I have tried looking at other posts and found solutions but none worked quite right. This is my current code. How it is expected to work is the overlay is there but you can interact with everything behind it as if the app was not there.
import tkinter as tk
from tkinter import *
import time
from tkinter import ttk
from tkinter import messagebox
win = tk.Tk()
win.title("Pink-Out")
win.geometry("1900x1000")
win.attributes('-alpha',1)
win.configure(bg='black')
sec = StringVar()
Entry(win, textvariable=sec, width = 2, font = 'Helvetica 14').place(x=1720, y=900)
sec.set('00')
mins= StringVar()
Entry(win, textvariable = mins, width =2, font = 'Helvetica 14').place(x=1680, y=900)
mins.set('00')
hrs= StringVar()
Entry(win, textvariable = hrs, width =2, font = 'Helvetica 14').place(x=1640, y=900)
hrs.set('00')
def pink():
command = win.configure(bg='#FF007F')
command = win.attributes('-fullscreen', True)
command = win.attributes('-alpha', 0.10, '-topmost', 1)
messagebox.showinfo("", "Remeber to look away from your screen every 20 min to protect your eyes.")
# hide the button
for i in range(1,100):
times = int(hrs.get())*3600+ int(mins.get())*60 + int(sec.get())
while times > -1:
minute,second = (times // 60 , times % 60)
hour =0
if minute > 60:
hour , minute = (minute // 60 , minute % 60)
sec.set(second)
mins.set(minute)
hrs.set(hour)
#Update the time
win.update()
time.sleep(1)
if(times == 0):
sec.set('00')
mins.set('20')
hrs.set('00')
messagebox.showinfo("", "Take a break")
times -= 1
b1 = tk.Button(win, text='START', bd ='2', bg = 'IndianRed1',font =('Helvetica bold',10), command = pink).place(x=2667, y=925)
win.bind('<Return>', lambda event:pink())
win.mainloop()

This is not an answer. I will delete it sooner.
Your Entry and Button is out of window. I am not going to try this.
In Line 8, I changed window size.
win.geometry("640x480")
In line 13,. Change this: Entry(win, textvariable=sec, width = 2, font = In line 13, 'Helvetica 14').place(x=20, y=90)
In line 16. Change this: Entry(win, textvariable = mins, width =2, font = 'Helvetica 14').place(x=50, y=90)
In line 19. Change this: Entry(win, textvariable = hrs, width =2, font = 'Helvetica 14').place(x=80, y=90)
In Line 50. Change this: b1 = tk.Button(win, text='START', bd ='2', bg = 'IndianRed1',font =('Helvetica bold',10), command = pink).place(x=26, y=25)
Result:

Related

How do I fix "name is not defined error" (tkinter)

I'm trying to make a stopwatch app with Tkinter, but now I have some trouble. Somewhy, I'm receiving the following error:
name 'label13' is not defined. line 177, in countdown
label13.config(text = count)
I have no idea why this error message pops up. I really appreciate it if you can help me.
Here is my code:
from tkinter import Tk, Canvas, Entry, Text, Button, PhotoImage
from tkinter import *
window = Tk()
window.geometry("703x981")
window.configure(bg = "#FFFFFF")
def countdown(count):
#change text in label
label13.config(text = count)
if count > 0:
#call countdown again after 1000ms (1s)
window.after(1000, countdown, count-1)
countdown(120)
label13 = Label(window, font = "Courier 40 bold", bg="white", fg="black")
label13.place(x =29, y=300)
window.resizable(False, False)
window.mainloop()
Because label13 should defined before calling countdown(120) as shown below.
from tkinter import Tk, Canvas, Entry, Text, Button, PhotoImage
from tkinter import *
window = Tk()
window.geometry("703x981")
window.configure(bg = "#FFFFFF")
window.resizable(False, False)
label13 = Label(window, font = "Courier 40 bold", bg="white", fg="black")
label13.place(x =29, y=300)
def countdown(count):
#change text in label
label13.config(text = count)
if count > 0:
#call countdown again after 1000ms (1s)
window.after(1000, countdown, count-1)
countdown(120)
window.mainloop()

Display every keyboard character pressed Python tkinter

When I watched ecnerwala videos on competitive programming, I found something interesting in his video.
This running text
ecnerwala running text
Here is the link of the video
https://www.youtube.com/watch?v=ExmrrXi04vI&t=1030s
So I tried to create something like that running text using tkinter.text widget in python.
I create a window, add text object to it, and bind all keyboard keys to the window. I insert those keys into the text object when any key is pressed. I also make sure that even if I press the enter button, I don't insert it as a newline to the text widget but as the word 'Return' instead
Of course, there is a possibility that the length of all characters I insert into the text is longer than the length of the text widget could fit in one sentence. That's why I want to make the text widget to "always" see the characters from index END-(the number of character the widget could fit) until END
Here is my code
from tkinter import *
def handle(event):
text.config(state = NORMAL)
text.insert(END, event.keysym)
text.config(state = DISABLED)
# Things to be fix
text.doSomethingToMakeItBehaveLikeEntryWidget()
window = Tk()
window.geometry('500x500')
text = Text(window, font = ('Arial', 20), height = 1)
entry = Entry(window, font = ('Arial', 20))
text.config(state = DISABLED)
text.pack()
entry.pack()
window.bind('<Key>', handle)
window.mainloop()
Is there any solution for this problem? Even if I have to use another widget instead of text widget to solve it? Thanks for the help
Given that you use only one line in the text widget, you can use an entry in read-only mode instead.
No matter whether you use an entry or a text widget, you can use the method text.xview_moveto(<fraction>) to set which part of the content is visible, <fraction> being the relative portion of the widget's content which is hidden on the left. If you set this fraction to 1, it will ensure that the last character is visible.
from tkinter import *
def handle(event):
text.config(state=NORMAL)
text.insert(END, event.keysym)
text.config(state="readonly")
text.xview_moveto(1)
window = Tk()
window.geometry('500x500')
text = Entry(window, font = ('Arial', 20), state="readonly", readonlybackground="white")
entry = Entry(window, font = ('Arial', 20))
text.config(state = DISABLED)
text.pack()
entry.pack()
window.bind('<Key>', handle)
window.mainloop()
Try this.
from tkinter import *
from tkinter.scrolledtext import ScrolledText
def handle(event):
text.config(state = NORMAL)
text.insert(END, event.keysym)
text.config(state = DISABLED)
t = text.get('1.0','end-1c')
length= len(t)
width =text.winfo_width()
max_char = int((35/500)*width)
if max_char < length:
a = length-max_char
text.config(state = NORMAL)
text.delete(1.0,END)
text.insert(1.0,t[a:])
text.config(state = DISABLED)
window = Tk()
window.geometry('500x500')
text = Text(window, font = ('Arial', 20), height = 1)
entry = Entry(window, font = ('Arial', 20))
text.config(state = DISABLED)
text.pack()
entry.pack()
window.bind('<Key>', handle)
window.mainloop()

How to make a Tkinter window not resizable?

I need a Python script that uses the Tkinter module to create a static (not resizable) window.
I have a pretty simple Tkinter script but I don't want it to be resizable. How do I prevent a Tkinter window from being resizable? I honestly don't know what to do.
This is my script:
from tkinter import *
import ctypes, os
def callback():
active.set(False)
quitButton.destroy()
JustGo = Button(root, text=" Keep Going!", command= lambda: KeepGoing())
JustGo.pack()
JustGo.place(x=150, y=110)
#root.destroy() # Uncomment this to close the window
def sleep():
if not active.get(): return
root.after(1000, sleep)
timeLeft.set(timeLeft.get()-1)
timeOutLabel['text'] = "Time Left: " + str(timeLeft.get()) #Update the label
if timeLeft.get() == 0: #sleep if timeLeft = 0
os.system("Powercfg -H OFF")
os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")
def KeepGoing():
active.set(True)
sleep()
quitButton1 = Button(root, text="do not sleep!", command=callback)
quitButton1.pack()
quitButton1.place(x=150, y=110)
root = Tk()
root.geometry("400x268")
root.title("Alert")
root.configure(background='light blue')
timeLeft = IntVar()
timeLeft.set(10) # Time in seconds until shutdown
active = BooleanVar()
active.set(True) # Something to show us that countdown is still going.
label = Label(root, text="ALERT this device will go to sleep soon!", fg="red")
label.config(font=("Courier", 12))
label.configure(background='light blue')
label.pack()
timeOutLabel = Label(root, text = 'Time left: ' + str(timeLeft.get()), background='light blue') # Label to show how much time we have left.
timeOutLabel.pack()
quitButton = Button(root, text="do not sleep!", command=callback)
quitButton.pack()
quitButton.place(x=150, y=110)
root.after(0, sleep)
root.mainloop()
The resizable method on the root window takes two boolean parameters to describe whether the window is resizable in the X and Y direction. To make it completely fixed in size, set both parameters to False:
root.resizable(False, False)

How do I update this Text Box's text in Tkinter?

So I am making a stopwatch in python with tkinter, I have the loop for updating the time working, but I have it so the loop clears the text box, and then updates the text box with the new number.
Although it doesnt work, for some reason it just doesnt clear it, it just keeps adding numbers to the box.
Here is the code that I have used, if someone would be able to have a look at this for me I would appriciate it a lot :)
import time
from tkinter import *
root = Tk()
root.title("StopWatch")
#textbox for the screen
screen = Text(root, height = 1, width = 20, bd=10)
screen.grid(row=0, column=0)
#Active variable
global stopwatch_active
stopwatch_active = False
stop_time = 0
stop_minutes = 0
#command for starting the stopwatch
def start_com():
stop_btn.config(state=NORMAL)
stopwatch_active = True
start_btn.config(state=DISABLED)
global stop_time
stop_time += 1
screen.insert(END, stop_time)
root.after(1000, start_com)
#button for starting the stopwatch
start_btn = Button(root, text = "Start", width = 10, bd = 5, command = start_com)
start_btn.grid(row=1, column=0, sticky=W)
#button for stopping the stopwatch
stop_btn = Button(root, text = "Stop", width = 10, bd = 5)
stop_btn.grid(row=1, column=0, sticky=E)
stop_btn.config(state=DISABLED)
Add:
screen.delete("1.0", END)
Before you do:
screen.insert(END, stop_time)
This will clear all the text from the text box. Effbot has more information if your interested. This will produce something similar to:

Python tkinter grid layout problems

I'm creating a very simple UI using Tkinter and python, but I'm having trouble sizing GUI elements and using the grid format to place them correctly. Here's a first-order approximation of what I'm trying to have:
Here's the code I have so far. I keep getting close, but I don't think I really understand what I'm doing. Any help is much appreciated!
#User interface
root = Tk()
window_width = root.winfo_screenwidth()
window_height = root.winfo_screenheight()
root.geometry ("%dx%d"%(window_width,window_height))
menu_bar = Menu(root)
menu = Menu(menu_bar, tearoff=0)
menu.add_command(label="Open", command = open_file)
menu.add_command(label="Save", command = save)
menu.add_separator()
menu.add_command(label="Quit", command = exit)
menu_bar.add_cascade(label="File",menu=menu)
root.config(menu=menu_bar)
#textbox is the window in which the code is written
textbox = Text(root, width=50, height = window_height/20+4)
#canvas is where the car will go
canvas_frame= Frame(root, width = window_width/1.5, height = window_height-200)
canvas_frame.configure(borderwidth=1.5,background='black')
canvas = Canvas(canvas_frame, width = window_width/1.5, height = window_height-200)
#console to print to
console = Text(root, width = int(window_width/1.5), height = 10)
run_button = Button(root, text = "Run", command = lambda:generate_program(textbox.get(1.0,END)))
clear_button = Button(root, text = "Clear text", command = clear)
#add them to frame
textbox.grid(row=0, column=0, rowspan=20, columnspan=10)
run_button.grid(row=21,column=0)
clear_button.grid(row=21,column=1)
canvas_frame.grid(row=0,rowspan=10,column=21,columnspan=25)
canvas.grid(row=0, rowspan=1, column=21, columnspan=25)
console.grid(row = 1, rowspan=1, column = 21, columnspan=25)
root.mainloop()
In my opinion, this is layout can be much easier with the pack geometry manager. One of the problems is that you are trying to make the width and the height of each widget fit in its place with rowspan and columspan options. Also, since canvasis inside a frame, you have to think that it is like inside a new window, so a simple call to canvas.grid() would be enough.
However, with pack() you just have to put textbox, run_button and clear_button inside a new frame:
left_frame = Frame(root)
textbox = Text(left_frame, ...)
run_button = Button(left_frame, ...)
clear_button = Button(left_frame, ...)
canvas_frame= Frame(root, ...)
canvas_frame.configure(borderwidth=1.5,background='black')
canvas = Canvas(canvas_frame, ...)
console = Text(root, ...)
left_frame.pack(side=LEFT)
textbox.pack()
run_button.pack(side=LEFT)
clear_button.pack()
canvas_frame.pack()
canvas.pack()
console.pack()

Categories

Resources