0

Displayio Dynamic change of rectangle width
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Displayio Dynamic change of rectangle width

by Tonygo on Wed May 12, 2021 7:10 am

I’m just getting my head round Graphics in CircuitPython with displayio and I hope somebody can help.

I want to have three horizontal bar graphs which change length as potentiometers are twisted. I thought I would be able to set up the rectangles to change width on a variable in the same manner as I change the text in a label but all I got were ‘not allowed’ type errors.

Is there a way to do this?

I managed to get what I wanted by popping and appending the changing rectangle. I could do this with 3 rectangles but this might make the screen jitter.

Is there a way to hold the screen updates while such a multi stage process takes place?

Here is my ‘experimental code’.


Code: Select all | TOGGLE FULL SIZE
"""
Example of CircuitPython/Raspberry Pi Pico
to display on 320x240 ili9341 SPI display
"""
import board
import displayio
import time
import terminalio
import busio
from adafruit_display_text import label
import adafruit_ili9341
from adafruit_display_shapes.rect import Rect

# Release any resources currently in use for the displays
displayio.release_displays()
# Setup ili9341 320x240 TFT display
TFT_WIDTH = 320
TFT_HEIGHT = 240

tft_spi_clk = board.GP6
tft_spi_mosi = board.GP7
tft_cs = board.GP13
tft_dc = board.GP15
tft_res = board.GP14

tft_spi = busio.SPI(tft_spi_clk, MOSI=tft_spi_mosi)

display_bus = displayio.FourWire(
    tft_spi, command=tft_dc, chip_select=tft_cs, reset=tft_res)

display = adafruit_ili9341.ILI9341(display_bus,
                    width=TFT_WIDTH, height=TFT_HEIGHT)
display.rotation = 0

# Make the display context
splash = displayio.Group(max_size=20)
display.show(splash)

# Make a background color fill
color_bitmap = displayio.Bitmap(320, 240, 1) # Full screen background WHITE
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF # WHITE
bg_sprite = displayio.TileGrid(color_bitmap, x=0, y=0, pixel_shader=color_palette)
splash.append(bg_sprite)
##########################################################################

text = "HELLO WORLD"
font = terminalio.FONT
color = 0x0000FF

# Create the text label
text_area = label.Label(font, text=text, color=color)

# Set the location
text_area.x = 10
text_area.y = 60

# Show it
splash.append(text_area)
time.sleep(2)

rect_bar = Rect(30, 50, 0, 20, fill=0x0)
splash.append(rect_bar)
v = [10,0,20,30,40,50,20,70,85,100,50,1,0,33,100,27]
for x in v:
    text_area.text = str(x)
    splash.pop()
    rect_bar = Rect(30, 50, x, 20, fill=0x0)
    splash.append(rect_bar)
    time.sleep(0.6)
print("Done")
time.sleep(3)


I would grateful for some help.

Tonygo
 
Posts: 95
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

by kmatch on Wed May 12, 2021 2:03 pm

Using display_shapes, you can only change the size by recreating the rectangles.

As for controlling the display to prevent partial refreshes of the screen while you are recreating the rectangles, there are two options.

1. Set display.auto_refresh=False at the setup portion of your code, then perform display.refresh() after you finished recreating your rectangles.
2. Before recreating your rectangles, set display.auto_refresh=False. Recreate your rectangles. Set display.auto_refresh=True.

https://circuitpython.readthedocs.io/en/latest/shared-bindings/displayio/#displayio.Display.auto_refresh

One other thing you may consider if you need to save RAM, use the vectorio library for creating your solid colored background and your rectangles.

kmatch
 
Posts: 16
Joined: Sun Sep 03, 2017 12:17 am

Re: Displayio Dynamic change of rectangle width

by Tonygo on Thu May 13, 2021 4:09 am

Thank you for the quick response.

Tonygo
 
Posts: 95
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

by burrito_poots on Thu May 13, 2021 4:49 pm

It's been a really long time so I don't know where it was shown in what guide but I swear I saw someone accomplish this by just using really long rectangles that would move up/down into the display border, so to the user it appeared as though the rectangle was growing taller or shorter, but as far as the code was concerned you were just moving an already predefined sized rectangle into or out of the viewing display area.

burrito_poots
 
Posts: 103
Joined: Thu May 30, 2019 5:02 pm

Re: Displayio Dynamic change of rectangle width

by Tonygo on Fri May 14, 2021 9:37 am

Thank you.
burrito_poots wrote:It's been a really long time so I don't know where it was shown in what guide but I swear I saw someone accomplish this by just using really long rectangles that would move up/down into the display border, so to the user it appeared as though the rectangle was growing taller or shorter, but as far as the code was concerned you were just moving an already predefined sized rectangle into or out of the viewing display area.


