Use If statement with keyboard event in Tkinter Python - python

I am writing a program in Python on Ubuntu, to import files from a folder then single Left click for Highlight the filename and "Delete" keyboard button for remove that Highlighted file
Single click is working fine,
but when I press delete button, it is not working and start deleting characters of filename which is totally unnecessary.
I am trying to adding multi-functions when I pressed "Delete" button from keyboard?
how do I use "Delete" button with IF... THEN statement in Python?
import subprocess,os
from Tkinter import *
def text_click_callback(event):
# an event to highlight a line when single click is done
line_no = event.widget.index("#%s,%s linestart" % (event.x, event.y))
line_end = event.widget.index("%s lineend" % line_no)
event.widget.tag_remove("highlight", 1.0, "end")
event.widget.tag_add("highlight", line_no, line_end)
event.widget.tag_configure("highlight", background="yellow")
the_text = event.widget.get(line_no, line_end)
tex.tag_bind(the_text, "<Delete>", lambda event, the_text1 = path+'/'+the_text: os.remove(the_text1))
def viewFile():
tex.delete('1.0', END)
for f in os.listdir(path):
linkname="link-" + f
tex.insert(END,f + "\n", linkname)
tex.tag_configure(linkname, foreground="blue", underline=True)
tex.tag_bind(linkname, "<Button-1>", text_click_callback ) # highlight a line
if __name__ == '__main__':
root = Tk()
step = LabelFrame(root,text="FILE MANAGER", font = "Arial 20 bold italic")
step.grid(row=1, columnspan=7, sticky='W',padx=100, pady=5, ipadx=130, ipady=25)
Button(step, text="ViewFile", font = "Arial 8 bold italic", activebackground="turquoise", width=30, height=5, command=viewFile).grid (row= 6, column =3)
Button(step, text="Exit", font = "Arial 8 bold italic", activebackground="turquoise", width=20, height=5, command=root.quit).grid (row= 6, column =5)
tex = Text(master=root) # TextBox For Displaying File Information
scr=Scrollbar(root,orient =VERTICAL,command=tex.yview)
scr.grid(row=8, column=2, rowspan=15, columnspan=1, sticky=NS)
tex.grid(row=8, column=1, sticky=E)
tex.config(yscrollcommand=scr.set,font=('Arial', 8, 'bold', 'italic'))
global process
path = os.path.expanduser("/tmp") # Define path To play, delete, or rename video
root.mainloop()

Don't use tag_bind. Use the normal bindmethod. Then, instead of passing the data in, have the bound function query for the selected filename. If your bound function returns the string "break", it will prevent the default binding from working (the reason why characters are being deleted).
It sounds like you would be better off using a listbox widget, if all you are doing is giving the user a list of items to select. It will require a bit less code, and not be subject to other behaviour that the text widget provides which you likely don't want.
Example:
def deleteHighlightedFile(event):
text = event.widget.get("highlight.first", "highlight.last")
print "selected file:", text
return "break"
...
tex = Text(master=root)
tex.bind("<Delete>", deleteHighlightedFile)

Related

Python GUI - "<Return>" event only seems to run once

I'm trying to create a Tkinter GUI that will take a value from a textbox and put another value in a second textbox when the user presses Enter. So far I'm stuck on binding the event correctly. Here is the code:
# Event handler functions
def get_input(event):
print("hello world")
input_str = tbx_input.get("1.0", "end-1c")
tbx_output.delete("1.0", "end")
tbx_output.insert("1.0", input_str)
root = tk.Tk()
# Widget definitions
tbx_input = tk.Text(
fg="black",
bg="white",
width=40,
height=1,
)
tbx_output = tk.Text(
fg="black",
bg="white",
width=40,
height=1,
)
# Event binding
root.bind("<Return>", get_input)
# Display logic
tbx_input.pack()
tbx_output.pack()
root.mainloop()
Here are the steps I take in the GUI.
In the first textbox, type something:
Press Enter, and expect the text I typed to appear in the second textbox (As expected)
Then I type something else in the first textbox
And I expect the value to appear in the 2nd textbox. It does not.
However the terminal output shows that the event function is being triggered, as "hello world" is printed twice:
$ python testapp.py
hello world
hello world
So while the hello world gets printed once, the "delete" and "insert" calls to the second textbox only happen the first time the function gets called.
Why is this?
You could change the text box from a Text widget to an Entry widget, and modify the get and insert calls accordingly. The caveat here is that the Entry widget only accepts a single line of text.
def get_input(event):
input_str = tbx_input.get() # just 'get()' is sufficient here
tbx_output.delete(0, 'end') # clear out the output textbox
tbx_output.insert(0, input_str) # update the 'insert()' call as well
tbx_input = tk.Entry( # use an Entry widget
fg="black",
bg="white",
width=40,
height=1,
)
tbx_output = tk.Entry( # use an Entry widget
fg="black",
bg="white",
width=40,
height=1,
)

