Preview a PDF file and choose printer before actually printing the document



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















I am currently developing an application in Python3/tkinter that will run primarily on Macs and will need to print PDF files.



In the past, I have managed to send PDF files to printer automatically by using some commands in a bash script, so I think I could end up using that approach as a last resort.



However, I never found a way to specify one printer, it would always send it right into the currently selected printer (usually the last used one). The problem is that all those computers are connected to more that one printer, and some of the printers are not suitable for A4 documents (for instance, label printers).



Does anyone know if there is any way to launch the Preview application from command line, or any external module that allows us to preview and choose printers before actually printing?










share|improve this question
























  • In my Bash scripts, I use for instance pdfsplit $FILENAME 3 |lpr to print page 3 of a PDF file coming from the previous action. I can also specify more pages, adding their numbers with a space between each of them.

    – Victor Domingos
    Mar 14 '17 at 11:01






  • 1





    Hmm would letting the user print the pdf by themselves work as well? You could open it using webbrowser and let your user review and print it themselves...

    – Nearoo
    Mar 14 '17 at 11:05











  • @Nearoo is there a URL Scheme for the Preview app? Or would I have to launch a browser and print from there?

    – Victor Domingos
    Mar 14 '17 at 12:10











  • The latter would be the case. But I see someone already posted a better answer.

    – Nearoo
    Mar 15 '17 at 12:21

















1















I am currently developing an application in Python3/tkinter that will run primarily on Macs and will need to print PDF files.



In the past, I have managed to send PDF files to printer automatically by using some commands in a bash script, so I think I could end up using that approach as a last resort.



However, I never found a way to specify one printer, it would always send it right into the currently selected printer (usually the last used one). The problem is that all those computers are connected to more that one printer, and some of the printers are not suitable for A4 documents (for instance, label printers).



Does anyone know if there is any way to launch the Preview application from command line, or any external module that allows us to preview and choose printers before actually printing?










share|improve this question
























  • In my Bash scripts, I use for instance pdfsplit $FILENAME 3 |lpr to print page 3 of a PDF file coming from the previous action. I can also specify more pages, adding their numbers with a space between each of them.

    – Victor Domingos
    Mar 14 '17 at 11:01






  • 1





    Hmm would letting the user print the pdf by themselves work as well? You could open it using webbrowser and let your user review and print it themselves...

    – Nearoo
    Mar 14 '17 at 11:05











  • @Nearoo is there a URL Scheme for the Preview app? Or would I have to launch a browser and print from there?

    – Victor Domingos
    Mar 14 '17 at 12:10











  • The latter would be the case. But I see someone already posted a better answer.

    – Nearoo
    Mar 15 '17 at 12:21













1












1








1


2






I am currently developing an application in Python3/tkinter that will run primarily on Macs and will need to print PDF files.



In the past, I have managed to send PDF files to printer automatically by using some commands in a bash script, so I think I could end up using that approach as a last resort.



However, I never found a way to specify one printer, it would always send it right into the currently selected printer (usually the last used one). The problem is that all those computers are connected to more that one printer, and some of the printers are not suitable for A4 documents (for instance, label printers).



Does anyone know if there is any way to launch the Preview application from command line, or any external module that allows us to preview and choose printers before actually printing?










share|improve this question
















I am currently developing an application in Python3/tkinter that will run primarily on Macs and will need to print PDF files.



In the past, I have managed to send PDF files to printer automatically by using some commands in a bash script, so I think I could end up using that approach as a last resort.



However, I never found a way to specify one printer, it would always send it right into the currently selected printer (usually the last used one). The problem is that all those computers are connected to more that one printer, and some of the printers are not suitable for A4 documents (for instance, label printers).



Does anyone know if there is any way to launch the Preview application from command line, or any external module that allows us to preview and choose printers before actually printing?







python macos printing tkinter printers






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 14 '17 at 11:00







Victor Domingos

















asked Mar 14 '17 at 9:18









Victor DomingosVictor Domingos

504525




