Tkinter: I can't highlight text in text widget - python

So I made a text editor using tkinter and I used tag_config to highlight the syntax.
CODE
#Importing modules
from tkinter import *
#Main Window
Window = Tk()
Window.minsize(400, 550)
##Main Script
#Defs
#Main frame
main = Frame(Window)
#Main text widget
text = Text(main, bd=0, highlightthickness=0, borderwidth=0, bg="#323232", fg="white")
#Configs
text.config(width=55, height=35)
main.config(width=55, height=35)
#Tag config for coloring syntax
text.tag_configure("import", foreground="yellow")
Window.update()
#Packs and places
#main.place(anchor="c", rely=.5, relx=.5)
main.pack(expand=True, fill=BOTH, side="right")
text.pack(expand=True, fill=BOTH)
#Update window
Window.update()
#Window.mainloop()
Window.mainloop()
PROBLEM
The tag_configure is not working in line 23
text.tag_configure("import", foreground="yellow")
QUESTION
Is there a way to fix that? or Is there any way to highlighting text in tkinter?
EDIT
I add
def check_syntax(event):
text.tag_add('import', 1.0, END)
text.bind("<Return>", check_syntax)
on the code but there are 1 problem, when i run the code and type
import tkinter in the text widget for test and press enter the "tkinter" is highlighted too
How to fix that?

