Whenever I try to bind a text widget with "<Control-x>" , I keep getting an error that says:
_tkinter.TclError: PRIMARY selection doesn't exist or form "STRING" not defined
Here's the code:
from tkinter import *
root = Tk()
def cut_text(event):
selected = text.selection_get()
clipboard_label.config(text = clipboard_label['text'] + f"\t{selected}")
text = Text(root , width = 65 , height = 20 , font = "consolas 14")
text.grid(row = 0 , column = 0)
clipboard_label = Label(root , text = "Your Clipboard History:" , font = "arial 11")
clipboard_label.grid(row = 1 , column = 0)
root.bind("<Control-x>" , cut_text)
mainloop()
As I keep getting that error , I tried this:
def cut_text(event):
selected = text.get("sel.first" , "sel.last")
clipboard_label.config(text = clipboard_label['text'] + f"\t{selected}")
But when I do that , I get this error:
_tkinter.TclError: text doesn't contain any characters tagged with "sel"
I don't face this problem with any other binding like "<Control-c>" , but this problem only occurs when I use the "<Control-x>" binding.
Is there any way to solve this problem ?
It would be great if anyone could help me out.
Well you can return 'break' for this purpose. Like:
text.bind("<Control-x>" , cut_text)
root.bind('<Control-x>',lambda e: 'break')
What 'break' does is, it overrides the default behaviour(sort-ish). I could link you to a nicely written documentation, but Effbot is currently down.
Related
When I try to translate text using the googletrans module, I get an error:
httpcore._exceptions.ConnectTimeout: _ssl.c:1106: The handshake operation timed out
Here's my code:
from tkinter import *
from googletrans import Translator , LANGUAGES
root = Tk()
root.geometry("500x500")
def translate():
translator = Translator()
translated_text = translator.translate(text=entry.get(),
dest=languages_listbox.get(languages_listbox.curselection())) # Text does not get get translated and it throws an error
output_label.config(text = f"Translated Text: {translated_text}")
entry = Entry(root , font = "consolas 14")
entry.place(x = 120 , y = 0)
entry.insert(0 , "Hello world")
languages_list = []
for key, value in LANGUAGES.items():
languages_list.append(value)
languages_listbox_frame = Frame(root)
languages_listbox_frame.place(x = 120 , y = 50)
languages_listbox = Listbox(languages_listbox_frame , font = "calibri 14")
languages_listbox.grid(row = 0 , column = 0)
scrollbar = Scrollbar(languages_listbox_frame , orient = VERTICAL , command = languages_listbox.yview)
scrollbar.grid(row = 0 , column = 1 , sticky = N+S+E+W)
languages_listbox.config(yscrollcommand = scrollbar.set)
for language in languages_list:
languages_listbox.insert(END , language)
languages_listbox.select_set(0)
translate_button = Button(root , text = "Translate" , font = "comicsansms 18 bold" , command = translate)
translate_button.place(x = 160 , y = 370)
output_label = Label(root , text = "Translated Text: " , font = "comicsansms 16 bold")
output_label.place(x = 5 , y = 460)
mainloop()
My code is very simple and I can't figure out what's wrong with it.
I tried changing the network connection, but it made no difference.
Is there any way to fix this problem?
It would be great if anyone could help me out.
Well that seems very much like an API error as google does not like when you send too much request, I cannot close this question either as the answer there is not an accepted one, anyway here is an alternative using deep_translator.
Start by installing it:
pip install deep-translator
Now I recommend you take a stroll down its docs, but ill include an example using Google Translate anyway. Start by importing it:
from deep_translator import GoogleTranslator
Now create an initial instance of it, just to get the language map.
translator = GoogleTranslator(target='en')
languages_list = []
lang_map = translator.get_supported_languages(as_dict=True) # Get in form of dict
for key, value in lang_map.items():
languages_list.append(key.title()) # Making first letter capital with title()
Now for the translation part, change your function to the following:
def translate():
lang = lang_map[languages_listbox.get(languages_listbox.curselection()[0]).lower()] # Get the corresponding language code from the dictionary
translator = GoogleTranslator(source='en',target=lang) # Create new instance with selected language
translated_text = translator.translate(entry.get()) # Translate
output_label.config(text = f"Translated Text: {translated_text}") # Update the text
Yes creating a new instance every time function is run is not a good idea, but I couldn't find another successful method to change the target language once it is initially set. It does not seem to give any error as of now, unless your source and target languages are both same.
On a side note, it is better to use threading, as sometimes the API might take time to respond and it will freeze the GUI.
Using python 2.7 and Tkinter.
I am creating four lables in a loop and binding them to . I want the label to return
the name in the label's text.
The problem is that no matter which label I press it returns the name in the last label.
I found this question Python Tkinter: Bind function with labels in for loop with exactly my problem but the solution given does not work for me even if I copied the code exactly.
Please anyone? here is my original code:
# labelbind.py
from Tkinter import *
root = Tk()
root.title('Label choices')
root.geometry('1160x900+650+50')
root.option_readfile('setstyle2.txt')
def lblpress(x):
print 'Label pressed', x
names = ['AMEX', 'CIBC', 'VISA', 'BMO']
col = 150
row = 45
num = 1
for name in names:
bobo = 'lbl' + str(num)
print bobo, name
bobo = Label(root, text = name)
bobo.bind('<ButtonRelease-1>', lambda x = name : lblpress(name))
bobo.place(x = col, y = row)
row += 40
num += 1
root.mainloop()
You don't need to pass anything to the callback. The event object that is given to the callback contains a reference to the widget, and from the widget you can get the text.
For example:
import Tkinter as tk
def lblpress(event):
print 'Label pressed:', event.widget.cget("text")
root = tk.Tk()
names = ['AMEX', 'CIBC', 'VISA', 'BMO']
for name in names:
label = tk.Label(root, text=name)
label.bind("<ButtonRelease-1>", lblpress)
label.pack(side="top")
root.mainloop()
I am trying to take entry from an entry boxes and use them in an equation. Basically it is
Entry_one - Entry_two * entry_three / 12. But I cant seem to figure out how to do this. To make it more clear here is the working python code:
a = int(input('Order Amount. '))
c = int(input('Beams Left. '))
l = int(input('Beam Length. '))
a1 = a-c
a2 = a1*l
a3 = a2/12
print ('The Hourly Count Is: ',a3)
Now here is the code that I'm trying to make do the exact same thing with tkinter:
from tkinter import *
root = Tk()
root.geometry('450x450')
root.title('Hourly Production Count')
def calc_result():
subtract_var = int(total_order_ent.get()) - int(beams_left_ent.get())
beams_left_var = int(subtract_var) * int(length_ent.get())
order_output = int(beams_left_var) / 12
answer_var = order_output.get()
label = Label(root,text = answer_var).pack()
button1 = Button(root,text = 'Enter',command = calc_result,fg='black',bg= 'green').pack()
total_order_ent = Entry(root).pack()
Beams_left_ent = Entry(root).pack()
length_ent = Entry(root).pack()
label_total = Label(root,text = 'Enter Total Order Amount').pack()
label_beams_left = Label(root,text = 'Enter Amount Left To Complete').pack()
root.mainloop()
That's what I have so far. I havn't used any grid placement for the widgets yet since I just want to get the code to work before I work on how it looks but if anyone can help me it would be appreciated. I've searched other questions and have modified other code, tried it as a class and other things and just cant seem to make it work. some errors I'm getting are:
line 23, in <module>
label_length = Label('Enter Beam Length').pack()
Python\Python35\lib\tkinter\__init__.py", line 2109, in _setup
self.tk = master.tk
AttributeError: 'str' object has no attribute 'tk'
Your code doesn't exhibit the error you say it does. Just about the only possible way to get that specific error is if you omit the first three lines of your program after the import, and set root to a string. Even when you do that, you get a slightly different error -- it will complain about the first use of Button rather than Label as in your question.
My guess is, you're not running the exact code you think you are. Regardless, this specific problem is due to the fact you haven't properly created a root window, and you're passing a string as the parent to the other widgets.
Once you solve that problem, you also will need to solve the problem addressed in this question: Tkinter: AttributeError: NoneType object has no attribute get. The short version is, total_order_ent = Entry(root).pack() will set total_order_ent to None, making it impossible to get the value of the widget at a later date.
you could create a variable and retrieve it with the get method in your function:
as explained in the following documentation:
from tkinter import *
root = Tk()
var_01 = StringVar()
enter_01 = Entry(root, textvariable=var_01)
enter_01.pack()
def get_var():
getvar = var_01.get()
print(getvar)
button_01 = Button(root, text='print variable', command=get_var)
button_01.pack()
root.mainloop()
I have written a program in Python that allow me to change the names of many files all at once. I have one issue that is quite odd.
When I use raw_input to get my desired extension, the GUI will not launch. I don't get any errors, but the window will never appear.
I tried using raw_input as a way of getting a file extension from the user to build the file list. This program will works correctly when raw_input is not used.The section of code that I am referring to is in my globList function. For some reason when raw_imput is used the window will not launch.
import os
import Tkinter
import glob
from Tkinter import *
def changeNames(dynamic_entry_list, filelist):
for index in range(len(dynamic_entry_list)):
if(dynamic_entry_list[index].get() != filelist[index]):
os.rename(filelist[index], dynamic_entry_list[index].get())
print "The files have been updated!"
def drawWindow(filelist):
dynamic_entry_list = []
my_row = 0
my_column = 0
for name in filelist:
my_column = 0
label = Tkinter.Label(window, text = name, justify = RIGHT)
label.grid(row = my_row, column = my_column)
my_column = 1
entry = Entry(window, width = 50)
dynamic_entry_list.append(entry)
entry.insert(0, name)
entry.grid(row = my_row, column = my_column)
my_row += 1
return dynamic_entry_list
def globList(filelist):
#ext = raw_input("Enter the file extension:")
ext = ""
desired = '*' + ext
for name in glob.glob(desired):
filelist.append(name)
filelist = []
globList(filelist)
window = Tkinter.Tk()
user_input = drawWindow(filelist)
button = Button(window, text = "Change File Names", command = (lambda e=user_input: changeNames(e, filelist)))
button.grid(row = len(filelist) + 1 , column = 1)
window.mainloop()
Is this a problem with raw_input?
What would be a good solution to the problem?
This is how tkinter is defined to work. It is single threaded, so while it's waiting for user input it's truly waiting. mainloop must be running so that the GUI can respond to events, including internal events such as requests to draw the window on the screen.
Generally speaking, you shouldn't be mixing a GUI with reading input from stdin. If you're creating a GUI, get the input from the user via an entry widget. Or, get the user input before creating the GUI.
A decent tutorial on popup dialogs can be found on the effbot site: http://effbot.org/tkinterbook/tkinter-dialog-windows.htm
I got the error unexpected EOF while parsing when i'm trying to create a conversion program with tkinter. Here is my code:
from tkinter import *
from tkinter.ttk import *
class conversion:
def centi():
def centiMet():
meStr=a.get()
meStrc = eval(meStr)
con=meStrc/100
conS=str(con)
CenMet2=Label(root,text=conS + " Meters",font="CenturyGothic 12 bold").pack()
return
rootCm= Tk()
a = StringVar()
rootCm.geometry("500x300")
rootCm.title("Quick Reference Application - Version 0.1.8 [alpha] ")
label1= Label(rootCm,text="Unit Conversions",font="CenturyGothic 17 bold").pack()
inputCm= Entry(rootCm,textvariable=a).pack()
convButton1= Button(rootCm,text="Convert!",command = centiMet).pack()
root= Tk()
root.geometry("500x300")
root.title("Quick Reference Application - Version 0.1.8 [alpha] ")
label1= Label(root,text="Unit Conversions",font="CenturyGothic 17 bold").pack()
CenMet1= Label(root,text="Please select the type you want!!",font="CenturyGothic 12 bold").pack()
convButton1= Button(root,text="Centimeters to Meters",command = conversion.centi).pack()
The error will show after you clicked the centimeter to meter button and try to convert. It works fine before i tried to make a button to initiate a new window for the cm to meters. Does anyone have any suggestion?
As you noticed, the problem seems to be with the second Tk() element. I am not 100% sure why this is the case, but it seems to work if you use a Toplevel window instead.
class conversion:
def centi():
def centiMet():
meStr = a.get()
con = float(meStr) / 100
Label(rootCm, text="{} Meters".format(con), font="CenturyGothic 12 bold").pack()
rootCm = Toplevel()
rootCm.geometry("500x300")
a = StringVar()
Label(rootCm, text="Unit Conversions", font="CenturyGothic 17 bold").pack()
Entry(rootCm, textvariable=a).pack()
Button(rootCm, text="Convert!", command=centiMet).pack()
Some more pointers:
don't use eval if it can be avoided; use float instead
label = Label(...).pack() will assign the result of pack() to label, not the actual label; also, you do not seem to need those variables anyway
not sure whether this was intentional or not, but you added the result label to the original root, not to the popup-window
If you want to reuse the same label when converting multiple measures, use another StringVar:
class conversion:
def centi():
def centiMet():
b.set("{} Meters".format(float(a.get()) / 100))
...
b = StringVar()
Label(rootCm, textvariable=b, font="CenturyGothic 12 bold").pack()