504525












  • In my Bash scripts, I use for instance pdfsplit $FILENAME 3 |lpr to print page 3 of a PDF file coming from the previous action. I can also specify more pages, adding their numbers with a space between each of them.

    – Victor Domingos
    Mar 14 '17 at 11:01






  • 1





    Hmm would letting the user print the pdf by themselves work as well? You could open it using webbrowser and let your user review and print it themselves...

    – Nearoo
    Mar 14 '17 at 11:05











  • @Nearoo is there a URL Scheme for the Preview app? Or would I have to launch a browser and print from there?

    – Victor Domingos
    Mar 14 '17 at 12:10











  • The latter would be the case. But I see someone already posted a better answer.

    – Nearoo
    Mar 15 '17 at 12:21

















  • In my Bash scripts, I use for instance pdfsplit $FILENAME 3 |lpr to print page 3 of a PDF file coming from the previous action. I can also specify more pages, adding their numbers with a space between each of them.

    – Victor Domingos
    Mar 14 '17 at 11:01






  • 1





    Hmm would letting the user print the pdf by themselves work as well? You could open it using webbrowser and let your user review and print it themselves...

    – Nearoo
    Mar 14 '17 at 11:05











  • @Nearoo is there a URL Scheme for the Preview app? Or would I have to launch a browser and print from there?

    – Victor Domingos
    Mar 14 '17 at 12:10











  • The latter would be the case. But I see someone already posted a better answer.

    – Nearoo
    Mar 15 '17 at 12:21
















In my Bash scripts, I use for instance pdfsplit $FILENAME 3 |lpr to print page 3 of a PDF file coming from the previous action. I can also specify more pages, adding their numbers with a space between each of them.

– Victor Domingos
Mar 14 '17 at 11:01





In my Bash scripts, I use for instance pdfsplit $FILENAME 3 |lpr to print page 3 of a PDF file coming from the previous action. I can also specify more pages, adding their numbers with a space between each of them.

– Victor Domingos
Mar 14 '17 at 11:01




1




1





Hmm would letting the user print the pdf by themselves work as well? You could open it using webbrowser and let your user review and print it themselves...

– Nearoo
Mar 14 '17 at 11:05





Hmm would letting the user print the pdf by themselves work as well? You could open it using webbrowser and let your user review and print it themselves...

– Nearoo
Mar 14 '17 at 11:05













@Nearoo is there a URL Scheme for the Preview app? Or would I have to launch a browser and print from there?

– Victor Domingos
Mar 14 '17 at 12:10





@Nearoo is there a URL Scheme for the Preview app? Or would I have to launch a browser and print from there?

– Victor Domingos
Mar 14 '17 at 12:10













The latter would be the case. But I see someone already posted a better answer.

– Nearoo
Mar 15 '17 at 12:21





The latter would be the case. But I see someone already posted a better answer.

– Nearoo
Mar 15 '17 at 12:21












1 Answer
1






active

oldest

votes


















1














Here's a program I've just created that allows you to select a printer and print.



import tkinter as tk
from tkinter.filedialog import askopenfilename
import subprocess
from pprint import pprint
import platform
import sys

def which(program):
# http://stackoverflow.com/a/377028/3924118
import os
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file

return None


class FilePrinterDialog(tk.Toplevel):

def __init__(self, root, *args, **kwargs):
tk.Toplevel.__init__(self, root, *args, **kwargs)
self.root = root

self.body = tk.Frame(self, bg="lightblue")
self.body.pack(expand=True, fill="both")

self.title_frame = tk.Frame(self.body, pady=5)
self.title_frame.pack(fill="both", pady=(15, 5))

self.title = tk.Label(self.title_frame, text="Let's print!")
self.title.pack(fill="x")

# Current selected printer of your system
self.system_default_destination = self._find_system_default_destination()

# Finds printer names
self.printers_names = self._find_printers_names()

self.selected_file = None # To hold the selected file's name
self.data_bytes = None # Bytes read from the selected file to print
self.selected_printer = None # Hols name of selected printer

# Display them
self.printers_frame = tk.Frame(self.body, bg="lightblue", padx=10, pady=10)
self.printers_frame.pack(expand=True, fill="both")
self._display_printers()

