Displayio Dynamic change of rectangle width

CircuitPython on hardware including Adafruit's boards, and CircuitPython libraries using Blinka on host computers.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
Tonygo
 
Posts: 108
Joined: Fri Apr 13, 2018 11:09 am

Displayio Dynamic change of rectangle width

Post by Tonygo »

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

"""
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.

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

Re: Displayio Dynamic change of rectangle width

Post by kmatch »

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 ... to_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.

User avatar
Tonygo
 
Posts: 108
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

Post by Tonygo »

Thank you for the quick response.

User avatar
burrito_poots
 
Posts: 134
Joined: Thu May 30, 2019 5:02 pm

Re: Displayio Dynamic change of rectangle width

Post by burrito_poots »

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.

User avatar
Tonygo
 
Posts: 108
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

Post by Tonygo »

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.)

User avatar
Tonygo
 
Posts: 108
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

Post by Tonygo »

Here is the solution:

Code: Select all

"""
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'.

User avatar
kevinjwalters
 
Posts: 1025
Joined: Sun Oct 01, 2017 3:15 pm

Re: Displayio Dynamic change of rectangle width

Post by kevinjwalters »

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

User avatar
Tonygo
 
Posts: 108
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

Post by Tonygo »

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

User avatar
kevinjwalters
 
Posts: 1025
Joined: Sun Oct 01, 2017 3:15 pm

Re: Displayio Dynamic change of rectangle width

Post by kevinjwalters »

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.

User avatar
Tonygo
 
Posts: 108
Joined: Fri Apr 13, 2018 11:09 am

Re: Displayio Dynamic change of rectangle width

Post by Tonygo »

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.

Locked
Please be positive and constructive with your questions and comments.

Return to “Adafruit CircuitPython”