Hi @HannaBarbera. Iâve been working a lot with Vanilla + DrawBot + Glyphs lately, so Iâll try my hand at answering!
The purpose of setPDFDocument
is to update the DrawView with the latest version of the canvas/drawing. DrawBot starts a new drawing with newDrawing()
, then adds a page and some elements to it. But that drawing is hidden if youâre not using the DrawBot app (or the DrawBot window within Glyphs). The DrawView element self.w.drawBotCanvas
doesnât automatically receive and show the drawing that your script is putting together. In order to show it in the DrawView, the drawing has to be converted into PDF data with pdfImage()
, then passed to the DrawViewâs setPDFDocument
function. This process is only necessary because weâre working with a custom Vanilla window with its own DrawViewânot DrawBotâs own preview window.
Regarding your main question: the most common approach to saving an image would be to simply call saveImage()
on its own (not on an object), which will accept a file path string and some other optional parameters. That will export whatever your current DrawBot canvas/drawing isâwhich should meet your needs most of the time. This will even work with your Vanilla window example.
If you wanted to add a Save PDF button to the Vanilla window in your example, you could add a new method called, for example, saveIt()
that captures the current DrawBot drawing and exports it. Hereâs an updated demo, in which Iâve also changed/added a few lines near the top in order to add the button (lines 3, 11, and 12).
from drawBot import *
from drawBot.ui.drawView import DrawView
from vanilla import Window, Slider, Button
class DrawBotViewer(object):
def __init__(self):
# create a window
self.w = Window((400, 400), minSize=(200, 200))
# add a slider
self.w.slider = Slider((10, 10, -100, 22), callback=self.sliderCallback)
self.w.saveButton = Button((-90, 10, -10, 22), 'Save It', callback=self.saveIt)
# add a drawBox view
self.w.drawBotCanvas = DrawView((0, 40, -0, -0))
# draw something
self.drawIt()
# open the window
self.w.open()
def sliderCallback(self, sender):
# slider chagned so redraw it
self.drawIt()
def drawIt(self):
# get the value from the slider
value = self.w.slider.get()
print(value)
# initiate a new drawing
newDrawing()
# add a page
newPage(300, 300)
# set a fill color
fill(1, value/100., 0)
# draw a rectangle
rect(10, 10, 100, 100)
# set a font size
fontSize(48 + value)
# draw some text
text("Hello", (10, 120))
# get the pdf document
pdfData = pdfImage()
# set the pdf document into the canvas
self.w.drawBotCanvas.setPDFDocument(pdfData)
def saveIt(self, sender):
# Ask user to choose a file path and file name (ensures .pdf extension)
path = GetSaveFile(filetypes=['pdf'])
# if a file path was chosen, export the PDF there
if path:
saveImage( path )
DrawBotViewer()
From what I can tell, DrawBot wasnât really made to have users programmatically saving/exporting the contents of a DrawView. It is possible, but itâs not wrapped in friendly DrawBot methods (or documented), so Iâd try to avoid this approach. To do it, you could replace the saveImage( path )
line in the example above with this:
# (inside the if statement...)
# get the PDF data from the window's canvas
canvasAsPDF = self.w.drawBotCanvas.get()
# Save that data to a file path (should end in .pdf)
canvasAsPDF.writeToFile_atomically_( path , False)