self.bottom_frame = tk.Frame(self.body, pady=5)
self.bottom_frame.pack(fill="both", pady=(5, 16))
self.open_file_chooser = tk.Button(self.bottom_frame,
text="Open file chooser",
command=self._select_file)
self.open_file_chooser.pack(side="left", padx=10)

self.print_file = tk.Button(self.bottom_frame,
text="Print",
command=self._print_selected_file)
self.print_file.pack(side="right", padx=10)


self._make_modal()

def _read_file(self):
# NOT USED!
if not self.selected_file:
raise ValueError("No file chosen")
with open(self.selected_file, "rb") as in_file: # opening for [r]eading as [b]inary
return in_file.read() # if you only wanted to read 512 bytes, do .read(512)

def _print_selected_file(self):
if not self.selected_file:
print("No file selected yet!")
else:
subprocess.call(["lpr", self.selected_file])

def _select_file(self):
self.selected_file = askopenfilename(title = "Choose file to print")
print(self.selected_file)

def _on_listbox_selection(self, event):
self.selected_printer = self._find_current_selected_printer()

# Sets the printer on your system
subprocess.call(["lpoptions", "-d", self.selected_printer])
print("Selected printer:", self.selected_printer)

def _find_current_selected_printer(self):
curselection = self.listbox.curselection()
if len(curselection) > 0:
return self.listbox.get(curselection[0])
else:
return None

def _display_printers(self):
self.scrollbar = tk.Scrollbar(self.printers_frame)
self.scrollbar.pack(side="right", fill="y")

self.listbox = tk.Listbox(self.printers_frame,
yscrollcommand=self.scrollbar.set,
selectbackground="yellow",
selectmode="single",
height=6)

for printer_name in self.printers_names:
self.listbox.insert("end", printer_name)

# Keep track of selected listbox
self.listbox.bind("<<ListboxSelect>>", self._on_listbox_selection)

# Sets first listbox as selected
self.listbox.select_set(0) # Sets focus
self.listbox.event_generate("<<ListboxSelect>>")

self.listbox.pack(side="left", fill="both", expand=True)
self.scrollbar.config(command=self.listbox.yview)

def _find_system_default_destination(self):
return subprocess.getoutput("lpstat -d").split(": ")[1]

def _find_printers_names(self):
# Command to obtain printer names based on: https://superuser.com/a/1016825/317323
return subprocess.getoutput("lpstat -a | awk 'print $1'").split("n")

def _make_modal(self):
# Makes the window modal
self.transient(self.root)
self.grab_set()
self.wait_window(self)


if __name__ == "__main__":
if not which("lpoptions") or not which("lpr") or not which("awk") or not which("lpstat"):
sys.stderr.write("Requirements: lopotions, lpr, lpstat and awk not satisfied")
else:
root = tk.Tk()
opener = tk.Button(root, text="Open printer chooser", command=lambda: FilePrinterDialog(root))
opener.pack()
root.mainloop()


This program only works if you have the required dependencies which I specify in the program. You should have those since I'm also on a Mac OS X (Sierra).



I've tested only with a .py file. Unfortunately, the format of the printed documented isn't really as desired (since I'm not really an expert on how to use lpr to print files), but you can check the options of lpr and see what you can do with it.



Also, I've not created any preview of the selected file, but you may achieve this using PIL (at least for images)...



Note: be careful, do not click 100 times on the print button, otherwise you will have 100 files in the queue to be printed! You may want to fix this somehow.






share|improve this answer

























  • Seems to be what I am looking for. I will study that code! :)

    – Victor Domingos
    Mar 14 '17 at 12:59






  • 1





    @VictorDomingos Nice! Make me know if there are any problems and we can eventually improve the program (maybe also for future users) ;)

    – nbro
    Mar 14 '17 at 13:01











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f42781944%2fpreview-a-pdf-file-and-choose-printer-before-actually-printing-the-document%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Here's a program I've just created that allows you to select a printer and print.



import tkinter as tk
from tkinter.filedialog import askopenfilename
import subprocess
from pprint import pprint
import platform
import sys

def which(program):
# http://stackoverflow.com/a/377028/3924118
import os
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file

return None


class FilePrinterDialog(tk.Toplevel):