I believe the reason is that you need to actually add a tag first using the tag_add function. You should read this other question with a similar problem. I tried out the code myself and it works. (You'll have to press enter after completing a line)
How to use tkinter tag_config? Python 3.7.3

tag_configure only configures a tag, it doesn't apply the tag to a range of text. To use the tag you need to call tag_add and give it a start and end index. That, or add the tag when calling insert.
For example, this shows how to insert some text, and then apply highlighting to a few characters:
text.insert("end", "import foo\nimport bar\n")
text.tag_add("import", "1.0", "1.6")
text.tag_add("import", "2.0", "2.6")

Related

change size of tkinter messagebox

In python, I am attempting the change the width of the tkinter messagebox window so that text can fit on one line.
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
messagebox.showinfo("info","this information goes beyond the width of the messagebox")
root.mainloop()
It's not possible to adjust the size of messagebox.
When to use the Message Widget
The widget can be used to display short text messages, using a single font. You can often use a plain Label instead. If you need to display text in multiple fonts, use a Text widget. -effbot
Also see:
Can I adjust the size of message box created by tkMessagebox?
#CharleyPathak is correct. You either need to put a newline in the middle of the text, because message boxes can display multiple lines, or create a custom dialog box.
Heres another method that gets the effect youre looking for but doesnt use messagebox. it looks a lot longer but it just offers much more in terms of customization.
def popupmsg():
popup = tk.Tk()
def leavemini():
popup.destroy()
popup.wm_title("Coming Soon")
popup.wm_attributes('-topmost', True) # keeps popup above everything until closed.
popup.wm_attributes("-fullscreen", True) # I chose to make mine fullscreen with transparent effects.
popup.configure(background='#4a4a4a') # this is outter background colour
popup.wm_attributes("-alpha", 0.95) # level of transparency
popup.config(bd=2, relief=FLAT) # tk style
# this next label (tk.button) is the text field holding your message. i put it in a tk.button so the sizing matched the "close" button
# also want to note that my button is very big due to it being used on a touch screen application.
label = tk.Button(popup, text="""PUT MESSAGE HERE""", background="#3e3e3e", font=headerfont,
width=30, height=11, relief=FLAT, state=DISABLED, disabledforeground="#3dcc8e")
label.pack(pady=18)
close_button = tk.Button(popup, text="Close", font=headerfont, command=leavemini, width=30, height=6,
background="#4a4a4a", relief=GROOVE, activebackground="#323232", foreground="#3dcc8e",
activeforeground="#0f8954")
close_button.pack()
I managed to have a proper size for my
"tkMessageBox.showinfo(title="Help", message = str(readme))" this way:
I wanted to show a help file (readme.txt).
def helpfile(filetype):
if filetype==1:
with open("readme.txt") as f:
readme = f.read()
tkMessageBox.showinfo(title="Help", message = str(readme))
I opened the file readme.txt and EDITED IT so that the length of all lines did not exeed about 65 chars. That worked well for me. I think it is important NOT TO HAVE LONG LINES which include CR/LF in between. So format the txt file properly.

ttk.ComboBox Styling does not get set properly

I have created a python GUI application. It works great, and I've styled everything to my liking, save for the ComboBox. Styling on the ttk.Combobox doesn't seem to work.
That should give an idea of the material style I'm going for. Here's the styling block I have for the combobox.
globalStyle = ttk.Style()
globalStyle.configure('TCombobox', foreground=textColor, background=backgroundColor, fieldbackground=selectColor, fieldforeground=textColor, font='Verdana')
The only thing I have been able to successfully change is the text and the foreground color. I am looking to edit the following attributes:
Text color
Field background
Dropdown text color
Dropdown background
EDIT: I should mention that the color variables used are all valid hex color codes.
selectColor = '#333333'
backgroundColor = '#444444'
foregroundColor = '#555555'
textColor = '#999999'
So I ran in to the same issue but found most of the solution here. All you have to do is add the following to your code:
option add *TCombobox*Listbox.background color
option add *TCombobox*Listbox.font font
option add *TCombobox*Listbox.foreground color
option add *TCombobox*Listbox.selectBackground color
option add *TCombobox*Listbox.selectForeground color
Then to change the font inside the box (when the drop down isn't present) add font='font_style' to your code.
So in my case I had:
class CreateProfile(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, bg='dodgerblue4')
label = tk.Label(self, text="Create Profile", font=large_font, bg='dodgerblue4', fg='deepskyblue')
label.grid(columnspan=10, row=0, column=0, pady=5, padx=5)
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(1, weight=1)
self.option_add("*TCombobox*Listbox*Background", "dodgerblue")
self.option_add("*TCombobox*Listbox*Font", "pirulen")
self.list_c = ttk.Combobox(self, values=("1", "2", "3", "4"), font='pirulen')
self.list_c.grid(row=1, column=1, pady=5, padx=5)
Make sure you also have the following imports:
import tkinter as tk
import tkinter.ttk as ttk
My issue is I'm only able to change the background color of the actual box (when the drop down isn't present). I'm still trying to figure out how to change the font color (foreground doesn't work for me), and the color of the box itself. So if anybody could add to this answer that would be great!
I know that this question is half a year old, but I had a similar issue and managed to solve it. For changing the color of a ttk Combobox popdown frame you can use the following code:
# these imports are indeed only valid for python 3.x
import tkinter as tk
import tkinter.ttk as ttk
# for python 2.x the following import statements should work:
# import Tkinter as tk
# import ttk
root = tk.Tk()
# adding the options to the root elements
# (all comboboxes will receive this options)
root.option_add("*background", "#444444"),
root.option_add("*foreground", "#999999"),
# create a combobox
ttk.Combobox(root, values=["Banana", "Coconut", "Strawberry"]).pack()
root.mainloop()
I'm not sure whether I understand the styling mechanisms of tk correctly.
At least the above code works for me on Python 3.2 and Python 3.4

Tkinter text insert: " 'Nonetype' object has no attribute 'insert'