Tkinter Radio Button Controlling If True

I am trying to do a simple program. I am trying to check if radio button 1 is selected show a button and if radio button 2 selected and if there is a button on the screen disappear it. Please help me.
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog
bati = tkinter.Tk()
bati.geometry('500x500')
bati.title('Project')
def hello():
messagebox.showinfo("Say Hello", "Hello World")
def askfile():
bati.filename = filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
lb2 = Label(bati, text=bati.filename, fg='red', font=("Times", 10, "bold"))
lb2.place(x='270',y='34')
def first():
b = Button(bati, text='Import', activebackground='red', bd='3', bg='gray', fg='yellow', font=("Times New Roman", 10, "bold"), command=askfile)
b.place(x='200',y='30')
working = True
def second():
if working == True:
b.widget.pack_forget()
working = False
canvas_width = 3000
canvas_height = 220
w = Canvas(bati, width=canvas_width,height=canvas_height)
w.pack()
y = int(canvas_height / 2)
w.create_line(0, y, canvas_width, y, fill="#476042", width='2')
v = IntVar()
v.set('L')
rb1 = Radiobutton(bati, text='Import A File', value=1, variable=v, command=first, font=("Comic Sans MS", 10, "bold"))
rb2 = Radiobutton(bati, text='Choose From Web', value=2, variable=v, command=second, font=("Comic Sans MS", 10, "bold"))
rb1.place(x='50',y='30')
rb2.place(x='50',y='50')
working = False
bati.mainloop()
Issues:
Local variables will not work for this - you need to remember the button state outside of first and second, so that you can use it the next time.
We show the button with .place, so we should similarly hide it with .place_forget instead of .pack_forget.
The .place position should be given with integers instead of strings. Similarly for the button's bd, i.e. border width (in pixels, i.e. a number of pixels).
Event handlers are supposed to receive an event parameter, even if you ignore it. The .widget you've written in your second command is presumably copied from some other code that tries to find out the widget to hide from the event data (e.g. here). But that .widget would be the one that sent the command, i.e. the Radiobutton, not the Button that you want to hide.
What we will do is create the button ahead of time, in a global variable (in a more serious project, you should consider using classes instead, and then you would use a class member to remember it). Since the button should start out not visible, we just don't .place it right away, but instead use .place in first and .place_forget in second. So:
b = Button(
bati, text='Import', activebackground='red', bd=3,
bg='gray', fg='yellow', font=("Times New Roman", 10, "bold"),
command=askfile
)
def first(event):
b.place(x=200,y=30)
def second():
b.place_forget()

How to clear/delete the contents of a Tkinter Text widget?

