Creating Text Frames for Image Captions: Difference between revisions

From Scribus Wiki
Jump to navigation Jump to search
Line 278: Line 278:
         textf = scribus.createText(fx + fwidth, fy, cwidth, cheight)
         textf = scribus.createText(fx + fwidth, fy, cwidth, cheight)
</syntaxhighlight>
</syntaxhighlight>
Remember that everything entered into a '''valueDialog()''' is a string, so after splitting to 2 separate values, we then need to convert to '''float()''' since this is what '''createText()''' requires. Add the extra lines for the left caption also to complete the process, but note that it's a bit trickier, since the upper left corner of the caption frame depends on its width.
Remember that everything entered into a '''valueDialog()''' is a string, so after splitting to 2 separate values, we then need to convert to '''float()''' since this is what '''createText()''' requires. Add the extra lines for the left caption also to complete the process, but note that it's a bit trickier, since the upper left corner of the caption frame depends on its width and height.
<syntaxhighlight lang=python>
<syntaxhighlight lang=python>
     elif location == "L":
     elif location == "L":
Line 285: Line 285:
         cwidth = float(cwidth)
         cwidth = float(cwidth)
         cheight = float(cheight)
         cheight = float(cheight)
         textf = scribus.createText(fx-cwidth, fy + fheight - 40, cwidth, cheight)
         textf = scribus.createText(fx-cwidth, fy + fheight - cheight, cwidth, cheight)
</syntaxhighlight>
</syntaxhighlight>

Revision as of 18:14, 5 January 2017

This article is part of the Scripts series.

Here is a series of scripts which accomplish the simple task of creating a caption frame for images. You can either do frames one-by-one, or select a number of frames as long as you want the captions in the same position relative to the image.

I tend to prefer simple scripts, with little or no input needed, which is why I made individual scripts for each position, but at the bottom, I'll show how to create one script which needs input to state which position to place the caption. The sizes and positions of frames can be changed according to your needs, and like any frame, can be edited afterward. Your page units don't matter, since the script converts to points and uses points, then switches back again.

In usage, this would be a situation where you could save time be creating a caption Paragraph Style for the caption frames. One thing to notice is that the scripts do not check for object type, so you can create "captions" for any object, such as shapes, text frames, render frames, vector graphics, or even groups of objects (make sure you actually group them, since if you just select a number of objects, each one will get its own caption).

Image captions.png

bcaption.py

#!/usr/bin/env python
# -*- coding: utf-8  -*-
"""

© 2017 Gregory Pittman

bcaption.py

Creates a text frame (caption) below one or more selected frames.

"""
try:
    import scribus
except ImportError:
    print "Unable to import the 'scribus' module. This script will only run within"
    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
    sys.exit(1)

numselect = scribus.selectionCount()
count = 0
frames = []

