Highlight text when clicked in tkinter - python

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.

Related

Only open 1 window when button clicked multiple times

I am trying to create a basic invoicing system. However i have encountered an issue as you can tell from my the title, is there any way to achieve this. I have been using a counter to determine if the window should open or not but i dont think it is right.
from tkinter import *
window = Tk()
count = 0
def openNewWindow():
global count
count = count + 1
if count == 1:
newWindow = Toplevel(window)
newWindow.title("New Window")
newWindow.geometry("800x800")
newWindow.title('test ©') # Frame title
newWindow.iconbitmap('icon4.ico') # Frame logo
if 'normal' == newWindow.state():
count = 2
else:
count = 0
width = window.winfo_screenwidth()
height = window.winfo_screenheight()
window.geometry("%dx%d" % (width, height))
bg = PhotoImage(file="bsor.gif")
label_image = Label(window, image=bg)
label_image.place(x=0, y=0)
title_label = Label(window, text="Job Management System", bg="black", fg="white")
title_label.config(font=("Courier", 70))
title_label.place(x=65, y=3)
customer_database_button = Button(window, text="Customer Database", width="23", height="2",
font=('Courier', 13, 'bold'), command=openNewWindow)
customer_database_button.grid(row=3, column=0, pady=185, padx=(110, 0))
employee_database_button = Button(window, text="Employee Database", width="23", height="2",
font=('Courier', 13, 'bold'))
employee_database_button.grid(row=3, column=1, pady=10, padx=(50, 0))
job_category_button = Button(window, text="Job Category (Pricing)", width="23", height="2",
font=('Courier', 13, 'bold'))
job_category_button.grid(row=3, column=2, pady=10, padx=(50, 0))
quote_sale_button = Button(window, text="Quotes / Sales", width="23", height="2", font=
('Courier', 13, 'bold'))
quote_sale_button.grid(row=3, column=3, pady=10, padx=(50, 0))
cash_management_button = Button(window, text="Cash Management", width="23", height="2", font=
('Courier', 13, 'bold'))
cash_management_button.grid(row=3, column=4, pady=10, padx=(50, 0))
analysis_mode_button = Button(window, text="Analysis Mode", width="23", height="2", font=
('Courier', 13, 'bold'))
analysis_mode_button.grid(row=3, column=5, pady=10, padx=(50, 0))
window.title('test') # Frame title
window.iconbitmap('icon4.ico') # Frame logo
window.mainloop()
Here is a minimal example on how to do it (works best with only one additional allowed window):
from tkinter import Tk, Toplevel, Button
def open_window(button):
button.config(state='disabled')
top = Toplevel(root)
top.transient(root)
top.focus_set()
top.bind('<Destroy>', lambda _: btn.config(state='normal'))
root = Tk()
root.geometry('300x200')
btn = Button(root, text='Open new window!', command=lambda: open_window(btn))
btn.pack(expand=True)
root.mainloop()
Just have the function disable the button and bind a <Destroy> event to the Toplevel to set the button's state back to normal. (Also you may want to use .transient on the Toplevel to make it appear above its master so that people don't forget that they haven't closed the window and wonder why they can't press the button (it will also not display additional icon in the taskbar))
Also:
I strongly advise against using wildcard (*) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2 and so on or import the whole module: import module then You can also use an alias: import module as md or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.
I strongly suggest following PEP 8 - Style Guide for Python Code. Function and variable names should be in snake_case, class names in CapitalCase. Don't have space around = if it is used as a part of keyword argument (func(arg='value')) but have space around = if it is used for assigning a value (variable = 'some value'). Have space around operators (+-/ etc.: value = x + y(except here value += x + y)). Have two blank lines around function and class declarations.

Tkinter lable config dynamically