def __init__(self, root, *args, **kwargs):
tk.Toplevel.__init__(self, root, *args, **kwargs)
self.root = root

self.body = tk.Frame(self, bg="lightblue")
self.body.pack(expand=True, fill="both")

self.title_frame = tk.Frame(self.body, pady=5)
self.title_frame.pack(fill="both", pady=(15, 5))

self.title = tk.Label(self.title_frame, text="Let's print!")
self.title.pack(fill="x")

# Current selected printer of your system
self.system_default_destination = self._find_system_default_destination()

# Finds printer names
self.printers_names = self._find_printers_names()

self.selected_file = None # To hold the selected file's name
self.data_bytes = None # Bytes read from the selected file to print
self.selected_printer = None # Hols name of selected printer

# Display them
self.printers_frame = tk.Frame(self.body, bg="lightblue", padx=10, pady=10)
self.printers_frame.pack(expand=True, fill="both")
self._display_printers()

self.bottom_frame = tk.Frame(self.body, pady=5)
self.bottom_frame.pack(fill="both", pady=(5, 16))
self.open_file_chooser = tk.Button(self.bottom_frame,
text="Open file chooser",
command=self._select_file)
self.open_file_chooser.pack(side="left", padx=10)

self.print_file = tk.Button(self.bottom_frame,
text="Print",
command=self._print_selected_file)
self.print_file.pack(side="right", padx=10)


self._make_modal()

def _read_file(self):
# NOT USED!
if not self.selected_file:
raise ValueError("No file chosen")
with open(self.selected_file, "rb") as in_file: # opening for [r]eading as [b]inary
return in_file.read() # if you only wanted to read 512 bytes, do .read(512)

def _print_selected_file(self):
if not self.selected_file:
print("No file selected yet!")
else:
subprocess.call(["lpr", self.selected_file])

def _select_file(self):
self.selected_file = askopenfilename(title = "Choose file to print")
print(self.selected_file)

def _on_listbox_selection(self, event):
self.selected_printer = self._find_current_selected_printer()

# Sets the printer on your system
subprocess.call(["lpoptions", "-d", self.selected_printer])
print("Selected printer:", self.selected_printer)

def _find_current_selected_printer(self):
curselection = self.listbox.curselection()
if len(curselection) > 0:
return self.listbox.get(curselection[0])
else:
return None

def _display_printers(self):
self.scrollbar = tk.Scrollbar(self.printers_frame)
self.scrollbar.pack(side="right", fill="y")

self.listbox = tk.Listbox(self.printers_frame,
yscrollcommand=self.scrollbar.set,
selectbackground="yellow",
selectmode="single",
height=6)

for printer_name in self.printers_names:
self.listbox.insert("end", printer_name)

# Keep track of selected listbox
self.listbox.bind("<<ListboxSelect>>", self._on_listbox_selection)

# Sets first listbox as selected
self.listbox.select_set(0) # Sets focus
self.listbox.event_generate("<<ListboxSelect>>")

self.listbox.pack(side="left", fill="both", expand=True)
self.scrollbar.config(command=self.listbox.yview)

def _find_system_default_destination(self):
return subprocess.getoutput("lpstat -d").split(": ")[1]

def _find_printers_names(self):
# Command to obtain printer names based on: https://superuser.com/a/1016825/317323
return subprocess.getoutput("lpstat -a | awk 'print $1'").split("n")

def _make_modal(self):
# Makes the window modal
self.transient(self.root)
self.grab_set()
self.wait_window(self)


if __name__ == "__main__":
if not which("lpoptions") or not which("lpr") or not which("awk") or not which("lpstat"):
sys.stderr.write("Requirements: lopotions, lpr, lpstat and awk not satisfied")
else:
root = tk.Tk()
opener = tk.Button(root, text="Open printer chooser", command=lambda: FilePrinterDialog(root))
opener.pack()
root.mainloop()


This program only works if you have the required dependencies which I specify in the program. You should have those since I'm also on a Mac OS X (Sierra).



