11

For a tkinter GUI, I must read in a Hex address in the form of '0x00' to set an I2C address. The way I am currently doing it is by reading the input as a string, converting the string to an integer, then converting that integer to an actual Hex value as shown in the partial code below:

GUI initialization:

self.I2CAddress=StringVar()
self.I2CAddress.set("0x00") #Sets Default value of '0x00'
Label(frame, text="Address: ").grid(row=5, column=4)
Entry(frame, textvariable=self.I2CAddress).grid(row=5, column=5)

Then inside the function:

addr = self.I2CAddress.get()   
addrint = int(addr, 16)  
addrhex = hex(addrint)

This works for most values, but my issue is that if I enter a small Hex value string such as '0x01', it converts to the proper integer of 1, but then that is converted to a Hex value of 0x1 instead of 0x01.

I am an EE and have very limited programming experience, so any help is greatly appreciated.

BDP
  • 191
  • 1
  • 4
  • 11

1 Answers1

18

Use the format() function:

format(addrint, '#04x')

This formats the input value as a 2 digit hexadecimal string with leading zeros to make up the length, and # includes the 'standard prefix', 0x in this case. Note that the width of 4 includes that prefix. x produces lower-case hex strings; use X if you need uppercase.

Demo:

>>> for i in range(8, 12):
...     print format(i, '#04x')
... 
0x08
0x09
0x0a
0x0b
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • You answered so quickly I have to wait a few minutes before it allows me, but I absolutely will – BDP May 24 '13 at 19:17
  • You can just use `{:#02x}` instead of the explicit `0x`. The `#` will add the "standard prefix", which for hex numbers is `0x`. (This also works the same way with %-formatting, and C `printf`, and POSIX command-line `printf`, etc.) – abarnert May 25 '13 at 00:05
  • @abarnert: Cool, I was *not* aware of the `#` prefix option. – Martijn Pieters May 25 '13 at 00:06
  • @abarnert: Slight snag: `#` **removes** the leading zeros again. That, to me, looks like a bug, it appears as if the width is ignored altogether. – Martijn Pieters May 25 '13 at 00:09
  • @abarnert: ah, no, the field width includes the prefix. – Martijn Pieters May 25 '13 at 00:12
  • Right, sorry, you want `{:#04x}`. Whenever I actually write code for this (in C or Python) I type 10, 6, or 4 without thinking, but whenever I explain it to someone else, I tell them to use 8, 4, or 2, and they run into the exact same thing you did. You'd think I'd learn one of these decades… – abarnert May 25 '13 at 00:14
  • 1
    @abarnert: With the `#` prefix you can just use the `format()` function and completely dispense with the string templating altogether. – Martijn Pieters May 25 '13 at 00:20
  • @MartijnPieters, For format(-1,'04X') the output is -01 instead of FF – Nazar Mar 15 '20 at 21:58
  • @Nazar: Python integers are unbounded, unlike C signed integers. -01 is the *correct* output. – Martijn Pieters Mar 15 '20 at 23:07