i want dynamic lable.config is it possible ? because the result doesn't fix with the screen size and the rest of the text are cut off and cannot see. Here is the code. i know my code is not effective but i am a beginner and i have no idea and dont know anything about GUI in python
def link_GUI(graph):
def btn_click():
data1 = str(txtDataEntry.get()) # get data from test box
data2 = str(txtDataEntry2.get())
r_edge = link(graph, data1, data2)
lblResult.config(text="" + data1 + " and " + data2 + " are linked")
lblResult2.config(text="" + str(r_edge))
root = Tk()
root.title("SSM Application")
root.geometry("1500x600")
lblTitle = Label(text=" Link a station to another station", font=('arial', 20, 'bold'), fg='Black')
lblTitle.pack()
lblTitle = Label(text=" *Close the box to choose another option* ", font=('arial', 10, 'bold'), fg='Black')
lblTitle.pack()
frame1 = Frame()
lblDataentry = Label(frame1, text="Enter first station name:", pady=1, fg='black') # 1111111111111111
lblDataentry.grid(row=0, column=0)
txtDataEntry = Entry(frame1) # 111111111111111
txtDataEntry.grid(row=0, column=1)
lblDataentry = Label(frame1, text="Enter second station name:", pady=1, fg='black') # 2222222222222
lblDataentry.grid(row=1, column=0)
txtDataEntry2 = Entry(frame1) # 222222222222222
txtDataEntry2.grid(row=1, column=1)
btnSubmit = Button(frame1, text="Link", bg='grey', fg='black', command=btn_click)
btnSubmit.grid(row=2, column=1)
frame1.pack() # add frame to gui
lblResult = Label(font=('arial', 18, 'bold'), fg='darkblue')
lblResult.pack()
lblResult2 = Label(font=('arial', 18, 'bold'), fg='darkblue')
lblResult2.pack()
root.mainloop()
the original output result1: https://i.stack.imgur.com/ErzL6.png
here is the result after i tried with wrap length but it also cannot help too is there any other ways to do?
https://i.stack.imgur.com/J3eBd.png
change root.geometry("1500x600") to root.minsize(1500, 600) in order to let the root window to expand.
change lblResult2.pack() to lblResult2.pack(fill="both", expand=1), so that lblResult2 will fill the root window width and adjust the root window height in order to show all its content.
change lblResult2.config(text=""+str(r_edge)) to lblResult2.config(text=str(r_edget), wraplength=lblResult2.winfo_width(), justify='left') in order to wrap its content to fit its width.
Edit: Another solution is to use Text widget instead of Label:
change the following lines
lblResult2 = Label(font=('arial', 18, 'bold'), fg='darkblue')
lblResult2.pack()
to
txtResult2 = Text(font=('arial', 18, 'bold'), fg='darkblue')
txtResult2.pack(fill='both', expand=1)
change the following line in btn_click():
lblResult2.config(text=""+str(r_edge))
to
txtResult2.delete(1.0, 'end')
txtResult2.insert('end', str(r_edge))

tkinter past text keeping font

I have a tkinter text widget and I would be able to copy a text from excel (as exemple) and past it into my text widget 'tC' and keep the font define in excel, like bold, italics, color ect.. for now i just get the text black and basic. I don't get if it's just the display or the font is not past. Thanks you
Here is how I create my text label:
windPop = tk.Toplevel()
windPop.attributes('-topmost', 'true')
windPop.wm_geometry("600x600")
frm1 = tk.LabelFrame(windPop)
frm1.pack(side=tk.TOP)
labT = tk.Label(frm1, text="Titre", bg="white", height=1, width=10)
labT.grid(row=0,column=1)
tT = tk.Text(frm1, height=1, width=10, bg="white")
tT.grid(row=0,column=2)
frm3 = tk.LabelFrame(windPop)
frm3.pack()
labT = tk.Label(frm3, text="Genre", bg="white", height=1, width=10)
labT.grid(row=0,column=1)
sexMail = tk.StringVar(frm3)
sexMail.set("neutre")
tG = tk.OptionMenu(frm3, windows.genreMailVariable, *windows.genreMail)
tG.grid(row=0,column=2)
frm2 = tk.LabelFrame(windPop)
frm2.pack()
labC = tk.Label(frm2, text="Corps du mail", bg="white", width=20)
labC.grid(row=0,column=1)
tC = tk.Text(frm2, height=30, width=40, bg="white")
tC.grid(row=0,column=2)
bb = tk.Button(windPop, text='valider creation', width=20)
bb.pack(pady=10, side=tk.BOTTOM)
bb.configure(command=lambda w=windows, corp=tC, titre=tT, genre=sexMail, par=windPop :self.valid_creation(w, corp, titre, genre, par))
There is no support for this in tkinter. Tkinter can't get font information from the clipboard.

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")

Use If statement with keyboard event in Tkinter 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)

Categories

Resources