Version of Canvas create_text() that supports word wrap? - python

Is there a create_text() mode or technique that supports word wrap? I'm stuck using create_text() vs. a Label or Text widget because I'm placing text on top of an image on my Canvas.
Also, is there a Tkinter API that truncates text that doesn't fit a certain width with an ellipsis like suffix, eg. Where very, very, very long text gets converted to something like Where very, very, ....

There is indeed a word wrap feature in create_text(). You'd call it like so:
canvas.create_text(x, y, width=80)
You can set the width parameter to whatever max length you want, or 0 if you want no word wrapping. See this article for all the options, arguments etc. for create_text().
I'm not sure about truncating text, but I did see this talking about a way to limit the length of input in an Entry widget...

Related

React Native Text custom ellipsis

I'm currently using React Native's Text component like this
<Text numberOfLines={2} ellipsizeMode="tail">Some long texts...</Text>
This renders texts like this
First line
Second line…
I'd like to use different ellipsis, for example,
Instead of
End of a long line...
It would be
End of a long line ...More
Currently, possible solutions would be:
Count the number of characters and cut the string then concatenate custom ellipsis.
Problem: Font's width differs per character.
Use ellipsizeMode="clip" and create absolutely positioned View with a custom ellipsis.
Problem: Can't programmatically tell when the Text is clipped.
Does anyone have a solution?

How do I double space a tkinter text widget without using extra newline characters?

I have a tkinter Text widget in which I want to display the contents of a dict as a reference. I have no trouble configuring the style of each item, but I'm not pleased with the display because the lines are too close together for me to read comfortably. I want to "double space" the list, but I don't want to add extra newline characters, as this would get confusing and could potentially screw up how tagged areas are displayed. Specifically, I want to space the lines out so that the following criteria are met:
no vertical space above the first line of the listing
no vertical space below the last line of the listing
a consistent vertical spacing I specify between the lines of the listing
the text widget is wide enough to contain all the text without wrapping
each line of the listing is separated from the next by exactly one newline character
each key and each value is separately tagged and configurable
Here's my current code:
import tkinter
dictionary = {
"test": "blue",
"test2": "red",
"test3": "green"
}
spacing = 30
root = tkinter.Tk()
text_widget = tkinter.Text(root)
text_widget.pack()
# "works" with this line, but don't want the side effect:
# text_widget.configure(width=5)
for index, (key, value) in enumerate(dictionary.items()):
text_widget.mark_set("begin", "insert")
text_widget.insert("insert", key+": ", (key,))
text_widget.insert("insert", value+"\n", (value,))
text_widget.tag_configure(key, font="courier 12 normal")
text_widget.tag_configure(value, foreground=value)
#corrected the starting index as per the comments
text_widget.tag_add("whole", "1.0", "end")
text_widget.tag_configure("whole", spacing2=spacing)
root.mainloop()
Though there are three spacing tag attributes that look like one of them should work for my case, none of them do. The spacing2 attribute comes frustratingly close, but according to https://www.tutorialspoint.com/python/tk_text.htm,
spacing2
This option specifies how much extra vertical space to add between displayed lines of text when a logical line wraps. Default is 0.
and this functionality doesn't seem particularly useful either, in my opinion.
Since I want to space all the text in the widget, it doesn't matter whether the solution is implemented at the tag level or widget-wide.
How can I put space between the lines of my listing according to the criteria given?
My expected output looks like this:
Python 3.8.2 Tkinter 8.6
Yyou need to use either spacing1 on all but the first line, or spacing3 on all but the last line. spacing1 defines how much space to add above each line, and spacing3 defines how much space to add below each line.
For example, this uses spacing1 on all but the first line:
text_widget.tag_add("whole", "2.0", "end-1c")
text_widget.tag_configure("whole", spacing1=spacing)

How can I limit text box width of QLineEdit to display at most four characters?

