Ignamious
Posts: 3
Joined: Fri Oct 06, 2017 7:49 pm

7” Pi display screen overlay text.

Fri Oct 06, 2017 7:56 pm

I’m working on a case for the 7” Pi foundation display and RP3 with speakers. I’ll be adding volume controls to it via a + and - button. These will send a 3db change to an I2C amp. I can also return the current db that the device is set too.

What I’d like to do is add an onscreen display of this when I update the volume rather then having leds do it.

Is it possible to do this? Is it possible to display on top of any currently running program to add this overlay text / bar graph?

Programs that will most likely run are emulators / ports, Kodi, and sometimes a OS Desktop.

User avatar
paddyg
Posts: 1979
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: 7” Pi display screen overlay text.

Sat Oct 07, 2017 12:02 pm

Yes definitely possible by drawing onto display layer in front of other output. See https://github.com/swehner/foos for a sophisticated overlay system and https://github.com/pi3d/pi3d_demos/blob/master/Dials.py for the simple one below (which has a non-zero alpha for background but could be completely clear). Also I think info-beamer (and possibly many other) systems can overlay images and text - but I've not used them.
Screenshot from 2017-10-07 12-50-23.jpg
Screenshot from 2017-10-07 12-50-23.jpg (57.74 KiB) Viewed 471 times
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Davies
Posts: 121
Joined: Sat Apr 04, 2015 4:24 pm

Re: 7” Pi display screen overlay text.

Sat Oct 07, 2017 1:25 pm

to get the keyboard info you could use pynput

Code: Select all

from pynput import keyboard

def on_press(key):
    try:
        print('alphanumeric key {0} pressed'.format(
            key.char))
    except AttributeError:
        print('special key {0} pressed'.format(
            key))

def on_release(key):
    print('{0} released'.format(
        key))
    if key == keyboard.Key.esc:
        # Stop listener
        return False

# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()
this example would print the keyboard input to console but could be used to set a variable which would then be passed to a clock/dial, tkinter label or anything else.
with tkinter you would need to use something like

Code: Select all

root.lift()
in the window set up to force it to front

User avatar
paddyg
Posts: 1979
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: 7” Pi display screen overlay text.

Sat Oct 07, 2017 5:09 pm