I've tested only with a .py file. Unfortunately, the format of the printed documented isn't really as desired (since I'm not really an expert on how to use lpr to print files), but you can check the options of lpr and see what you can do with it.



Also, I've not created any preview of the selected file, but you may achieve this using PIL (at least for images)...



Note: be careful, do not click 100 times on the print button, otherwise you will have 100 files in the queue to be printed! You may want to fix this somehow.






share|improve this answer

























  • Seems to be what I am looking for. I will study that code! :)

    – Victor Domingos
    Mar 14 '17 at 12:59






  • 1





    @VictorDomingos Nice! Make me know if there are any problems and we can eventually improve the program (maybe also for future users) ;)

    – nbro
    Mar 14 '17 at 13:01















1














Here's a program I've just created that allows you to select a printer and print.



import tkinter as tk
from tkinter.filedialog import askopenfilename
import subprocess
from pprint import pprint
import platform
import sys

def which(program):
# http://stackoverflow.com/a/377028/3924118
import os
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file

return None


class FilePrinterDialog(tk.Toplevel):

def __init__(self, root, *args, **kwargs):
tk.Toplevel.__init__(self, root, *args, **kwargs)
self.root = root

self.body = tk.Frame(self, bg="lightblue")
self.body.pack(expand=True, fill="both")

self.title_frame = tk.Frame(self.body, pady=5)
self.title_frame.pack(fill="both", pady=(15, 5))

self.title = tk.Label(self.title_frame, text="Let's print!")
self.title.pack(fill="x")

# Current selected printer of your system
self.system_default_destination = self._find_system_default_destination()

# Finds printer names
self.printers_names = self._find_printers_names()

self.selected_file = None # To hold the selected file's name
self.data_bytes = None # Bytes read from the selected file to print
self.selected_printer = None # Hols name of selected printer

# Display them
self.printers_frame = tk.Frame(self.body, bg="lightblue", padx=10, pady=10)
self.printers_frame.pack(expand=True, fill="both")
self._display_printers()

self.bottom_frame = tk.Frame(self.body, pady=5)
self.bottom_frame.pack(fill="both", pady=(5, 16))
self.open_file_chooser = tk.Button(self.bottom_frame,
text="Open file chooser",
command=self._select_file)
self.open_file_chooser.pack(side="left", padx=10)

self.print_file = tk.Button(self.bottom_frame,
text="Print",
command=self._print_selected_file)
self.print_file.pack(side="right", padx=10)


self._make_modal()

def _read_file(self):
# NOT USED!
if not self.selected_file:
raise ValueError("No file chosen")
with open(self.selected_file, "rb") as in_file: # opening for [r]eading as [b]inary
return in_file.read() # if you only wanted to read 512 bytes, do .read(512)

def _print_selected_file(self):
if not self.selected_file:
print("No file selected yet!")
else:
subprocess.call(["lpr", self.selected_file])

def _select_file(self):
self.selected_file = askopenfilename(title = "Choose file to print")
print(self.selected_file)

def _on_listbox_selection(self, event):
self.selected_printer = self._find_current_selected_printer()

# Sets the printer on your system
subprocess.call(["lpoptions", "-d", self.selected_printer])
print("Selected printer:", self.selected_printer)

def _find_current_selected_printer(self):
curselection = self.listbox.curselection()
if len(curselection) > 0:
return self.listbox.get(curselection[0])
else:
return None

def _display_printers(self):
self.scrollbar = tk.Scrollbar(self.printers_frame)
self.scrollbar.pack(side="right", fill="y")

self.listbox = tk.Listbox(self.printers_frame,
yscrollcommand=self.scrollbar.set,
selectbackground="yellow",
selectmode="single",
height=6)

for printer_name in self.printers_names:
self.listbox.insert("end", printer_name)

# Keep track of selected listbox
self.listbox.bind("<<ListboxSelect>>", self._on_listbox_selection)

# Sets first listbox as selected
self.listbox.select_set(0) # Sets focus
self.listbox.event_generate("<<ListboxSelect>>")

self.listbox.pack(side="left", fill="both", expand=True)
self.scrollbar.config(command=self.listbox.yview)

def _find_system_default_destination(self):
return subprocess.getoutput("lpstat -d").split(": ")[1]

