According to http://www.tkdocs.com/tutorial/text.html#more, in Tk/Tcl it is possible to embed "elided" text in a Text widget, text that is not displayed. This sounds useful. Is this functionality available in Python? If so, what is the API?
Below example produces a Text widget that has elided text in it, using tags:
import tkinter as tk
root = tk.Tk()
text = tk.Text(root)
text.pack()
text.tag_config('mytag', elide=True)
text.insert('end', "This text is non-elided.")
text.tag_add('mytag', '1.13', '1.17')
def toggle_elision():
# cget returns string "1" or "0"
if int(text.tag_cget('mytag', 'elide')):
text.tag_config('mytag', elide=False)
else:
text.tag_config('mytag', elide=True)
tk.Button(root, text="Toggle", command=toggle_elision).pack()
root.mainloop()
Furas is quite right... The solution is as simple as the elide=True keyword arg passed to the tag_config() method. It's strange that the elide keyword is not documented in any Tkinter docs I can find. But, the simplest scenario is to create a tag config as follows:
textWidget.tag_config('hidden', elide=True) # or elide=1
This will cause the tagged text to be "invisible" or "hidden" in the text widget. You will not be able to see the text in the Text widget, but it is still there. If you call textWidget.get('1.0', 'end - 1c'), you'll see the hidden characters in the text returned by the method. You can also delete the hidden characters from textWidget without needing to see them. As you're deleting the elided characters, you won't see the INSERT cursor move. It's a bit odd...
Note that the tagged text can span multiple lines, so all lines are collapsed in the Text widget. The first thing I thought of while testing this was that, if I were implementing a source code editor and wanted to add the feature of "collapsing" part of the code (say, in an if block), elided text would be the feature I would want to be using to do that.
Thanks, Furas!
Related
I am writing a python code to create a RICH TEXT EDITOR in pythonmy python text editor. It has a bold button and all formating buttons like italic,fonts etc.
These buttons would format the selected text.
But the problem with all these buttons is that First when I bold the selected text, it is working fine but at the second time it applies the same format to the previously selected text
This is my code for the bold and italic function :
def boldtxt():
bldbtn['activebackground']="#ffad33"
contboxfont['weight']="bold"
contbox.tag_add("bold",SEL_FIRST,SEL_LAST)
contbox.tag_config("bold",font=contboxfont)
def italictxt():
itlbtn['activebackground']="#ffad33"
contboxfont['slant']="italic"
contbox.tag_add("italic",SEL_FIRST,SEL_LAST)
contbox.tag_config("italic",font=contboxfont)
contbox=Text()
contbox.pack()
bldbtn=Button(comand=boldtxt)
bldbtn.pack()
itlbtn=Button(command=italictxt)
itlbtn.pack()
I want that every word (or selected item should be formatted according to the user.
For ex.
if the bold button is pressed the selected text should be bold
and if the italic button is pressed then the selected text would be italic.
Thanks in advance :)
If you want each word to be uniquely formatted, they each need to have a unique tag. In your code, everything uses the "bold" tag, so if you change the "bold" tag, all of the words would change. If you don't want that, each word will need its own unique tag.
Is there a way to change the color of specific text in the Text widget in Tkinter?
Any answer will be welcomed.
The Library manual has a tkinter chapter that lists some online and paper materials. I mostly use the NMT reference. See its Text widget sections and in particular the text methods section.
Tags are the specific answer to your question. You can tag a slice of text with a string either when inserting or later (tag_add method). A slice can get multiple tags. A tag can be applied to multiple slices. One can customize 19 options for a given tag with the tag_config method. Color is just one of them, but perhaps the most common. It is used by syntax coloring. Minimal example:
from tkinter import Tk, Text
root = Tk()
text = Text(root)
text.pack()
text.insert('insert', 'normal text')
text.insert('insert', ' red text', 'RED')
text.tag_config('RED', foreground='red')
root.mainloop()
I'm wondering how to get all the tags within a Text widget at a time. So let's say this is my contents:
(Assuming each time I put ("tag", text), I mean that text has the tag tag.)
("keyword", print) ("string", "Hello world!")
("keyword", print) ("string", "You are"), ("support", raw_input())
Now let's say that this is my code for each tag:
self.text.tag_config('keyword', foreground="orange")
self.text.tag_config('operator', foreground="blue")
self.text.tag_config('number', foreground="red")
self.text.tag_config('string', foreground="red")
self.text.tag_config('support', foreground="blue")
self.text.tag_config('comment', foreground="violet")
self.text.tag_config('error', background="red")
self.text.tag_config('warning', background="yellow")
Now, is there any function / constant to get only the tags currently within my string? It would report ['keyword', 'string', 'support'].
(Note: mostly I'm just wondering about this because I'm curious. It's not like it's the end of the world if there isn't. :P)
Notice: the second code block was written in Python and I'm hoping for an answer in Python. :)
From my favorite tkinter reference
.tag_names(index=None)
If you pass an index argument, this method returns a sequence of all the tag names that are associated with the character after that
index. If you pass no argument, you get a sequence of all the tag
names defined in the text widget.
.tag_ranges(tagName) lists the indexes where a particular tag is used.
I am using wxPython to build a wizard with PyWizardPages.
I'm wondering if there's a way to bold or italicize text "inline"?
In other words:
# StaticText
a = wx.StaticText(page, -1, "Click Next")
# TextCtrl
b = wx.TextCtrl(page2, -1, "")
b.SetValue("Here are the details:")
Now, say, I want to bold the "Next" and italicize "details." This is not kosher syntax but just something that I'd like to be able to do, if possible:
# Hypothetical way to inline bold
a = wx.StaticText(page, -1, "Click <b>Next</b>")
# Hypothetical way to inline italicize
b.SetValue("Here are the <i>details</i>:")
Is something like this possible or do I need to create a new StaticText/TextCtrl, bold and italicize them, and then figure out how to place it accordingly in the grid so it looks like it's one whole sentence?
The TextCtrl has a style flag called wx.TE_RICH and wx.TE_RICH2. Both of these are shown in the wxPython demo. I don't believe the StaticText widget will work for you. There is also a RichText widget that you could use or a StyleTextCtrl. Another alternative would be to draw the text onscreen yourself, which would give you the most control. There are examples of all of these topic in the wxPython demo, so I would start there.
so I've got this little Text widget with a scroll bar and I've got a question. How do I make text in this Text widget a variable ? If I made this text a variable I would be able to open a text file and edit it's text or save the text I've written, etc or maybe it's a wrong way that I'm approaching this, is there a better way to do this ?
There is no option to associate a variable with a text widget. You can achieve the same thing by using variable traces and widget bindings but it's rarely worth the effort.
The typical way to interact with the text widget is to read a file into a variable then use the insert method of the widget to put the text into the widget. Then, to save you just do the reverse -- get the text from the widget with the get method, and write the data to a file.
One tip: when you do a get, don't get the text from 1.0 to "end", use "end-1c" instead. If you specify "end" as the last character you'll get the implicit newline that tk always adds, meaning your text file will grow by one character each time you do a load/save cycle.