Though if the OP wants info, graphs etc superimposed over the existing screen content I don't think tkinter will do it. Qt has transparent background but I suspect it won't work for the main widget if you use X11 (someone with more knowledge about these things will be able to correct me if I'm wrong)
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Davies
Posts: 121
Joined: Sat Apr 04, 2015 4:24 pm

Re: 7” Pi display screen overlay text.

Sun Oct 08, 2017 3:54 pm

hey paddy, i was thinking more along the lines of a text overlay also suggested by the OP..
transparency effects and closing/opening of tkinter windows is possible and something i wanted to put into this example but i just dont have time right now, so if the OP is wanting to use tkinter theyll have to put some work in.. but heres a borderless tkinter window displaying a variable which will update on each press of +/- keys..

Code: Select all

from Tkinter import *
from pynput import keyboard
import threading

volume = 0


def on_press(key):
    global volume
    try:
        if key.char == '+':
            volume += 1
            label.config(text="Volume "+"%02d" % volume)
            t1.update_idletasks()
        if key.char == '-':
            volume -= 1
            label.config(text="Volume " + "%02d" % volume)
            t1.update_idletasks()
    except:
        pass


def on_release(key):
    if key.char == '+' or '-':
        pass


def key_input():
    with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
            listener.join()


thread = threading.Thread(target=key_input)
thread.daemon = True
thread.start()


t1 = Tk()
t1.overrideredirect(True)
label = Label(t1, text="Volume "+"%02d" % volume, width=12, font=('aharoni', 28, 'bold'), fg='red')
label.grid(padx=10, pady=5, row=0, column=0, sticky='W,E,N,S')
t1.lift()
t1.mainloop()

User avatar
paddyg
Posts: 1979
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: 7” Pi display screen overlay text.

Sun Oct 08, 2017 5:11 pm

I didn't know that you could make X windows transparent like that. If I make fg='white', bg='black' then
t1.wm_attributes("-alpha", 0.5)
It doesn't look bad. On my laptop at least. I can't figure out how to change the widget transparency on the Raspberry Pi and it's not clear how to make just the background transparent, but it might be possible.
PS is there a reason not to use the tkinter <KeyPress> and <KeyRelease>?
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Ignamious
Posts: 3
Joined: Fri Oct 06, 2017 7:49 pm

Re: 7” Pi display screen overlay text.

Wed Oct 11, 2017 12:27 am

This is all fantastic advice, and direction, thank you all. I'm going to give this a shot now. Going to SSH into a pi displaying onto the TV now and give it a shot and see if I can get anything to show up. In a way having the PI's Low power Lightning but is the effect I'm looking for (but with a vertical bar graph displaying the volume that the TPA2016 is reporting via i2c. I'm already able to communicate with it over the via a python script.

I'm very new to python as in just started looking at it a month ago, but I know enough C to get into trouble.

I'll report back here with success / failure and include any code I come up with.

Ignamious
Posts: 3
Joined: Fri Oct 06, 2017 7:49 pm

Re: 7” Pi display screen overlay text.

Wed Oct 11, 2017 1:38 am

So, onlooking up the info I found a handy tool called pngview

https://github.com/AndrewFromMelbourne/ ... er/pngview

Got that and was able to get a PNG Displayed on the screen. This will work perfectly as the TPA2016 is -28 to 30 db gain and boots at 6db in the script I'll just make sure at -27 it'll be the lowest and any more just turn off output. though with some tests I've already done with my current speakers 0 is the lowest I'll want. so I'll just make some PNG's as there are 20 steps I'll only need like 23 PNG's max.

Code: Select all

#!/usr/bin/python
import os

os.system("/home/pi/test/pngview -b 0 -l 3000 -x 600 -y 600 /home/pi/test/test.png")

I wonder how they get the Temp and Bad power to sho up on the Pi, as that would be the ideal way to do it, that way I'm not adding more bloat, but this will work for now. I'll just make a simple small bar graph 0-100% and a speaker icon to show the percentage in 5 step blocks with 3db gain per volume button press.

RDS
Posts: 535
Joined: Tue Oct 06, 2015 8:17 am
Location: Lancashire, UK

Re: 7” Pi display screen overlay text.

Wed Oct 11, 2017 9:43 pm

@Davies
Could you advise please, is this a Python2 program?

User avatar
paddyg
Posts: 1979
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: 7” Pi display screen overlay text.

Wed Oct 11, 2017 10:27 pm

The example was py2 but using 'import tkinter' will make it work with py3 (not sure about pynput, haven't installed that)
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

RDS
Posts: 535
Joined: Tue Oct 06, 2015 8:17 am
Location: Lancashire, UK

Re: 7” Pi display screen overlay text.

Wed Oct 11, 2017 10:32 pm

Thanks Paddy, I had tried tkinter but then it failed at the pynput line, so I thought it best to ask before going further.

User avatar
paddyg
Posts: 1979
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: 7” Pi display screen overlay text.

Wed Oct 11, 2017 11:26 pm

One issue with the borderless tkinter Label system is that using overrideredirect stops the normal tkinter keyboard input. Which could have been done with

Code: Select all

def on_left(key):
  global volume
  volume -= 1
  label.config(text="Volume "+"%02d" % volume)
...
t1.bind('<Left>', on_left)
...
which would be simpler if you didn't mind about the window title bar. I've not used pynput but you can do a very similar thing with curses (which doesn't need anything to be installed). For completeness this would be a py3 curses version (though the OP seems to have found a completely different approach)

Code: Select all

from tkinter import *
import curses
import threading
import time

volume = 0

def check_input():
    global volume
    key = curses.initscr()
    curses.cbreak()
    curses.noecho()
    key.keypad(1)
    key.nodelay(1)
    keep_running = True
    while keep_running:
      k = key.getch()
      if k != -1:
        if k == 27: #esc to quit
          curses.nocbreak()
          key.keypad(0)
          curses.echo()
          curses.endwin()
          t1.quit()
          keep_running = False
        elif k == ord('+'):
          volume += 1
        elif k == ord('-'):  
          volume -= 1
        label.config(text="Volume "+"%02d" % volume)
      time.sleep(0.1)

t = threading.Thread(target=check_input)
t.start()

t1 = Tk()
t1.overrideredirect(True)
label = Label(t1, text="Volume "+"%02d" % volume, width=12, font=('aharoni', 28, 'bold'), fg='red')
label.grid(padx=10, pady=5, row=0, column=0, sticky='W,E,N,S')
t1.lift()
t1.mainloop()
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Return to “Python”

Who is online

Users browsing this forum: No registered users and 13 guests