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;
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
add a comment |
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
In my Bash scripts, I use for instancepdfsplit $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
add a comment |
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
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
python macos printing tkinter printers
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 instancepdfsplit $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
add a comment |
In my Bash scripts, I use for instancepdfsplit $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
add a comment |
1 Answer
1
active
oldest
votes
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.
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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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