def _find_printers_names(self):
# Command to obtain printer names based on: https://superuser.com/a/1016825/317323
return subprocess.getoutput("lpstat -a | awk 'print $1'").split("n")

def _make_modal(self):
# Makes the window modal
self.transient(self.root)
self.grab_set()
self.wait_window(self)


if __name__ == "__main__":
if not which("lpoptions") or not which("lpr") or not which("awk") or not which("lpstat"):
sys.stderr.write("Requirements: lopotions, lpr, lpstat and awk not satisfied")
else:
root = tk.Tk()
opener = tk.Button(root, text="Open printer chooser", command=lambda: FilePrinterDialog(root))
opener.pack()
root.mainloop()


This program only works if you have the required dependencies which I specify in the program. You should have those since I'm also on a Mac OS X (Sierra).



I've tested only with a .py file. Unfortunately, the format of the printed documented isn't really as desired (since I'm not really an expert on how to use lpr to print files), but you can check the options of lpr and see what you can do with it.



Also, I've not created any preview of the selected file, but you may achieve this using PIL (at least for images)...



Note: be careful, do not click 100 times on the print button, otherwise you will have 100 files in the queue to be printed! You may want to fix this somehow.






share|improve this answer

























  • Seems to be what I am looking for. I will study that code! :)

    – Victor Domingos
    Mar 14 '17 at 12:59






  • 1





    @VictorDomingos Nice! Make me know if there are any problems and we can eventually improve the program (maybe also for future users) ;)

    – nbro
    Mar 14 '17 at 13:01













1












1








1







Here's a program I've just created that allows you to select a printer and print.



import tkinter as tk
from tkinter.filedialog import askopenfilename
import subprocess
from pprint import pprint
import platform
import sys

def which(program):
# http://stackoverflow.com/a/377028/3924118
import os
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file

return None


class FilePrinterDialog(tk.Toplevel):

def __init__(self, root, *args, **kwargs):
tk.Toplevel.__init__(self, root, *args, **kwargs)
self.root = root

self.body = tk.Frame(self, bg="lightblue")
self.body.pack(expand=True, fill="both")

self.title_frame = tk.Frame(self.body, pady=5)
self.title_frame.pack(fill="both", pady=(15, 5))

self.title = tk.Label(self.title_frame, text="Let's print!")
self.title.pack(fill="x")

# Current selected printer of your system
self.system_default_destination = self._find_system_default_destination()

# Finds printer names
self.printers_names = self._find_printers_names()

self.selected_file = None # To hold the selected file's name
self.data_bytes = None # Bytes read from the selected file to print
self.selected_printer = None # Hols name of selected printer

# Display them
self.printers_frame = tk.Frame(self.body, bg="lightblue", padx=10, pady=10)
self.printers_frame.pack(expand=True, fill="both")
self._display_printers()

self.bottom_frame = tk.Frame(self.body, pady=5)
self.bottom_frame.pack(fill="both", pady=(5, 16))
self.open_file_chooser = tk.Button(self.bottom_frame,
text="Open file chooser",
command=self._select_file)
self.open_file_chooser.pack(side="left", padx=10)

self.print_file = tk.Button(self.bottom_frame,
text="Print",
command=self._print_selected_file)
self.print_file.pack(side="right", padx=10)


self._make_modal()

def _read_file(self):
# NOT USED!
if not self.selected_file:
raise ValueError("No file chosen")
with open(self.selected_file, "rb") as in_file: # opening for [r]eading as [b]inary
return in_file.read() # if you only wanted to read 512 bytes, do .read(512)

def _print_selected_file(self):
if not self.selected_file:
print("No file selected yet!")
else:
subprocess.call(["lpr", self.selected_file])

def _select_file(self):
self.selected_file = askopenfilename(title = "Choose file to print")
print(self.selected_file)

def _on_listbox_selection(self, event):
self.selected_printer = self._find_current_selected_printer()

# Sets the printer on your system
subprocess.call(["lpoptions", "-d", self.selected_printer])
print("Selected printer:", self.selected_printer)

def _find_current_selected_printer(self):
curselection = self.listbox.curselection()
if len(curselection) > 0:
return self.listbox.get(curselection[0])
else:
return None

