Re: wraplength for tkinter.Label, from the NM Tech docs by John Shipman: "You can limit the number of characters in each line by setting this option to the desired number. The default value, 0, means that lines will be broken only at newlines." Other sources agree that the units for wraplength are characters.
The code below seems to be breaking the line as if the units of wraplength were pixels, not characters. If I set wraplength to 10, for example, the label displays a column of text one or two characters wide. If I set wraplength to 20, the lines are 3 or 4 characters long.
In my application, the user will be creating his own simple widgets for custom forms, and it would be better if the wraplength option used character count for units instead of whatever it is doing. Since the NMTech docs are for Tkinter 8.5, but 8.6 is what comes with my Python 3.5, maybe that explains the difference, but I don't see docs for 8.6.
But ideally, lines should wrap at the nearest space between words with wraplength just used as a maximum line length. So if the user has to type in his own \n anyway, wraplength seems useless to me.
Summary: in a GUI for users who will be inputing option values for their own simple widgets, 1) is there a way to get Tkinter to accept characters for wraplength units and 2) can I get the line to break at the nearest space short of the wraplength with wraplength used as a maximum line length only, instead of an absolute line length?
Thanks for any solutions or suggestions.
import tkinter as tk
root = tk.Tk()
sib = tk.Label(root, text='Give em hell Harry', wraplength=10)
sib.grid()
root.mainloop()
Is there a way to get Tkinter to accept characters for wraplength units
No, there is not. If you need wrapping to happen at word boundaries you can use a text widget rather than a label.
Unless specified otherwise, the units are in pixels. From the canonical tk documentation:
wraplength For widgets that can perform word-wrapping, this option specifies the maximum line length. Lines that would exceed this length are wrapped onto the next line, so that no line is longer than the specified length. The value may be specified in any of the standard forms for screen distances. If this value is less than or equal to 0 then no wrapping is done: lines will break only at newline characters in the text.
In the above text, "any of the standard forms for screen distances" refers to the fact that you can use a suffix to specify the distance in printers points (eg: "72p"), centimeters (eg: "2.54c"), millimeters (eg: "1000m"), or inches (eg: "1i")
This answer is two years later, but if anyone that sees it and needs to wrap text in a label based on characters or words, you could use the textwrap module. It's very useful if you don't want words to get cut-off between lines but still want to keep them in a label widget.
Related
Is there a way to get way to get an integer to a valid Tkinter text widget position. For example, 0 would get changed to '1.0' and if there were no characters on line 1, 1 would go to '2.0'. I am aware of the widget's index method however only to get the cursor position (in case this is the answer).
Many thanks
EDIT
I believe (having now done more research on the matter) that the Tk Text widget lazy loads the text (for performance). Therefore, without you getting the entire text contents and performing string actions on that, I don't think its possible (the Tk Text only has a minor understanding of what is above and below the currently viewed text - hence why a horizontal scrollbar will constantly adjust when scrolling vertically).
The text widget supports many modifiers to an index. For example, you can take an existing index and compute a new index by adding or subtracting characters or lines. For example, if you want to get the first 10 characters on line 2 you can use "2.0 + 10 chars" (or the more compact "2.0+10c"). If you want the 100th character in the text widget you can use "1.0+100c", etc.
In addition to characters, you can add or subtract lines (eg: "end-1line"), and you can get the start or end of a word or line (eg: "end-1c linestart" represents the first character of the last line in the widget).
You can read about all of the forms an index can take in the canonical tcl/tk documentation: http://tcl.tk/man/tcl8.5/TkCmd/text.htm#M7
I've been going through a tutorial on Python's Tkinter, I'm currently working with the Entry widget and just came across the insert method. I understand what the method does (makes a default string to appear in a text entry field), but what I don't get is the method's first parameter, which to the best of my understanding is the index at which the string should start. now here comes the confusion. When playing around with it, giving different values for the index parameter, every time I run it the text appears in the same spot (at the very beginning). So as best I can tell, I'm either doing something wrong or, I'm misunderstanding the documentation. this is a snippet from my code:
e1 = Entry(master)
e1.insert(0,"First Name")
When ever I run this, weather the index is 0, 10 or 100 the text "First Name" always appears at the very beginning of the text field
First, the statement "makes a default string appear" is not quite true. While it can be used to insert default text, it more correctly is described simply as inserting text, period. It can be default text, replacement text, additional text, whatever you want.
Any index that is before the first character is treated as 0 (zero). Any index that is after the last character is treated as being the end. When you insert something into an entry widget that is empty, every index is treated as 0. Thus, the index is mostly useful for inserting text somewhere into existing text.
For example:
e1 = Entry(master)
e1.insert(0, "hello")
e1.insert("end", "world")
e1.insert(5, ", ")
As an application programmer, you will almost never use the insert method with anything other than an index of 0 (zero) or "end", and perhaps "insert". However, when you try to add advanced functionality (eg: spell checking, auto-complete, etc) you will find the index to be highly useful.
In this line:
text.insert('1.0', 'here is my\ntext to insert')
The "1.0" here is the position where to insert the text, and can be read as "line 1, character 0". This refers to the first character of the first line. Historically, especially on Unix, programmers tend to think about line numbers as 1-based and character positions as 0-based.
The text to insert is just a string. Because the widget can hold multi-line text, the string we supply can be multi-line as well. To do this, simply embed \n (newline) characters in the string at the appropriate locations.
From the Tk docs https://tkdocs.com/tutorial/text.html
you use it when you use multiple insert() method
for example:
e = Entery(window)
e.pack()
e.insert(0, "Hi")
e.insert(2, " there")
Note : in " there" you should have a space behind it or else it will appear like this (Hithere)
I can not write on a standard Georgian language in the Text widget. instead of letters writes question marks .
when no tkinter, ie, when writing code, Georgian font recognized without problems. Plus, if I copy the word written in Georgian and inserted in the text widget, it is displayed correctly.
this is elementary code that displays the text box on the screen, where I want to write a word in Georgian.
import tkinter
root = tkinter.Tk()
txt = tkinter.Text(root)
txt.pack()
root.mainloop()
the first image shows how the word is displayed when the selected Georgian language.
the second shot, when I write in the code in Georgian, and define in advance the value of text field. in this case, the text in the field is displayed normally.
Okay, so here is how I achieved it:
First, make sure you have a Georgian font installed in your computer; if there is no any, then go download one (I downloaded mine from here);
Now, go to your tkinter program, and add your font to your Text widget:
txt = tkinter.Text(root, font=("AcadNusx", 16))
NOTE 1: My font name that supports Georgian is AcadNusx, but yours can be different;
NOTE 2: If you have not imported Font, then import it at the beginning of your program;
NOTE 3: Do not change your computer's font to Georgian, because you have already changed it inside the program, so make sure it is set to English.
The best answer I can determine so far is that there is something about Georgian and keyboard entry that tk does not like, at least not on Windows.
Character 'translation' is usually called 'transliteration'.
Tk text uses the Basic Multilingual Plane (the BMP, the first 2**16 codepoints) of Unicode. This includes the Georgian alphabet. The second image shows that the default Text widget font on your system is quite capable of displaying Georgian characters once the characters are in the widget. So a new display font does not seem to be the solution to your problem.
('ქართული ენა' is visible on Firefox because FF is unicode based and can display most if not all of the BMP.)
It looks like the problem is getting the proper codes to tk without going through your editor. What OS and editor are your using. How did you enter the mixed-alphabet line similar to
txt.insert('1.0', 'ქართული ენა') # ? (I cannot copy the image string.)
How are you running the Python code? If you cut the question marks from the first image and insert into
for c in '<insert here>': print(ord(c))
what do you see?
You need a 'Georgian keyboard entry' or 'input method' program (Google shows several) for your OS that will let you switch back and forth between sending ascii and Geargian codes to any program reading the keyboard.
Windows now comes with this, with languages activated on a case-by-case basis. I already had Spanish entry, and with it I can enter á and ñ both here and into IDLE and a fresh Text box. However, when I add Georgian, I can type (randomly ;-) ჰჯჰფგეუგსკფ here (in FireFox, also MS Edge) but only get ?????? in tk Text boxes. And these are actual ascii question marks, ord('?') = 63, rather that replacements for codes that cannot be represented. Japanese also works with tk-Text based IDLE. So the problem with Georgian is not generic to all non-latin alphabets.
I searched for creating aligned strings in Python and found some relevant stuff, but didn't work for me. Here's one example:
for line in [[1, 128, 1298039], [123388, 0, 2]]:
print('{:>8} {:>8} {:>8}'.format(*line))
Output:
1 128 1298039
123388 0 2
This is what I see in the shell:
As you can see, the alignment didn't happen. Same problem arises when using \t.
What can I do to align the strings in a neat, tabular format?
You have configured your IDLE shell to use a proportional font, one that uses different widths for different characters. Notice how the () pair takes almost the same amount of horizontal space as the > character above it.
Your code is otherwise entirely correct; with a fixed-width font the numbers will line up correctly.
Switch to using a fixed width font instead. Courier is a good default choice, but Windows has various other fonts installed that are proportional, including Consolas.
Configure the font in the Options -> Configure IDLE menu. Pick a different font from the Font Face list. The sample characters in the panel below should line up (except for the second line k at the end, it should stick out).
I have a TextCtrl in my wxPython program and I'd like to set its width to exactly 3 characters. However, the only way to set its size manually accepts only numbers of pixels. Is there any way to specify characters instead of pixels?
There doesn't seem to be a way. You can, however, use wxWindow::GetTextExtent. This is C++ code, but can be easily adapted to wxPython:
int x, y;
textCtrl->GetTextExtent(wxT("T"), &x, &y);
textCtrl->SetMinSize(wxSize(x * N + 10, -1));
textCtrl->SetMaxSize(wxSize(x * N + 10, -1));
/* re-layout the children*/
this->Layout();
/* alternative to Layout, will resize the parent to fit around the new
* size of the text control. */
this->GetSizer()->SetSizeHints(this);
this->Fit();
This is, you take the size of a reasonable width character (fonts may have variable width characters) and multiply it properly, adding some small value to account for native padding (say, 10px).
Realize that most fonts are proportional, which means that each character may take a different width. WWW and lll are both 3 characters, but they will require vastly different sizes of text box. Some fonts, such as Courier, are designed to be fixed width and will not have this problem. Unfortunately you may not have any control over which font is selected in the text box.
If you still want to try this, the key is to get the width of a character in pixels, multiply it by the number of characters, then add some padding for the borders around the characters. You may find this to be a good starting point:
http://docs.wxwidgets.org/stable/wx_wxdc.html#wxdcgetpartialtextextents
or, as litb suggests:
http://docs.wxwidgets.org/2.4/wx_wxwindow.html#wxwindowgettextextent