Relatively new to coding in general, and have been trying to create a simple chat client for Python. Trying to work the GUI, and have encountered the problem shown below.
I have a functioning GUI and use the "example.get()" function to retrieve the string text from an entry box. The program then prints the text to the command prompt (Just to prove it's been retrieved) and then should place it in a text box, however it gives me a "Nonetype" error. Code is below. Does anyone have any idea how to fix this?
Thanks
from tkinter import *
#Create GUI
root=Tk()
root.title("Chat test")
root.geometry("450x450+300+300")
#Declare variables
msg=StringVar()
#Get and post text to chat log
def postaction():
msg1=msg.get()
print(msg1)
chatlog.insert(INSERT,msg1+'\n')
root.mainloop()
#Build GUI components
chatlog=Text(root, height=10, state=DISABLED).pack(side=TOP, fill=X)
entry=Entry(root, textvariable=msg).pack(side=BOTTOM, fill=X)
button=Button(root, command=postaction, text="Button").pack()
The .pack method of a widget always returns None. So, you need to place the calls to .pack on their own line:
chatlog=Text(root, height=10, state=DISABLED)
chatlog.pack(side=TOP, fill=X)
entry=Entry(root, textvariable=msg)
entry.pack(side=BOTTOM, fill=X)
button=Button(root, command=postaction, text="Button")
button.pack()

python Tkinter: scrollbar is not adding to the textarea

the follwing code in a serparate file is working fine. It is creating a text area and adding a scrollbar to it.
root = Tkinter.Tk()
text=Text(root,height=10,width=50,background='pink')
scroll=Scrollbar(root)
text.configure(yscrollcommand=scroll.set)
scroll.config(command=text.yview)
text.pack(side=LEFT)
scroll.pack(side=RIGHT,fill=Y)
But exactly same code is not woking when it was merged with other code (main.py)
//================ other code
root = Tkinter.Tk()
root.geometry("800x600+100+0") # width, height, x ,y
button_1 = Button(root,text="iphone file")
button_1.pack()
button_1.grid(row=0, column=0)
button_1.configure(command=openFile)
//------------------ following is the same code
text=Text(root,height=10,width=50,background='pink')
scroll=Scrollbar(root)
text.configure(yscrollcommand=scroll.set)
scroll.config(command=text.yview)
text.pack(side=LEFT)
scroll.pack(side=RIGHT,fill=Y)
and when i running main.py file from cmd prompt, it just hanging. what is going wrong here ?
You are attempting to use both grid and pack for the same containing widget. You cannot do that. You either need to use grid for the text and scrollbars or use pack for the buttons.

In python's tkinter, how can I make a Label such that you can select the text with the mouse?

In python's tkinter interface, is there a configuration option that will change a Label such that you can select the text in the Label and then copy it to the clipboard?
EDIT:
How would you modify this "hello world" app to provide such functionality?
from Tkinter import *
master = Tk()
w = Label(master, text="Hello, world!")
w.pack()
mainloop()
The easiest way is to use a disabled text widget with a height of 1 line:
from Tkinter import *
master = Tk()
w = Text(master, height=1, borderwidth=0)
w.insert(1.0, "Hello, world!")
w.pack()
w.configure(state="disabled")
# if tkinter is 8.5 or above you'll want the selection background
# to appear like it does when the widget is activated
# comment this out for older versions of Tkinter
w.configure(inactiveselectbackground=w.cget("selectbackground"))
mainloop()
You could use an entry widget in a similar manner.
Made some changes to the above code:
from tkinter import *
master = Tk()
w = Text(master, height=1)
w.insert(1.0, "Hello, world!")
w.pack()
# if tkinter is 8.5 or above you'll want the selection background
# to appear like it does when the widget is activated
# comment this out for older versions of Tkinter
w.configure(bg=master.cget('bg'), relief="flat")
w.configure(state="disabled")
mainloop()
The relief needs to be flat in order for it to look like an ordinary part of the display. :)
You can make texts which are selectable using either Text or Entry
I really find both useful, using text can be really helpful! Here I show you a code of Entry:
from tkinter import *
root = Tk()
data_string = StringVar()
data_string.set("Hello World! But, Wait!!! You Can Select Me :)")
ent = Entry(root,textvariable=data_string,fg="black",bg="white",bd=0,state="readonly")
ent.pack()
root.mainloop()
Tried Bryan Oakley's answer. Able to select the text but couldn't copy it to clipboard. Here is a workaround.
from Tkinter import *
def focusText(event):
w.config(state='normal')
w.focus()
w.config(state='disabled')
master = Tk()
w = Text(master, height=1, borderwidth=0)
w.insert(1.0, "Hello, world!")
w.pack()
w.configure(state="disabled")
w.bind('<Button-1>', focusText)
mainloop()
We could not copy the text unless the widget gets focused. We are anyway gonna use the mouse button1 (left-click) to select the text, so binding it to a function which enables the text widget, sets focus on it, then disables it again.
The other answers insert text to the text box instead of replacing the text. That works when you need to change the text only for one time. However, you need to delete the line first if you need to replace it. The following code would fix this issue:
from tkinter import *
master = Tk()
w = Text(master, height=1)
w.delete(1.0, "end")
w.insert(1.0, "Hello, world!")
w.pack()
# if tkinter is 8.5 or above you'll want the selection background
# to appear like it does when the widget is activated
# comment this out for older versions of Tkinter
w.configure(bg=master.cget('bg'), relief="flat")
w.configure(state="disabled")
mainloop()

Categories