[Rod Stephens Books]
Index Books Python Examples About Rod Contact
[Mastodon] [Bluesky] [Facebook]
[Build Your Own Python Action Arcade!]

[Build Your Own Ray Tracer With Python]

[Beginning Database Design Solutions, Second Edition]

[Beginning Software Engineering, Second Edition]

[Essential Algorithms, Second Edition]

[The Modern C# Challenge]

[WPF 3d, Three-Dimensional Graphics with WPF and C#]

[The C# Helper Top 100]

[Interview Puzzles Dissected]

Title: Make an improved interactive unit converter with tkinter in Python

[Converting between units like furlongs to feet in Python]

My previous post, Make an interactive unit converter with tkinter in Python, showed how you can build an interactive universal unit converter. It works but it can sometimes be hard to find the units that you want to work with. All of the units are present in the same list so units of weight, volume, distance, and time are all mixed together as shown in the picture below.

[Finding the units you want can be hard]
This example uses a different approach. First you select the category of unit that you want to work with like Volume or Distance. Then the left combo box presents a list holding only units of that type, making it easier to find the one you want. This would be a fairly complicated change from the original text-based unit converter, but the previous example already did a lot of the work we need for this one so it's not too hard.

Selecting Quantity

The new quantity combo box must display a list of the available quantity types. You may (but probably don't) remember that the UnitConverter class has a conversions dictionary holding the unit data. Each of that dictionary's keys is a quantity type like Distance or Weight. The values are sub-dictionaries holding information for the units of that quantity. The following code shows how the program initializes the conversions dictionary.

self.conversions = { # Distances in meters. 'Distance': { 'm': [0, 1, 0], 'in': [0, 0.0254, 0], 'ft': [0, 0.3048, 0], 'yd': [0, 0.9144, 0], 'mi': [0, 1609.34, 0], 'km': [0, 1000, 0], 'cm': [0, 0.01, 0], 'mm': [0, 0.001, 0], 'ell': [0, 1.143, 0], 'furlong': [0, 201.168, 0], 'league': [0, 5556, 0], }, # Weight in grams. 'Weight': { 'g': [0, 1, 0], 'lb': [0, 453.592, 0], 'oz': [0, 28.3495, 0], 'ton': [0, 907185, 0], 'kg': [0, 1000, 0], 'tonne': [0, 1000000, 0], 'stone': [0, 6350.29, 0], }, # Volume in liters. 'Volume': { 'l': [0, 1, 0], 'cup': [0, 0.236588, 0], 'fl oz': [0, 0.0295735, 0], 'tsp': [0, 0.00492892, 0], 'tbl': [0, 0.01479, 0], 'pint': [0, 0.473176, 0], 'qt': [0, 0.946353, 0], 'gal': [0, 3.78541, 0], 'cl': [0, 0.01, 0], 'ml': [0, 0.001, 0], }, # Time in seconds. 'Time': { 'sec': [0, 1, 0], 'min': [0, 60, 0], 'hour': [0, 3600, 0], 'day': [0, 1440, 0], 'week': [0, 10080, 0], 'year': [0, 525600, 0], 'fortnight': [0, 20160, 0], }, # Temperature in Kelvins. 'Temperature': { # base_unit = (x + a) * b + c. 'K': [0, 1, 0], 'C': [0, 1, 273.15], # C = (K + 0) * 1 + 273.15 'F': [-32, 0.5555, 273.15], # K = (F - 32) * 5/9 + 273.15 }, }

All of this gives us a trivial way to set the values in the Quantities combo box: we just take the conversions dictionary's keys and sort them.

The following code shows how the program creates this combo box. The code that sets the combo box's list of values is highlighted in blue.

quantities = sorted(self.converter.conversions.keys()) combo_width = max(len(quantity) for quantity in quantities) self.quantity_combo = ttk.Combobox(self.window, width=combo_width, values=quantities, state='readonly')

Listing Units

When you select a quantity type, the following code sets the choices in the "from" and "to" units combo boxes.

def quantity_changed(self, event): '''The quantity changed. Update the from unit combo choices.''' # Update from and to unit choices. quantity = self.quantity_combo.get() values = sorted(self.converter.conversions[quantity].keys()) self.from_unit_combo.configure(values=values) self.from_unit_combo.current(0) self.to_unit_combo.configure(values=values) self.to_unit_combo.current(0) # Perform the conversion if possible. self.convert()

This method gets the quantity type choice. It gets the sub-dictionary for that quantity, uses keys to get the units in that sub-dictionary, and sorts the keys.

The code then sets the from_unit_combo and to_unit_combo widgets' values properties to the values. It also selects the first choices in the combo boxes and then calls convert to display the conversion if possible.

Selecting From Unit

When you select a "from" unit in the previous version, the program changes the choices in the "to" unit combo box so they are appropriate. For example, if you select a Volume for the "from" unit, the code sets the choices in the "to" unit combo box so they are also Volumes.

This example's quantity_changed method sets the choices for both the "from" and "to" combo boxes so we don't need to do that here. We do, however, need to call convert to display the conversion if possible.

The previous version called the from_unit_changed method when you select a choice in the "from" combo box. This version uses the following code to make the combo box call convert instead.

self.from_unit_combo.bind('<>', self.convert)

Conclusion

That's all there is to it. This version of the program requires one extra step because you need to pick a quantity before you can pick units, but makes it easier to find the units you want.

Download the example to experiment with it and to see additional details.

© 2025 Rocky Mountain Computer Consulting, Inc. All rights reserved.