I am writing a Python program in TKinter on Ubuntu to import and print
the name of files from particular folder in Text widget.
It is just adding filenames to the previous filnames in the Text
widget, but I want to clear it first, then add a fresh list of filenames.
But I am struggling to clear the Text widget's previous list of
filenames.
Can someone please explain how to clear a Text widget?
Screenshoot and coding is giving below:
import os
from Tkinter import *
def viewFile():
path = os.path.expanduser("~/python")
for f in os.listdir(path):
tex.insert(END, f + "\n")
if __name__ == '__main__':
root = Tk()
step= root.attributes('-fullscreen', True)
step = LabelFrame(root, text="FILE MANAGER", font="Arial 20 bold italic")
step.grid(row=0, columnspan=7, sticky='W', padx=100, pady=5, ipadx=130, ipady=25)
Button(step, text="File View", font="Arial 8 bold italic", activebackground=
"turquoise", width=30, height=5, command=viewFile).grid(row=1, column=2)
Button(step, text="Quit", font="Arial 8 bold italic", activebackground=
"turquoise", width=20, height=5, command=root.quit).grid(row=1, column=5)
tex = Text(master=root)
scr=Scrollbar(root, orient=VERTICAL, command=tex.yview)
scr.grid(row=2, column=2, rowspan=15, columnspan=1, sticky=NS)
tex.grid(row=2, column=1, sticky=W)
tex.config(yscrollcommand=scr.set, font=('Arial', 8, 'bold', 'italic'))
root.mainloop()
I checked on my side by just adding '1.0' and it start working
tex.delete('1.0', END)
you can also try this
According to the tkinterbook the code to clear a text element should be:
text.delete(1.0,END)
This worked for me. source
It's different from clearing an entry element, which is done like this:
entry.delete(0,END) #note the 0 instead of 1.0
this works
import tkinter as tk
inputEdit.delete("1.0",tk.END)
from Tkinter import *
app = Tk()
# Text Widget + Font Size
txt = Text(app, font=('Verdana',8))
txt.pack()
# Delete Button
btn = Button(app, text='Delete', command=lambda: txt.delete(1.0,END))
btn.pack()
app.mainloop()
Here's an example of txt.delete(1.0,END) as mentioned.
The use of lambda makes us able to delete the contents without defining an actual function.
for me "1.0" didn't work, but '0' worked. This is Python 2.7.12, just FYI. Also depends on how you import the module. Here's how:
import Tkinter as tk
window = tk.Tk()
textBox = tk.Entry(window)
textBox.pack()
And the following code is called when you need to clear it. In my case there was a button Save that saves the data from the Entry text box and after the button is clicked, the text box is cleared
textBox.delete('0',tk.END)
I think this:
text.delete("1.0", tkinter.END)
Or if you did from tkinter import *
text.delete("1.0", END)
That should work
A lot of answers ask you to use END, but if that's not working for you, try:
text.delete("1.0", "end-1c")
text.delete(0, END)
This deletes everything inside the text box

Highlight text when clicked in tkinter