def _display_printers(self):
self.scrollbar = tk.Scrollbar(self.printers_frame)
self.scrollbar.pack(side="right", fill="y")

self.listbox = tk.Listbox(self.printers_frame,
yscrollcommand=self.scrollbar.set,
selectbackground="yellow",
selectmode="single",
height=6)

for printer_name in self.printers_names:
self.listbox.insert("end", printer_name)

# Keep track of selected listbox
self.listbox.bind("<<ListboxSelect>>", self._on_listbox_selection)

# Sets first listbox as selected
self.listbox.select_set(0) # Sets focus
self.listbox.event_generate("<<ListboxSelect>>")

self.listbox.pack(side="left", fill="both", expand=True)
self.scrollbar.config(command=self.listbox.yview)

def _find_system_default_destination(self):
return subprocess.getoutput("lpstat -d").split(": ")[1]

def _find_printers_names(self):
# Command to obtain printer names based on: https://superuser.com/a/1016825/317323
return subprocess.getoutput("lpstat -a | awk 'print $1'").split("n")

def _make_modal(self):
# Makes the window modal
self.transient(self.root)
self.grab_set()
self.wait_window(self)


if __name__ == "__main__":
if not which("lpoptions") or not which("lpr") or not which("awk") or not which("lpstat"):
sys.stderr.write("Requirements: lopotions, lpr, lpstat and awk not satisfied")
else:
root = tk.Tk()
opener = tk.Button(root, text="Open printer chooser", command=lambda: FilePrinterDialog(root))
opener.pack()
root.mainloop()


This program only works if you have the required dependencies which I specify in the program. You should have those since I'm also on a Mac OS X (Sierra).



