Is there a way to fractionally increase the spacing of lines in a tkinter text widget?
I'd like to space my text at, say, 1.2 * font size to enable the user to adjust for readability.
The spacing1, spacing2 and spacing3 parameters appear to be platform dependent, not supported on Windows, and whole lines only.
You can configure spacing in pixels as follows:
text.config(spacing1=10) # Spacing above the first line in a block of text
text.config(spacing2=10) # Spacing between the lines in a block of text
text.config(spacing3=10) # Spacing after the last line in a block of text
Works for me on Python 3.6.5 on win10. Or do you have an example of non-working code?
Related
I am creating a code editor as my project, and I think it is nice to have vertical lines under tabs so its easier for the coder. I want to draw a vertical line below tabs (I think the image below will be better to understand what I want, Just a screenshot from vs code):
Here you can see that there is a vertical line under def and I think these are pretty useful for me so that I won't make any indentation errors while I am coding. Now I want exactly a feature like this in my code editor. To simplify things I will upload a sample code below.
from tkinter import *
root = Tk()
txt = Text(root) # What changes do I have to make to this text widget so the lines appear like it does in the image
txt.pack()
root.mainloop()
The text widget doesn't directly support this. You can fake it by using ascii line drawing characters, but it would probably be a lot of work. It should be doable, though.
You can do this if you base your IDE on a canvas rather than a Text widget, but the text-editing ability of the canvas text item would be very cumbersome compared to the text widget.
All of that being said, with a little creativity you can get something close to what you want with tags. The idea is to add a tag to the character that you want to appear as a line. If you set the tag to have a different color than the text, it will look like a vertical line. The problem, however, is that you don't have much control over the width of the line. You might have some luck using the bgstipple option, which allows you to apply a bitmap to the region.
Here's an example to illustrate the idea.
import tkinter as tk
import tempfile
def add_markup(text, start=None, end="end"):
text.mark_set("current", start or "1.0")
text.tag_remove("markup", "current", end)
while text.compare("current", "<", end):
if text.get("current") == " ":
text.tag_add("markup", "current", "current+1c")
text.mark_set("current", "current+4c")
else:
text.mark_set("current", f"current +1l linestart")
root = tk.Tk()
text = tk.Text(root)
text.tag_configure("markup", background='#f0f0f0', bgstipple='#line.xbm', fgstipple='#line.xbm')
text.pack(fill="both", expand=True)
text.bind(
"<Any-KeyRelease>",
lambda event: add_markup(event.widget, "insert linestart", "insert lineend")
)
def load_this_file(text):
with open(__file__, "r") as f:
text.insert("1.0", f.read())
load_this_file(text)
add_markup(text)
root.mainloop()
This is what it looks like on my machine:
I found the possibility to make a stippled line in Python tkinter. (Seen here: Canvas Line Objects)
It states that I need a bitmap file and define stipple=bitmap_file
I tried this in:
# Import the required libraries
from tkinter import *
# Create an instance of tkinter frame or window
win=Tk()
# Set the size of the tkinter window
win.geometry("700x350")
# Create a canvas widget
canvas=Canvas(win, width=500, height=300)
canvas.pack()
# Add a line in canvas widget
canvas.create_line(100,200,200,35, stipple='#CheckedLine.bmp', fill='red', width=5)
win.mainloop()
However, the console then says:
_tkinter.TclError: error reading bitmap file "CheckedLine.bmp"
Can someone help?
The page linked to in the OP, also links to a detailed description of what they meant by a "bitmap", they never mention it to be a file but rather a bitmap.
stipple
To draw a stippled line, set this option to a bitmap that specifies
the stippling pattern, such as stipple='gray25'. See Section 5.7,
“Bitmaps” for the possible values.
Section 5.7 details about the files to be used -:
The graphic above shows Button widgets bearing the standard bitmaps.
From left to right, they are 'error', 'gray75', 'gray50', 'gray25',
'gray12', 'hourglass', 'info', 'questhead', 'question', and 'warning'.
You can use your own bitmaps. Any file in .xbm (X bit map) format will
work. In place of a standard bitmap name, use the string '#' followed
by the pathname of the .xbm file.
For more information on the .xbm format this may be useful.
Some image viewers/converters, e.g., XnView, FFmpeg and IrfanView,
support XBM. A 48×48 XBM can be converted to Ikon and eventually
X-Face with Netpbm tools.
ImageMagick supports converting images both to and from XBM. GIMP
may be used to create or modify images using the XBM format, and also
supports converting images to and from the XBM format.
NOTE:
Incase, you use the standard bitmaps as listed above and in the link provided, they render to look like this -:
I wanted change the all fonts in about 100 powerpoint files, without opening the files. There are several shape types in each slide and each might have a different font. I used python-pptx package and wrote the following code to change the fonts of all texts in a powerpoint presentation. Although it does not give any error, it does not work, and the fonts in the file are still whatever they were, for example Arial. I also added print(shape.text) to make sure that it has found all texts, and it seems that there is no issue there. Is it a bug? Or am I missing anything?
prs = Presentation('f10.pptx')
for i, slide in enumerate(prs.slides):
for shape in slide.shapes:
print (shape.has_text_frame)
if shape.has_text_frame:
print(shape.text)
for p in shape.text_frame.paragraphs:
for r in p.runs:
print(r.font.name)
r.font.name = 'Tahoma'
print(r.font.name)
prs.save('f10_tahoma.pptx')
Besides, it seems that the package does not work for utf-8 characters. I added a text-box on the last slide by adding:
text_frame = shape.text_frame
text_frame.clear() # not necessary for newly-created shape
p = text_frame.paragraphs[0]
run = p.add_run()
run.text = 'سلام '
font = run.font
font.name = 'Andalus'
font.size = Pt(18)
before saving the file to add a textbox with utf-8 characters. It adds it there, and when I check the font it shows that it is set to Andalus, but actually it is not Andalus.
With Aspose.Slides for Python via .NET, you can easily change all fonts for all texts in your presentations. The following code example shows you how to do this:
import aspose.slides as slides
with slides.Presentation('example.pptx') as presentation:
for slide in presentation.slides:
for shape in slide.shapes:
if isinstance(shape, slides.AutoShape):
for paragraph in shape.text_frame.paragraphs:
for portion in paragraph.portions:
portion.portion_format.latin_font = slides.FontData('Tahoma')
You can also evaluate Aspose.Slides Cloud SDK for Python for presentation manipulating. This REST-based API allows you to make 150 free API calls per month for API learning and presentation processing.
Aspose Slides Online Viewer can be used to view presentations without PowerPoint installed.
I work at Aspose.
What language is the text of the file? Run.font properties work fine for UTF-8, but there is a separate font for cursive scripts like Arabic. Access to that secondary font is not implemented in python-pptx unfortunately, but that could explain at least part of the behavior you're seeing.
For roman character text (like that we're using here), there are a couple things to check.
The font in question needs to be installed on the machine PowerPoint is running on when the document is opened. Otherwise PowerPoint will substitute a font.
The font (typeface) name used in the XML will not always exactly match what appears in the PowerPoint drop-down selection box. You need to give that name to python-pptx in the exact form it should appear in the XML. You may need to make an example file that works by hand, perhaps containing a single slide with a single textbox for simplicity, and then inspect the XML of that file to find the "spelling" used for that typeface by PowerPoint.
You could do that with code like this:
prs = Presentation("example.pptx")
shape = prs.slides[0].shapes[0]
print(shape._element.xml)
You should be able to locate the typeface name somewhere in an element like <p:rPr> or <p:defRPr>.
Just starting to try to use python-pptx, and have fallen at the first. Linux Mint 20.1, python 3.85, LibreOffice 6.4.
This is basically the 'Hello World' from the documentation.
from pptx import Presentation
from pptx.util import Inches, Pt
prs = Presentation()
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)
left = top = width = height = Inches(1)
txBox = slide.shapes.add_textbox(left, top, width, height)
tf = txBox.text_frame
print('before text ', txBox.left, txBox.top, txBox.width, txBox.height)
tf.text = "This is a long line of text inside a textbox"
print('after text ', txBox.left, txBox.top, txBox.width, txBox.height)
prs.save('test.pptx')
The text is more than a single line for the textbox. Printing out its bounds before and after text insertion shows that as far as python-pptx is concerned, the textbox width hasn't changed.
When the resulting presentation is viewed in LibreOffice, instead of wrapping the text within its boundaries, the textbox has expanded symmetrically around the mid point, pushing the start of the text off the lefthand edge of the page.
I was hoping the LibreOffice was only incompatible with powerpoint for rare edge cases, but text in text boxes is the meat and bread of presentations.
When I upload it to google slides, the text wraps within the left and right text box boundaries, but spills out of the bottom edge. The textbox shows up as 1" x 1" in the right place.
If I use onedrive.live.com, the text is left justified in the box and spills out of the righthand side without wrapping, and the textbox is shown as being 1" x 1" in the right place.
If I use onlinedocumentviewer.com, the display is the same as onedrive, though I can't get to see the text box.
Unfortunately I can't test the behaviour on a native powerpoint installation.
Maybe there's an autosize or fixed flag, which left unset leaves each viewer defaulting it in its own idiosyncratic way? How do we control text boxes / frames when targetting LibreOffice?
I possibly have a workaround to break up my text into single lines and use one per text box, but I'd rather understand the whether it can be done the proper way.
After some floundering around in the docs, I stumbled across the text_frame .word_wrap property. Setting to True gets the text to wrap in LibreOffice. While I was there, setting text_frame.auto_size = MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE reduces font size to get it all to fit in the box.
Is there a list of properties like .word_wrap in one place anywhere?
I am using tkinter.filedialog.askopenfilename in Python to select a file. How do I change the font size for the file list displayed? I have found answers on StackOverflow on how to change the font of some items on the display (for example here), but do not know the name of the ttk widget that is used for the file list.