I'm working on my Python program (on an Ubuntu system), and I have little idea of what I am doing: I am importing media filenames from a folder, and print it in a Text widget, and then click it to open on VLC Player.
I just want to add an additional feature, that is: when I click on any filename, it should be highlight and then open on VLC.
Can you please guide me on how can I do it?
import subprocess,os
from Tkinter import *
def viewFile():
tex.delete('1.0', END)
for f in os.listdir(path):
if f.endswith('.h264'):
linkname="link-" + f
tex.insert(END,f + "\n", linkname)
tex.tag_configure(linkname, foreground="blue", underline=True)
tex.tag_bind(linkname, "<1>", lambda event, filename =path+'/'+f: subprocess.call(['vlc',filename])) # Video play on VLC Player
if __name__ == '__main__':
root = Tk()
step= root.attributes('-fullscreen', True)
step = LabelFrame(root,text="FILE MANAGER", font = "Arial 20 bold italic")
step.grid(row=1, columnspan=7, sticky='W',padx=100, pady=5, ipadx=130, ipady=25)
Button(step, text="ViewFile", font = "Arial 8 bold italic", activebackground="turquoise", width=30, height=5, command=viewFile).grid (row= 6, column =3)
Button(step, text="Exit", font = "Arial 8 bold italic", activebackground="turquoise", width=20, height=5, command=root.quit).grid (row= 6, column =5)
tex = Text(master=root) # TextBox For Displaying File Information
scr=Scrollbar(root,orient =VERTICAL,command=tex.yview)
scr.grid(row=8, column=2, rowspan=15, columnspan=1, sticky=NS)
tex.grid(row=8, column=1, sticky=E)
tex.config(yscrollcommand=scr.set,font=('Arial', 8, 'bold', 'italic'))
global process
path = os.path.expanduser("~/python") # Define path To play, delete, or rename video
root.mainloop()
I modified your example to have the lines highlight. How to highlight a line is explained here. Basicly I added a text_click_callback that check which line is clicked and highlight it and calls vlc. I changed the input folder, to be able to execute the code, as I dont have any video files to work with.
import subprocess,os
from Tkinter import *
def text_click_callback(event):
# an event to highlight a line when single click is done
line_no = event.widget.index("#%s,%s linestart" % (event.x, event.y))
#print(line_no)
line_end = event.widget.index("%s lineend" % line_no)
event.widget.tag_remove("highlight", 1.0, "end")
event.widget.tag_add("highlight", line_no, line_end)
event.widget.tag_configure("highlight", background="yellow")
def viewFile():
tex.delete('1.0', END)
for f in os.listdir(path):
#if f.endswith('.h264'):
linkname="link-" + f
tex.insert(END,f + "\n", linkname)
tex.tag_configure(linkname, foreground="blue", underline=True)
tex.tag_bind(linkname, "<Button-1>", text_click_callback ) # highlight a line
tex.tag_bind(linkname, "<Double-Button-1>", lambda event, filename =path+'/'+f: subprocess.call(['vlc',filename]) ) # Video play on VLC Player
if __name__ == '__main__':
root = Tk()
#step= root.attributes('-fullscreen', True)
step = LabelFrame(root,text="FILE MANAGER", font = "Arial 20 bold italic")
step.grid(row=1, columnspan=7, sticky='W',padx=100, pady=5, ipadx=130, ipady=25)
Button(step, text="ViewFile", font = "Arial 8 bold italic", activebackground="turquoise", width=30, height=5, command=viewFile).grid (row= 6, column =3)
Button(step, text="Exit", font = "Arial 8 bold italic", activebackground="turquoise", width=20, height=5, command=root.quit).grid (row= 6, column =5)
tex = Text(master=root) # TextBox For Displaying File Information
scr=Scrollbar(root,orient =VERTICAL,command=tex.yview)
scr.grid(row=8, column=2, rowspan=15, columnspan=1, sticky=NS)
tex.grid(row=8, column=1, sticky=E)
tex.config(yscrollcommand=scr.set,font=('Arial', 8, 'bold', 'italic'))
global process
path = os.path.expanduser("/tmp") # Define path To play, delete, or rename video
root.mainloop()
How it works is shown below:
But I think Bryan Oakley is right. A listbox would be better for this. Nevertheless, if you want to keep using Text, you can do as in the example provided.

print in TextBox Tkinter Python on Ubuntu

I don't know what exactly what should I called this problem so if plz edit if not fully understand.
I am writing a program in Python on Ubuntu, to print file names in TextBox with scrolling option in Y-axis.
But file names are appearing outside the TextBox and scroll option is also not working properly.
I also attached the output of program below
Can you plz me to resolve this issue?
import io,sys,os,subprocess
from Tkinter import *
def viewFile():
s=1
for f in os.listdir(path):
var= StringVar()
var.set(f)
l1 = Label(mainframe, textvariable=var)
l1.grid(row=s)
s += 1
if __name__ == '__main__':
root = Tk()
mainframe= root.title("FILE MANAGER APPLICATION") # Program Objective
mainframe= root.attributes('-fullscreen', True)
step = LabelFrame(root,text="FILE MANAGER", font = "Arial 20 bold italic")
step.grid(row=0, columnspan=7, sticky='W',padx=100, pady=5, ipadx=130, ipady=25)
Button(step, text="File View", font = "Arial 8 bold italic", activebackground="turquoise", width=30, height=5, command=viewFile).grid (row= 1, column =2)
Button(step, text="Exit", font = "Arial 8 bold italic", activebackground="turquoise", width=20, height=5, command=root.quit).grid (row= 1, column =5)
tex = Text(master=root)
scr=Scrollbar(root,orient =VERTICAL,command=tex.yview)
scr.grid(row=2, column=2, rowspan=15, columnspan=1, sticky=NS)
tex.grid(row=2, column=1, sticky=W)
tex.config(yscrollcommand=scr.set,font=('Arial', 8, 'bold', 'italic'))
global process
path = os.path.expanduser("~/python") # Define path To play, delete, or rename video
root.mainloop()
If you want to insert the filenames in tex, then call tex.insert instead of creating new Labels.
def viewFile():
for f in os.listdir(path):
tex.insert(END, f + "\n")

Categories

Resources