I've tested only with a .py file. Unfortunately, the format of the printed documented isn't really as desired (since I'm not really an expert on how to use lpr to print files), but you can check the options of lpr and see what you can do with it.



Also, I've not created any preview of the selected file, but you may achieve this using PIL (at least for images)...



Note: be careful, do not click 100 times on the print button, otherwise you will have 100 files in the queue to be printed! You may want to fix this somehow.






share|improve this answer















Here's a program I've just created that allows you to select a printer and print.



import tkinter as tk
from tkinter.filedialog import askopenfilename
import subprocess
from pprint import pprint
import platform
import sys

def which(program):
# http://stackoverflow.com/a/377028/3924118
import os
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file

return None


class FilePrinterDialog(tk.Toplevel):

def __init__(self, root, *args, **kwargs):
tk.Toplevel.__init__(self, root, *args, **kwargs)
self.root = root

self.body = tk.Frame(self, bg="lightblue")
self.body.pack(expand=True, fill="both")

self.title_frame = tk.Frame(self.body, pady=5)
self.title_frame.pack(fill="both", pady=(15, 5))

self.title = tk.Label(self.title_frame, text="Let's print!")
self.title.pack(fill="x")

# Current selected printer of your system
self.system_default_destination = self._find_system_default_destination()

# Finds printer names
self.printers_names = self._find_printers_names()

self.selected_file = None # To hold the selected file's name
self.data_bytes = None # Bytes read from the selected file to print
self.selected_printer = None # Hols name of selected printer

# Display them
self.printers_frame = tk.Frame(self.body, bg="lightblue", padx=10, pady=10)
self.printers_frame.pack(expand=True, fill="both")
self._display_printers()

self.bottom_frame = tk.Frame(self.body, pady=5)
self.bottom_frame.pack(fill="both", pady=(5, 16))
self.open_file_chooser = tk.Button(self.bottom_frame,
text="Open file chooser",
command=self._select_file)
self.open_file_chooser.pack(side="left", padx=10)

self.print_file = tk.Button(self.bottom_frame,
text="Print",
command=self._print_selected_file)
self.print_file.pack(side="right", padx=10)


self._make_modal()

def _read_file(self):
# NOT USED!
if not self.selected_file:
raise ValueError("No file chosen")
with open(self.selected_file, "rb") as in_file: # opening for [r]eading as [b]inary
return in_file.read() # if you only wanted to read 512 bytes, do .read(512)

def _print_selected_file(self):
if not self.selected_file:
print("No file selected yet!")
else:
subprocess.call(["lpr", self.selected_file])

def _select_file(self):
self.selected_file = askopenfilename(title = "Choose file to print")
print(self.selected_file)

def _on_listbox_selection(self, event):
self.selected_printer = self._find_current_selected_printer()

# Sets the printer on your system
subprocess.call(["lpoptions", "-d", self.selected_printer])
print("Selected printer:", self.selected_printer)

def _find_current_selected_printer(self):
curselection = self.listbox.curselection()
if len(curselection) > 0:
return self.listbox.get(curselection[0])
else:
return None

def _display_printers(self):
self.scrollbar = tk.Scrollbar(self.printers_frame)
self.scrollbar.pack(side="right", fill="y")

self.listbox = tk.Listbox(self.printers_frame,
yscrollcommand=self.scrollbar.set,
selectbackground="yellow",
selectmode="single",
height=6)

for printer_name in self.printers_names:
self.listbox.insert("end", printer_name)

# Keep track of selected listbox
self.listbox.bind("<<ListboxSelect>>", self._on_listbox_selection)

# Sets first listbox as selected
self.listbox.select_set(0) # Sets focus
self.listbox.event_generate("<<ListboxSelect>>")

self.listbox.pack(side="left", fill="both", expand=True)
self.scrollbar.config(command=self.listbox.yview)

def _find_system_default_destination(self):
return subprocess.getoutput("lpstat -d").split(": ")[1]

def _find_printers_names(self):
# Command to obtain printer names based on: https://superuser.com/a/1016825/317323
return subprocess.getoutput("lpstat -a | awk 'print $1'").split("n")

def _make_modal(self):
# Makes the window modal
self.transient(self.root)
self.grab_set()
self.wait_window(self)


if __name__ == "__main__":
if not which("lpoptions") or not which("lpr") or not which("awk") or not which("lpstat"):
sys.stderr.write("Requirements: lopotions, lpr, lpstat and awk not satisfied")
else:
root = tk.Tk()
opener = tk.Button(root, text="Open printer chooser", command=lambda: FilePrinterDialog(root))
opener.pack()
root.mainloop()


This program only works if you have the required dependencies which I specify in the program. You should have those since I'm also on a Mac OS X (Sierra).



I've tested only with a .py file. Unfortunately, the format of the printed documented isn't really as desired (since I'm not really an expert on how to use lpr to print files), but you can check the options of lpr and see what you can do with it.



Also, I've not created any preview of the selected file, but you may achieve this using PIL (at least for images)...



Note: be careful, do not click 100 times on the print button, otherwise you will have 100 files in the queue to be printed! You may want to fix this somehow.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 14 '17 at 12:59

























answered Mar 14 '17 at 12:35









nbronbro

5,788105198




5,788105198












  • Seems to be what I am looking for. I will study that code! :)

    – Victor Domingos
    Mar 14 '17 at 12:59






  • 1





    @VictorDomingos Nice! Make me know if there are any problems and we can eventually improve the program (maybe also for future users) ;)

    – nbro
    Mar 14 '17 at 13:01

















  • Seems to be what I am looking for. I will study that code! :)

    – Victor Domingos
    Mar 14 '17 at 12:59






  • 1





    @VictorDomingos Nice! Make me know if there are any problems and we can eventually improve the program (maybe also for future users) ;)

    – nbro
    Mar 14 '17 at 13:01
















Seems to be what I am looking for. I will study that code! :)

– Victor Domingos
Mar 14 '17 at 12:59





Seems to be what I am looking for. I will study that code! :)

– Victor Domingos
Mar 14 '17 at 12:59




1




1





@VictorDomingos Nice! Make me know if there are any problems and we can eventually improve the program (maybe also for future users) ;)

– nbro
Mar 14 '17 at 13:01





@VictorDomingos Nice! Make me know if there are any problems and we can eventually improve the program (maybe also for future users) ;)

– nbro
Mar 14 '17 at 13:01



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f42781944%2fpreview-a-pdf-file-and-choose-printer-before-actually-printing-the-document%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)