I am working with a GUI based on PySide. I made a (one line) text box with QLineEdit and the input is just four characters long, a restriction I already successfully applied.
The problem is I have a wider than needed text box (i.e. there is a lot of unused space after the text). How can I shorten the length of the text box?
I know this is something that is easily fixed by designing the text box with Designer; however, this particular text box is not created in Designer.
If what you want is modify your QLineEdit width and fix it, use:
#setFixedWidth(int w)
MyLineEdit.setFixedWidth(120)
Looking at the source of QLineEdit.sizeHint() one sees that a line edit is typically wide enough to display 17 latin "x" characters. I tried to replicate this in Python and change it to display 4 characters but I failed in getting the style dependent margins of the line edit correctly due to limitations of the Python binding of Qt.
A simple:
e = QtGui.QLineEdit()
fm = e.fontMetrics()
m = e.textMargins()
c = e.contentsMargins()
w = 4*fm.width('x')+m.left()+m.right()+c.left()+c.right()
is returning 24 in my case which however is not enough to display four characters like "abcd" in a QLineEdit. A better value would be about 32 which you can set for example like.
e.setMaximumWidth(w+8) # mysterious additional factor required
which might still be okay even if the font is changed on many systems.

Changing select sections of text to different colors in a tkinter text box?

First I would like to say I am not looking to take spacific words and change all words related to that tag. I am trying to do something akin to highlighting text in word and just changing the text color.
I have a program that will output the string stored in a dictionary by calling the key. I want to change sections of text color within the string but not necessarily all the iterations of that text.
I don't think tagging words would do the job for me as it would take a lot of time to define all the different words I want to change the color of and I do not want all words to be changed.
If it is possible to highlight the words and click a button to color the text as well as when I save the text to the library the text retains its color given. That is more along the lines of what I am trying to do.
Further more if it is possible to create some kind of rule that looks for a set of characters and then takes everything inside those characters and changes the color.
Could I write something that would read the data inside the dictionary and look for an identifier lets call it clrGr* and then look for a closing identifier, lets call it clrGr** and then any text or string inside the identifiers would have been changed to green. by calling a tag or something similar.
clrGr* Just random string of text between the identifiers clrGr**
What I get currently only lets me change all the color of the text.
Now what I want to do is have something like the following display in my tkinter text box.
Applying tags via regular expression
The text widget supports finding ranges of text specified by a regular expression.
Note: the expression must follow tcl regular expression syntax, which has some slight differences from python regular expressions.
For example:
import tkinter as tk
root = tk.Tk()
text = tk.Text(root)
text.pack(fill="both", expand=True)
text.tag_configure("highlight", foreground="green")
text.insert("1.0", '''
blah blah
blah clrGr* Just random string of text between the identifiers clrGr** blah
blah blah
''')
# this just highlights the first match, but you can put this code
# in a loop to highlight the whole file
char_count = tk.IntVar()
index = text.search(r'(?:clrGr\*).*(?:clrGr\*\*)', "1.0", "end", count=char_count, regexp=True)
# we have to adjust the character indexes to skip over the identifiers
if index != "":
start = "%s + 6 chars" % index
end = "%s + %d chars" % (index, char_count.get()-7)
text.tag_add("highlight", start, end)
root.mainloop()
Saving the color information
You can, however, call the dump method on a text widget to get a list of tuples that describe the content of the text widget. You can use this information to either write directly to a file (in a format that only your app will understand), or to convert the data to a known format.
The best description of what the dump method returns is described in the tcl/tk man pages: http://tcl.tk/man/tcl8.6/TkCmd/text.htm#M108

Tkinter Text widget spacing

With the widget Tkinter.Text (especially when I use big size fonts) I have too much white space before the first line of text.
How to reduce this font spacing with Text widget ?
More generally, can we set negative spacing in order to have very short spacing between multiple lines ?
Have you tried all of the available options? For example, the default for pady is probably 1, so setting that to 0 (zero) will free up one pixel. You might also want to double-check that the default value for spacing1 is 0 (zero) -- it should be, but it's possible that it's not.
Other than that, I'm not sure there's much you can do. I think most of that space is unique to whatever font you use, so maybe you can choose a different font that requires less space between each line.
There is a space for Unicode characters you personally do not know. Consider:
Ť goes above T in ŤT. The same as g goes under o in go

Categories