The previous post was written by me (Aug 18, 2020) but I had forgotten all about it. (It is encouraging to see than someone reads my posts.)

viewtopic.php?f=60&t=168528

Basically you draw the full sized bar in the required colour and then cover it over with another rectangle in background colour from the high end which moves back and forth.

I will give the method another try with the new and larger display screen I'm now working on, 320x240 TFT - SPI with Touch, driven with a Raspberry Pi Pico.

(Covid isolation is sapping the brain. Coding is keeping me sane at the moment as travelling is out of the question.)

Tonygo
 
Posts: 95
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

by Tonygo on Fri May 14, 2021 10:41 am

Here is the solution:

Code: Select all | TOGGLE FULL SIZE
"""
Dynamic bar graph - Very basic - Proof of concept
Example of CircuitPython/Raspberry Pi Pico
to display on 320x240 ili9341 SPI display
Tony Goodhew 14 May 2021
"""
import board
import displayio
import time
import terminalio
import busio
from adafruit_display_text import label
import adafruit_ili9341
from adafruit_display_shapes.rect import Rect

# Release any resources currently in use for the displays
displayio.release_displays()
# Setup ili9341 320x240 TFT display
TFT_WIDTH = 320
TFT_HEIGHT = 240

tft_spi_clk = board.GP6
tft_spi_mosi = board.GP7
tft_cs = board.GP13
tft_dc = board.GP15
tft_res = board.GP14

tft_spi = busio.SPI(tft_spi_clk, MOSI=tft_spi_mosi)

display_bus = displayio.FourWire(
    tft_spi, command=tft_dc, chip_select=tft_cs, reset=tft_res)

display = adafruit_ili9341.ILI9341(display_bus,
                    width=TFT_WIDTH, height=TFT_HEIGHT)
display.rotation = 0

# Make the display context
splash = displayio.Group(max_size=20)
display.show(splash)

# Make a background color fill
color_bitmap = displayio.Bitmap(320, 240, 1) # Full screen background WHITE
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF # WHITE
bg_sprite = displayio.TileGrid(color_bitmap, x=0, y=0, pixel_shader=color_palette)
splash.append(bg_sprite)
##########################################################################

text = "Bar Graph"
font = terminalio.FONT
color = 0x0000FF

# Create the text label
text_area = label.Label(font, text=text, color=color)

# Set the location
text_area.x = 8
text_area.y = 60

# Show it
splash.append(text_area)
time.sleep(2)
base = Rect(28, 45, 2, 30, fill=0xFF0000)
splash.append(base)
rect_bar = Rect(30, 50, 200, 20, fill=0x0)
splash.append(rect_bar)
cover  = Rect(30, 50, 200, 20, fill=0xFFFFFF)
splash.append(cover)
v = [10,0,20,30,40,50,20,70,85,100,50,1,0,33,100,27]
for x in v:
    text_area.text = str(x)
    cover.x = x * 2 +30
    print(x)
    time.sleep(0.6)
print("Done")
time.sleep(1)


It might save someone else some 'thinking time'.

Tonygo
 
Posts: 95
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

by kevinjwalters on Fri May 14, 2021 8:49 pm

Not quite bar graphs but I wrote some displayio code a while ago to allow a program to show the state of GPIO pins graphically, see https://github.com/kevinjwalters/Circui ... DisplayPin

You can see it in action on: Adafruit CLUE running MicroPython code from Kitronik's Inventor's Kit using an emulation library (YouTube).

There's also this but I've not used it/seen it: https://github.com/adafruit/Adafruit_Ci ... rogressBar

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Displayio Dynamic change of rectangle width

by Tonygo on Sat May 15, 2021 4:17 am

I like the moving indicator as you turn the pot. Neat idea.

Tonygo
 
Posts: 95
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

by kevinjwalters on Sat May 15, 2021 8:44 am

I think that came out of an attempt to showcase the CLUE's screen, one advantage it has over the micro:bit's humble (but bright) 5x5 LEDs.

Turns out I've written more of these than I can remember, another basic +/- bargraph in https://github.com/adafruit/Adafruit_Le ... #L246-L287 from Adafruit Learn: CLUE Metal Detector in CircuitPython.

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Displayio Dynamic change of rectangle width

by Tonygo on Sat May 15, 2021 12:12 pm

I've got a CLUE and an Edge Badge, which I prefer as the connections underneath are so useful. I did a long review of the Inventors' Kit trying to get Kitronik to put a bit more effort into promoting Python.
I've been writing so much over the past year that some of what I have done in the past slips from the mind.

Tonygo
 
Posts: 95
Joined: Fri Apr 13, 2018 11:09 am

Please be positive and constructive with your questions and comments.