Where I work there's two different printers being used on a daily basis, one of them prints things from a particular program, which only uses the default printer. A lot of the times, during busy periods, people forget to switch the default printer, resulting in that program using the wrong printer, which isn't suitable for what's being printed.

The work PC is ancient and getting into the printers menu can take up to a few minutes. I am hoping my program will reduce spending so much time on the computer just to change the default printer.

This is the first time I've done up an interface in Tkinter, so I'd appreciate feedback if it can be done better.

import tkinter as tk
import tkinter.ttk as ttk

import win32print

def get_available_printers():
    return [printer[2] for printer in win32print.EnumPrinters(2)]

class PrinterManager(tk.Frame):

    def __init__(self, master, *args, **kwargs):
        tk.Frame.__init__(self, master, *args, **kwargs)
        self.master = master

    def configure_interface(self):
        self.master.title('Printer Manager')
        self.master.resizable(False, False)

    def create_widgets(self):
        self.default_printer_label = tk.Label(self.master, bg='#626a77', fg='white')
        self.default_printer_label.place(x=10, y=12)

        refresh_button = tk.Button(self.master, text='Refresh', command=self.update_default_printer_label)
        refresh_button.place(x=285, y=10)

        selected_printer = tk.StringVar()
        printer_choice_menu = ttk.Combobox(self.master, textvariable=selected_printer, values=get_available_printers(), width=35, state='readonly')
        printer_choice_menu.place(x=12, y=62)

        set_default_printer_button = tk.Button(self.master, text='Set', command=lambda: self.set_default_printer(selected_printer))
        set_default_printer_button.place(x=285, y=60, width=50)

    def update_default_printer_label(self):
        default_printer = win32print.GetDefaultPrinter()
        default_printer_text = 'Default printer: {}'.format(default_printer)

    def set_default_printer(self, printer_name):

if __name__ == '__main__':
    root = tk.Tk()

1 Answer 1


That is great as a first tkinter application. I like the fact you wrote two specific functions update_default_printer_label() and set_default_printer(). Most programmers will just do all what you did in one function and they believe as long as it does not exceed 25 lines length they are near perfection. With your approach, you have fine grain control on your program as unit testing is simplified (because you have small functions doing one clear task).

I do not have much to say about your program. There are very few imperfections but some may argue it is Ok. Nevertheless, I do not see the reason you let the function get_available_printers() orphan (I mean it can be integrated into the class PrinterManager, it is its right place and you will add only self. to call it where you did)

I would like to add one or two extra notes: given the description of the problematic, I think it would be reasonable to create a stand alone executable for your application using pyinstaller since you are trying to avoid navigating the printer menu and, why not, schedule your program (using python-crontab) to switch to the default printer (you need to add some code to check before switching) at a specific time (for example everyday at 08:10 AM)

  • 1
    \$\begingroup\$ Thanks! Yeah, I realized that get_available_printers is an oddball and since I have moved it inside the class. I actually already have created an .exe with pyinstaller, being able to build it into one file was great. \$\endgroup\$
    – Luke
    May 12, 2018 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.