if numselect == 0:
    scribus.messageBox('Selection Count', "You must have at least one image frame selected",
                       scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
pageunits = scribus.getUnit()
scribus.setUnit(scribus.UNIT_POINTS)

while count < numselect:
    frames.append(scribus.getSelectedObject(count))
    count += 1
    
for frame in frames:
    fwidth, fheight = scribus.getSize(frame)
    fx, fy = scribus.getPosition(frame)
    textf = scribus.createText(fx, fy+fheight, fwidth, 24)
    
scribus.setUnit(pageunits)

scribus.setRedraw(True)

tcaption.py

#!/usr/bin/env python
# -*- coding: utf-8  -*-

"""

© 2017 Gregory Pittman

tcaption.py

Creates a text frame (caption) above one or more selected frames.

"""

try:
    import scribus
except ImportError:
    print "Unable to import the 'scribus' module. This script will only run within"
    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
    sys.exit(1)

numselect = scribus.selectionCount()
count = 0
frames = []

if numselect == 0:
    scribus.messageBox('Selection Count', "You must have at least one image frame selected",
                       scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
pageunits = scribus.getUnit()
scribus.setUnit(scribus.UNIT_POINTS)
                
while count < numselect:
    frames.append(scribus.getSelectedObject(count))
    count += 1
    
for frame in frames:
    fwidth, fheight = scribus.getSize(frame)
    fx, fy = scribus.getPosition(frame)
    textf = scribus.createText(fx, fy-24, fwidth, 24) # frame height set at 24 points
    
scribus.setUnit(pageunits)

scribus.setRedraw(True)

rcaption.py

#!/usr/bin/env python
# -*- coding: utf-8  -*-

"""

© 2017 Gregory Pittman

rcaption.py

Creates a text frame (caption) to the right of one or more selected frames.

"""

try:
    import scribus
except ImportError:
    print "Unable to import the 'scribus' module. This script will only run within"
    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
    sys.exit(1)

numselect = scribus.selectionCount()
count = 0
frames = []

if numselect == 0:
    scribus.messageBox('Selection Count', "You must have at least one image frame selected",
                       scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
pageunits = scribus.getUnit()
scribus.setUnit(scribus.UNIT_POINTS)

while count < numselect:
    frames.append(scribus.getSelectedObject(count))
    count += 1
    
for frame in frames:
    fwidth, fheight = scribus.getSize(frame)
    fx, fy = scribus.getPosition(frame)
    textf = scribus.createText(fx + fwidth, fy, 150, 40)
    
scribus.setRedraw(True)

lcaption.py

#!/usr/bin/env python
# -*- coding: utf-8  -*-

"""

© 2017 Gregory Pittman

lcaption.py

Creates a text frame (caption) to the left of one or more selected frames.

"""

try:
    import scribus
except ImportError:
    print "Unable to import the 'scribus' module. This script will only run within"
    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
    sys.exit(1)

numselect = scribus.selectionCount()
count = 0
frames = []

if numselect == 0:
    scribus.messageBox('Selection Count', "You must have at least one image frame selected",
                       scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
pageunits = scribus.getUnit()
scribus.setUnit(scribus.UNIT_POINTS)


while count < numselect:
    frames.append(scribus.getSelectedObject(count))
    count += 1
    
for frame in frames:
    fwidth, fheight = scribus.getSize(frame)
    fx, fy = scribus.getPosition(frame)
    textf = scribus.createText(fx-150, fy + fheight - 40, 150, 40)
    
scribus.setUnit(pageunits)

scribus.setRedraw(True)

caption.py

Here is one more script which incorporates all the above options, by allowing you to choose position in a dialog. If you enter something other than b/t/r/l it shouldn't do anything.

#!/usr/bin/env python
# -*- coding: utf-8  -*-

"""

© 2017 Gregory Pittman

caption.py

Creates a text frame (caption) in selected location relative to 
one or more selected frames.

"""

try:
    import scribus
except ImportError:
    print "Unable to import the 'scribus' module. This script will only run within"
    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
    sys.exit(1)

numselect = scribus.selectionCount()
count = 0
frames = []

if numselect == 0:
    scribus.messageBox('Selection Count', "You must have at least one image frame selected",
                       scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)

captionloc = scribus.valueDialog("Caption Location","Where to put the caption(s) -\n B/T/R/L?", "b")
captionloc = captionloc[0]
location = captionloc.upper()

pageunits = scribus.getUnit()
scribus.setUnit(scribus.UNIT_POINTS)

while count < numselect:
    frames.append(scribus.getSelectedObject(count))
    count += 1
    
for frame in frames:
    fwidth, fheight = scribus.getSize(frame)
    fx, fy = scribus.getPosition(frame)
    if location == "B":
        textf = scribus.createText(fx, fy+fheight, fwidth, 24)# frame height set at 24 points
    elif location == "T":
        textf = scribus.createText(fx, fy-24, fwidth, 24) # frame height set at 24 points
    elif location == "R":
        textf = scribus.createText(fx + fwidth, fy, 150, 40)# frame width set at 150, height at 40 points
    elif location == "L":
        textf = scribus.createText(fx-150, fy + fheight - 40, 150, 40) # frame width set at 150, height at 40 points

scribus.setUnit(pageunits)

scribus.setRedraw(True)

Additional mods

In case you would like to set the width and height of the right and left captions, you might add the possibility of entering values. I'm going to use a single valueDialog() for this, then use the python .split operator. Here is the original script section:

    elif location == "R":
        textf = scribus.createText(fx + fwidth, fy, 150, 40)# frame width set at 150, height at 40 points

Let's change it to this by adding four lines, and use the variables instead of numbers in the createText() command:

    elif location == "R":
        cdimensions = scribus.valueDialog("Width/Height of Caption","Enter the width and height of the caption,\n in points (only space between values)", "150 40")
        cwidth, cheight = cdimensions.split()
        cwidth = float(cwidth)
        cheight = float(cheight)
        textf = scribus.createText(fx + fwidth, fy, cwidth, cheight)

Remember that everything entered into a valueDialog() is a string, so after splitting to 2 separate values, we then need to convert to float() since this is what createText() requires. Add the extra lines for the left caption also to complete the process, but note that it's a bit trickier, since the upper left corner of the caption frame depends on its width and height.

    elif location == "L":
        cdimensions = scribus.valueDialog("Width/Height of Caption","Enter the width and height of the caption,\n in points (only space between values)", "150 40")
        cwidth, cheight = cdimensions.split()
        cwidth = float(cwidth)
        cheight = float(cheight)
        textf = scribus.createText(fx-cwidth, fy + fheight - cheight, cwidth, cheight)