<Command-a> for Text - Tkinter - python

I found the below code :
def callback(ev):
ev.widget.select_range(0, 'end')
root = Tk()
t = Text(root, height=10, width=40)
t.pack()
t.bind('<Command-a>', callback) //WORKS for ENTRY
root.mainloop()
I'm basically trying to make cmd + a or Ctrl + a (Windows) work for Text in Tkinter.
Error (When I give the command : cmd-a in text):
'Text' object has no attribute 'select_range'

The code is ok except that you are inventing methods on the Text widget. However, if you look at the bindings on the widget class (Text) there are some virtual events defined
>>> '<<SelectAll>>' in root.bind_class('Text')
True
So in your handler for the keyboard event, use event_generate to raise a SelectAll virtual event.
import tkinter as tk
def select_all(ev):
ev.widget.event_generate('<<SelectAll>>')
root = tk.Tk()
txt = tk.Text(root)
txt.pack()
txt.bind('<Control-A>', select_all)

Text class does not have select_range() function, that is why you got that error message. But you can use bind_class() to bind events to the Text class widgets. Here is a dirty demo:
import tkinter as tk
def simulate_contral_a(e):
e.widget.tag_add("sel","1.0","end")
root = tk.Tk()
root.bind_class("Text","<Control-a>", simulate_contral_a)
T = tk.Text(root, height=2, width=30)
T.pack()
T.insert(tk.END, "Press Ctrl+a\nto select me\n")
root.mainloop()
Run this MCVE above and press Ctrl + a to see its effect:

Related

Why does tkinter creating two windows here? And how can i stop it?

import tkinter as tk
from subprocess import check_call
def copy_name():
cmd = 'echo ' + name.strip() + '|clip'
return check_call(cmd, shell=True)
root = tk.Toplevel(background="black")
root.title("Copying")
root.resizable(False, False)
T = tk.Label(root, text=name, height=2, width=len(name) + 25, background="black", foreground="white")
T.pack()
button = tk.Button(root, text="Copy", command=copy_name, background="black", foreground="white")
button.pack()
tk.mainloop()
This is my code.
I just wanted to test this way of copying text...
About my expectations... i want to understand from where those windows are appearing, and how to stop it.
Im just a newbie in Python and Tkinter... so please, tell me what i did wrong
You are not using Toplevel(). You just wanted single window. Just replaced Toplevel to tk()
Code:
import tkinter as tk
from subprocess import check_call
def copy_name():
cmd = 'echo ' + name.strip() + '|clip'
return check_call(cmd, shell=True)
root = tk.Tk()
root.title("Copying")
root.resizable(False, False)
T = tk.Label(root, text='name', height=2, width=25, background="black", foreground="white")
T.pack()
button = tk.Button(root, text="Copy", command=copy_name, background="black", foreground="white")
button.pack()
tk.mainloop()
Screenshot:
Every tkinter window requires a root window - an instance of Tk. If you don't create one, one will be created automatically. When you do root = tk.Toplevel(background="black"), tkinter will first create an instance of Tk and then it will create your Toplevel, resulting in two windows.
The solution in this case is to call Tk instead of Toplevel. Also, you'll need to remove the background="black" argument and instead configure the background in a separate step.
root = tk.Tk()
root.configure(background="black")
As #Bryan said, you should forget about Toplevel(). The normal way is Tk().
Try this:
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
label = tk.Label( root, text='Select:', background='green').pack(side='top')
btn1 = ttk.Button( root, text='Discard').pack()
btn2 = ttk.Button( root, text='Quit').pack()
while True:
root.mainloop()
And you should get:

Python: Reading from a spin box numbers and do following command of one

Good Morning/Evening,
I want to read a number from a spinbox, and if it is 2, it should print something. But my code does not work out. I've tried it with a slider instead of a spinbox and it worked out. But for me, it is really important to use a spinbox, so I hope somebody have an idea.
Code:
from tkinter import *
def a():
if spin.get()==2:
print("Hello World")
root = Tk()
root.geometry('300x100')
spin =Spinbox(root, from_=0, to=10,command=a)
button = Button(root, text='Enter')
button.pack(side=RIGHT)
spin.pack(side=RIGHT)
root.mainloop()
Adding to #coolCloud's answer I would suggest setting a textvariable for spinBox. So if the user changes it using the entry. It would automatically be updated.
Something like this:
from tkinter import *
def a(*event):
if text.get()=='2':
print("Hello World")
root = Tk()
root.geometry('300x100')
text = StringVar()
text.trace('w', a) # or give command=a in the button if you want it to call the event handler only when the button is pressed
spin =Spinbox(root, from_=0, to=10, textvariable=text)
button = Button(root, text='Enter')
button.pack(side=RIGHT)
spin.pack(side=RIGHT)
root.mainloop()

Is it possible to reopen tkinter window after closing it whose code written in separate file OnClicking button from file?

