Lo-Fi Python

Sep 14, 2018

Making A Desktop Color Eyedropper in Python to Grab Color Values

Goal: recreate my resume in the dark Atom text editor theme (background and fonts). Sub-goal: find a color eyedropper to grab the actual color values of the Atom layout.

Approach #1: find an Atom eyedropper package to grab the colors. My first thought was to find the easiest solution, within the packages of my Atom text editor. After searching Atom's packages, the two best potential solutions were "an-color-eyedropper" and "color picker" . The an-color-eyedropper description sounds perfect: "A simple "real" color picker. By "real" I mean it's able to pick colors anywhere on any screen."

Color picker an color eyedropper

Unfortunately it failed to install and displayed the error, "Unable to download 400 Bad Request Repository inaccessible". It seems to rely on the "python" Atom package which is now deprecated. I was unable to find a repo anywhere by googling.

Color picker has easy-to-follow instructions and installed with no problem. It allows you to quickly select any color visually with sliders. Then the RGB or Hexadecimal values of your color are added as text in the editor in proper format. However, we are looking for a color grabber to pull colors from a screen object. This is more of a productivity enhancing and color exploration tool for programmers. On to Python options.

Approach #2: Use the python tkcolorpicker package to grab the colors.

The first thing I found on Google was tkcolorpicker, a package that uses the tkinter library. I couldn't tell exactly what it was, so let's find out. First, install via pip install:

python -m pip install tkcolorpicker
Then run the below script. Cool gadget for sure, but also not quite what I was looking to use. It allows selection of a color with sliders or input values, similar to Atom's color picker, but for user input rather than color picking. Nice little tool. :D
color_picker_gui
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import tkinter as tk
import tkinter.ttk as ttk
from tkcolorpicker import askcolor

root = tk.Tk()
style = ttk.Style(root)
style.theme_use("clam")
hex_code, RGB_code = askcolor((255, 255, 0), root)
print(hex_code, RGB_code)
root.mainloop()

askcolor() returns a tuple with both the RGB and hex codes selected by the user. Above, we are unpacking that tuple into the hex_code and RGB_code variables.

Approach #3: Use the Python eyedropper package to grab the colors.

I then found eyedropper for Windows, which has a minimalist repository and offers a simple approach to desktop eyedropper functionality. Install eyedropper via pip:

python -m pip install eyedropper
pyeyedropper_start

Hover your mouse over the object you want to grab the color from (in my case, the Atom text editor background). Alternatively, I was able to run eyedropper from the command line by entering:

py -m eyedropper
pasted_hex2 CCvOYFiUgAA4DJd

Mission possible. Then I hit ctrl+v in a text file and there was the hex code for my Atom background. Some of the colors that eyedropper grabbed were nearly identical to those in the Atom text editor dark theme. Others were not quite the same. I made slight eyeball adjustments to the colors for some of the fonts.

Using Python to convert hex to RGB

Microsoft Word uses RGB codes but eyedropper gave us hex. To convert, I found this website practical and quick. Alternatively, you could convert a hex code to RGB with python:

1
2
3
hex_code = input("Enter hex: ").lstrip("#")
RGB_code = tuple(int(hex_code[i : i + 2], 16) for i in (0, 2, 4))
print("RGB =", RGB_code)
rgb_to_hex

Bonus: use pd.read_clipboard() docs to get the hex codes.

Once eyedropper sends the color values to your system's clipboard, there are multiple ways to access them. This alternative uses pandas.

Installing pandas and pyperclip with pip:

1
2
python -m pip install pandas
python -m pip install pyperclip

On Linux, install xclip or xsel

sudo apt-get install xclip

To get the clipboard contents with pandas:

1
2
3
4
import pandas as pd

hex_code_df = pd.read_clipboard()
print(hex_code_df.head())

Supplementary Notes and Links

Aug 25, 2018

Gooey GUI for Python Scripts

GUI stands for "Graphical User Interface", aka the part of a program designed for human interaction. Adding a GUI to a Python script allows anyone to run it without having to code or use the command line.

There are several GUI libraries in Python. A few I have heard of are Tkinter (comes in the standard library), wxPython, PyQT, easygui, DearPyGui and PySimpleGUI. I explored Tkinter back when I first got into Python. It was more intricate and offered more control over the look of your app, and took longer to pick up. Gooey is more of a pre-packaged GUI library.

The Gooey Github page was most useful to me and helped me to do what I needed. The script posted in this blog helped as well. I needed to enable a human to supply three files and enter a number. Gooey was a good match for this. The library has two branches:

  1. some basic widgets piggyback off the argparse library
  2. another part of the library uses a function called the GooeyParser. The GooeyParser offers more advanced widgets, like a file chooser. This was exactly what I was looking to use to pull in files for my script.