filename p1.py
import tkinter as tk
def action():
import p2
root=tk.Tk()
root.title('part1')
root.geometry('200x200+50+50')
btn=tk.Button(root,text='click me',command=action)
btn.pack()
root.mainloop()
filename p2.py
After closing this window, I want to reopen it on clicking the click me button but it does not open once I close this window.
import tkinter as tk
root=tk.Toplevel()
root.title('part2')
root.geometry('200x200+50+50')
lbl=tk.Label(root,text='Hello everybody \n I have problem',font=("times new roman",20,'bold'))
lbl.pack()
root.mainloop()
Here's a solution for you:
Module_one:
import tkinter as tk
def action():
import action_module
action_module.page_two()
root = tk.Tk()
root.title('part1')
root.geometry('200x200+50+50')
btn = tk.Button(root, text='click me', command=action)
btn.pack()
root.mainloop()
action_module:
def page_two():
import tkinter as tk
root = tk.Toplevel()
root.title('part2')
root.geometry('200x200+50+50')
lbl = tk.Label(root, text='Hello everybody \n I think the problem is fixed',
font=("times new roman", 20, 'bold'))
lbl.pack()
root.mainloop()
Just put the code in the second module inside a function. Then call it inside the first file's action function.

How to close other window by python Tkinter?

I have following python code in Tkinter.
import tkinter as tk
def main_gui(login, s):
login.quit() # close login window
win = tk.Tk()
win.geometry('300x150')
name = tk.Label(win, text='Hello' + s.get()) # Hello David
name.pack()
win.mainloop()
# initial Tkinter frame
login = tk.Tk()
login.title('Login')
login.geometry('300x150')
# input user name
user_name_var = tk.StringVar()
user_name_var.set('David')
tk.Label(login, text='User name').place(x=10, y=50)
user_name = tk.Entry(login, textvariable=user_name_var)
user_name.place(x=100, y=50)
input_ok = tk.Button(win_login, command=lambda: main_gui(login, user_name), text='OK', width=15)
input_ok.place(x=100, y=90)
win_login.mainloop()
I want to close login window, but my code can not close it. How to solve it.
You are almost there - only two details you have to adapt:
The method to remove a widget in Tkinter is destroy, so login.quit() should be login.destroy().
Once login is destroyed, the user_name Entry will also be destroyed, and you will not be able to get the name from it anymore. You should get the name earlier, e.g., directly in the lambda:
... lambda: main_gui(login, user_name.get()), ...
you can use the
root.withdraw()
function, this will close the window without completely destroying all of the root.after functions

Preventing circular import example

Lets say I have two python files. Both with an GUI. First is "Main" second is "Calculator". From Main I will start Calculator. So I have to import calculator. In Calculator I will do a calculation. Lets keep I easy an say 1+1=2. Now I want to "send" this Result to an Text in Main.
How do I do that without an circular import? I cant find an good tutorial/example for that!
My code so far:
Main:
from tkinter import *
import Test_2
window = Tk()
window.title("First Window")
def start():
Test_2.start_second()
Input1 = Entry(window)
Input1.grid(row=0,column=0, padx=10, pady=5)
Start = Button(window,text="Start", command=start)
Start.grid(row=1,column=0, padx=10, pady=5)
window.mainloop()
Second:
from tkinter import *
def start_second():
window2 = Tk()
window2.title("Second Window")
def send():
x = Input.get()
Input2 = Entry(window2)
Input2.grid(row=0,column=0, padx=10, pady=5)
Send = Button(window2,text="Send", command=send)
Send.grid(row=1,column=0, padx=10, pady=5)
window2.mainloop()
This code does exactly what you asked for (as opposed to what I suggested in the comment; but anyway, you either get a value from a module function or you send a reference for it to alter)
I tried to follow your structure.
Basically it is a matter of sending the parent window and the first entry as parameters to the second window creation function. Don't call mainloop two times, just once in the end, and use Toplevel for all other windows after the main Tk one. This is not to say that I like the use of an inner function and of the lambda, for readability, but lambdas are necessary in tkinter everytime you want to send parameters to a command callback, otherwise it will get called right way in command definition.
tkinter_w1.py (your main.py)
from tkinter import Tk, ttk
import tkinter as tk
from tkinter_w2 import open_window_2
root = Tk()
entry1 = ttk.Entry(root)
button1 = ttk.Button(root, text='Open Window 2',
command=lambda parent=root, entry=entry1:open_window_2(parent, entry))
entry1.pack()
button1.pack()
root.mainloop()
tkinter_w2.py (your Test_2.py)
from tkinter import Tk, ttk, Toplevel
import tkinter as tk
def open_window_2(parent, entry):
def send():
entry.delete(0,tk.END)
entry.insert(0,entry2.get())
window2 = Toplevel(parent)
entry2 = ttk.Entry(window2)
button2 = ttk.Button(window2, text='Send', command=send)
entry2.pack()
button2.pack()

Categories

Resources