Installing Gooey

Argparse comes stock with Python. You can install Gooey via the pip installer. Open command prompt or terminal and enter:

python -m pip install Gooey

Below is a basic argparse/Gooey combination script. The argparse version offers a handful of widgets such as checkboxes and dropdown, but I had trouble getting them to work with the GooeyParser (used in 2nd script).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from argparse import ArgumentParser
from gooey import Gooey

@Gooey(program_name='Report Generator', default_size=(575, 600))
def get_args():
    """Demonstrating python's vars built-in to store arguments in a python dict."""
    parser = ArgumentParser(description='A simple argument parser', epilog='This is where you might put example usage')
    parser.add_argument('Name', action='store', required=True, help='Help text for option X')
    parser.add_argument('Email', help='Help text for option Y', default=False)
    parser.add_argument('Campaign Number', help='Help text for option Z', type=int)
    parser.add_argument('Campaign Segment', choices=['A', 'B','All'], default='a', nargs='?')
    user_inputs = vars(parser.parse_args())
    print(user_inputs)
    name = user_inputs['Name']
    campaign_number = user_inputs['Campaign Number']
    return parser.parse_args()

if __name__ == '__main__':
    get_args()
Side note: Check out Python's vars() built-in function above. It returns the input data as a dictionary called user_inputs. Then we can get the values via the dictionary's keys. Pretty nifty!

The @Gooey() part of the code is an advanced function known as a decorator in Python. Put simply, decorators are functions that modify the function to which they are attached.

Below is my script that uses the more advanced GooeyParser for its "FileChooser" widget. Gooey allows you to group widgets together and set how many widgets per line with the gooey_options={} parameter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from gooey import Gooey, GooeyParser

@Gooey(program_name='Email Campaign Reporting Generator', default_size=(575, 600))
def get_args():
    """Adding two argument groups, each accepting two arguments. Using gooey_options to set layout."""
    parser = GooeyParser(description='Export campaign report spreadsheets and upload below.')
    top_group = parser.add_argument_group(gooey_options={'show_border': False,'columns': 1})
    top_group.add_argument('Contact List', help='Upload Send List (.xlsx)', widget='FileChooser')
    top_group.add_argument('Opens List', help='Upload Opens List (.xlsx)', widget='FileChooser')
    top_group.add_argument('Unsubscribe List', help='Upload Unsubscribe List (.xlsx)', widget='FileChooser')
    bottom_group = parser.add_argument_group(gooey_options={'show_border': False,'columns': 1, 'required':False})
    bottom_group.add_argument('Campaign ID', action='store', help="Number found in the Campaign 'Reports' tab")
    bottom_group.add_argument('Campaign Segment', action='store', help='Enter A, B, or All. All lists supplied must match segment.')
    user_inputs = vars(parser.parse_args())
    name = user_inputs['Name']
    return parser.parse_args()

if __name__ == '__main__':
    get_args()

Overall, Gooey knows what it wants to be, an easy to use GUI framework for Python. It does it well. Here's a screenshot of my program's shiny GUI:

gooey_gui_shot_2

Now that I have a GUI on top of my program and it delivers the expected output file, I'm hoping to take it one step further by packaging it up as a Windows .exe file. This would allow it to run as a desktop app on any Windows computer without the need to install Python or library dependencies. I've only begun exploring options to do this but a few libraries I've heard of are pyinstaller, cx_Freeze and Py2Exe. Updates coming if I figure it out. Cheers :D

Update: I did figure out how to compile my Gooey app to a Windows application with Pyinstaller. You can read more on how I did it here.

Feb 29, 2016

Tkinter and Python Libraries

Python's set of libraries are fun to explore. They allow Python to work with many types of other coding languages, allow you to do cool stuff, and seem to require a minimal knowledge of the actual code. You can read the complete list of standard libraries here. There are also others available that you can download and install for unique challenges or software such as Android.

Currently, my favorite library is Tkinter. Tkinter is a module that replicates Tk/TCL within Python and allows you to create a quick Graphical User Interface (GUI) for your programs - great for trying to put together a prototype program with basic aesthetic design control for things like buttons, entry boxes, text and other visual elements that make up the front end of a computer program.

+Pro Tip: When you're trying to use a new module, you can read how to use it in the module's documentation. Here's Tkinter's documentation.

++ Today's find: Free guide called "Automate the Boring stuff with Python"