LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   display a variable in guizero app? (https://www.linuxquestions.org/questions/programming-9/display-a-variable-in-guizero-app-4175661315/)

RonHof 09-22-2019 06:32 PM

display a variable in guizero app?
 
I have the following code the reads and decodes a string on serial port ttyUSB0:
Code:

#!/usr/bin/env python
import time
import serial
import string

   
ser = serial.Serial(

        port='/dev/ttyUSB0',
   
        baudrate = 4800,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        bytesize=serial.EIGHTBITS,
        timeout=1
)
while 1:
        Str = ser.readline(8)
        Str = Str.decode('cp1252','strict')
        print ("decoded string: ")
        print (Str)  # Print decoded string

and I have the following code to create a guizero app that displays the number 999.99 in this case. It works as expected.
Code:

#!/usr/bin/env python

import time, serial, string

from guizero import App, Text
app = App(title="Video Scoreboard", height=300, width=400)



message = Text(app, text="999.99",
            size=500,
            font="Times New Roman",
            color="white",
            bg="black"
            )
app.display()

It works as expected. I'm trying to replace the "999.99" in the app with Str from Str.decode but so far no luck

NevemTeve 09-22-2019 11:50 PM

Exactly what did you try and what was the error message?

astrogeek 09-23-2019 03:08 PM

I have no familiarity with guizero, even so it is difficult to understand the question without needing to know that detail.

What does this produce, exactly? Is it what you expected?

Code:

while 1:
        Str = ser.readline(8)
        Str = Str.decode('cp1252','strict')
        print ("decoded string: ")
        print (Str)  # Print decoded string

If not then how does it differ from what is sent to the serial port?

If it is correct then how are you passing it to your app object? We can see no attempt to set that value in the code you have posted.

Please review the Site FAQ for guidance in posting your questions and general forum usage. Especially, read the link in that page, How To Ask Questions The Smart Way. The more effort you put into understanding your problem and framing your questions, the better others can help!

RonHof 09-23-2019 05:16 PM

OK I have a legacy hardware device, a timer, that sends a floating point number between 0.00 and 999.99 as a coded stream. I have this device connected to the usb port on my Raspberry Pi. The first snippet of code reads and decodes the serial stream and displays the floating point number on the command line as I hoped it would. I want to display this number in the App. So far I haven't figured out how to do this. The app as posted displays the text 999.99 without any error messages. I only posted the code that I had working so you might see where I am trying to go. I tried putting the serial read and decode inside the app, that is between the app= and app.display, but all I get is a blank app window. No error messages. I also tried the TextBox widget but it would only read inputs from the keyboard. I have seen lots of windows displaying text and number data from outside sources so I assume there is some straight forward way to do this but I don't know how to proceed.
Thanks for your help

michaelk 09-23-2019 05:33 PM

guizero uses the Tkinter library and is supposed to be make it easier to create GUI applications.

It was my suggestion in another thread by the OP to use guizero as a way to display the decoded value received on the serial port in a window. The OP wants to incorporate the code from their command line python script into the GUI script. Unfortunately, I might of implied there was nothing to it... However, it is bit more complicated then the provided tutorials. Maybe I can find some decent code examples.

RonHof 09-25-2019 05:13 PM

still looking and reading... currently pursuing tkinter 'listbox' and tkinter.listvariable. Does this seem to be a useful direction?

RonHof 10-04-2019 02:16 PM

display a string in Tkinter?
 
I have the following code that gets a string from ttyUSB0.
Code:

#!/usr/bin/env python

import time
import serial
import string



ser = serial.Serial(

        port='/dev/ttyUSB0',
        baudrate = 4800,
        timeout=1
)
while 1:
        Str = ser.read(8)
        Str = Str.decode('cp1252','strict')
        dtime = (Str)     
       
        print ("decoded string: ")
        print (dtime)  # Print decoded string

It works and returns the decoded string to the command line.

I am also trying to create a GUI to display it. So far I have the following code that works in so far as it does display the word TEST and the QUIT button works
Code:

#!/usr/bin/env python

import tkinter as tk
import tkinter.font as tkFont
import time
import serial
import string
###############################################################################
# Parameters and global variables

# Default font size
font_size = -24

# Declare global variables
root = None
dfont = None
frame = None
dtime = None

# Global variable to remember if we are fullscreen or windowed
fullscreen = False

###############################################################################
# Functions

# Toggle fullscreen
def toggle_fullscreen(event=None):

    global root
    global fullscreen

    # Toggle between fullscreen and windowed modes
    fullscreen = not fullscreen
    root.attributes('-fullscreen', fullscreen)
    resize()

# Return to windowed mode
def end_fullscreen(event=None):

    global root
    global fullscreen

    # Turn off fullscreen mode
    fullscreen = False
    root.attributes('-fullscreen', False)
    resize()

# Automatically resize font size based on window size
def resize(event=None):

    global time_dfont
    global button_dfont
    global frame

    # Resize font based on frame height (minimum size of 12)
    # Use negative number for "pixels" instead of "points"
    new_size = -max(12, int((frame.winfo_height() / 2)))
    time_dfont.configure(size=new_size)
    new_size = -max(12, int((frame.winfo_height() / 30)))
    button_dfont.configure(size=new_size)


# Read values from ttyUSB0 at regular intervals
def update():

    global root
    global dtime

    # Get time:
         
    # read anb decode steps were inserted here   

    # Construct string out of time:

    dtime.set('TEST')

    # Schedule the poll() function for another 500 ms from now
    root.after(500, update)

###############################################################################
# Main script

# Create the main window
root = tk.Tk()
root.title("My Clock")

# Create the main container
frame = tk.Frame(root, bg='black')

# Lay out the main container (expand to fit window)
frame.pack(fill=tk.BOTH, expand=1)

# Variables for holding timer data
dtime = tk.StringVar()


# Create dynamic font for text
time_dfont = tkFont.Font(family='Courier New', size=font_size)
button_dfont = tkFont.Font(size=font_size)

# Create widgets
label_time = tk.Label(  frame,
                        textvariable=dtime,
                        font=time_dfont,
                        fg='red',
                        bg='black')
button_quit = tk.Button(frame,
                        text="Quit",
                        font=button_dfont,
                        command=root.destroy,
                        borderwidth=0,
                        highlightthickness=0,
                        fg='gray10',
                        bg='black')

# Lay out widgets in a grid in the frame
label_time.grid(row=0, column=0, padx=20, pady=20)
button_quit.grid(row=1, column=0, padx=5, pady=5, sticky=tk.E)

# Make it so that the grid cells expand out to fill window
frame.rowconfigure(0, weight=10)
frame.rowconfigure(1, weight=1)
frame.columnconfigure(0, weight=1)

# Bind F11 to toggle fullscreen and ESC to end fullscreen
root.bind('<F11>', toggle_fullscreen)
root.bind('<Escape>', end_fullscreen)

# Have the resize() function be called every time the window is resized
root.bind('<Configure>', resize)

# Schedule the poll() function to be called periodically
root.after(20, update)

# Start in fullscreen mode and run
toggle_fullscreen()
root.mainloop()

However when I try to put the read and decode steps into the GUI it only displays a blank window. I was trying to do this after the comment # GET time
I think I need to get the decoded string into dtime.set. If so, how do I do that? or is there a better easier way to do it?

Lawsie 10-09-2019 02:08 AM

You can’t use infinite loops with a GUI, there’s an explanation why here:
https://lawsie.github.io/guizero/blocking/

Here is a guizero example of how to read data from a sensor (in the example the sensor is just simulated by generating a random number)

https://github.com/lawsie/guizero/bl...ate_example.py

RonHof 10-13-2019 11:57 AM

Anchor text in widget?
 
I have made up a GUI with the following code. I believe I have a problem with anchoring the text in the label_time widget. The text is not always in the same location. Sometimes it is even wrapped onto two lines. I'm trying to get the text to always display centered in the label_time widget. I would also like to adjust the size of the font, but I think that is a problem to be addressed in another thread. There are no error messages when I execute the code.

Code:

#!/usr/bin/env python3
import tkinter as tk
import tkinter.font as tkFont
import time
import serial
import string
###############################################################################
# Parameters and global variables
# open serial port ttyUSB0
ser = serial.Serial(
        port='/dev/ttyUSB0',
        baudrate = 4800,
        timeout=1)
# Default font size
font_size = -12
# Declare global variables
root = None
dfont = None
frame = None
dtime = None
# Global variable to remember if we are fullscreen or windowed
fullscreen = False
###############################################################################
# Functions

# Toggle fullscreen
def toggle_fullscreen(event=None):
    global root
    global fullscreen
    # Toggle between fullscreen and windowed modes
    # fullscreen = not fullscreen
    root.attributes('-fullscreen', fullscreen)
    resize()
# Return to windowed mode
def end_fullscreen(event=None):
    global root
    global fullscreen
    # Turn off fullscreen mode
    fullscreen = False
    root.attributes('-fullscreen', False)
    resize()
# Automatically resize font size based on window size
def resize(event=None):
    global time_dfont
    global button_dfont
    global frame
    # Resize font based on frame height (minimum size of 12)
    # Use negative number for "pixels" instead of "points"
    new_size = -max(12, int((frame.winfo_height() / 2)))
    time_dfont.configure(size=new_size)
    new_size = -max(12, int((frame.winfo_height() / 30)))
    button_dfont.configure(size=new_size)
# Read values from ttyUSB0 at regular intervals
def update():
    global root
    global dtime
    # Get time 
    Str = ser.readline(8)
    Str = Str.decode('cp1252','strict')
    # Construct string out of time
    dtime.set(Str)
# Schedule the poll() function for another 10 ms from now   
    root.after(10, update)
###############################################################################
# Main script
# Create the main window named root
root = tk.Tk()
root.title("My Clock")
# Create the main container
frame = tk.Frame(root, bg='black')
# Lay out the main container (expand to fit window)
frame.pack(fill=tk.BOTH, expand=1)
# Variables for holding timer data
dtime = tk.StringVar()
# Create dynamic font for text
time_dfont = tkFont.Font(family='Courier New', size=50) #change font size
button_dfont = tkFont.Font(size=font_size)
# Create widgets
label_time = tk.Label(  frame,
                        textvariable=dtime, #inserts display time here
                        font=time_dfont,
                        fg='red',
                        bg='black',
                        justify = 'left',
                        anchor = 'center')
button_quit = tk.Button(frame,
                        text="Quit",
                        font=button_dfont,
                        command=root.destroy,
                        borderwidth=0,
                        highlightthickness=0,
                        fg='gray10',
                        bg='black')
# Lay out widgets in a grid in the frame
label_time.grid(row=0, column=0, padx=5, pady=5,)
button_quit.grid(row=1, column=0, padx=5, pady=5, sticky=tk.E)
# Make it so that the grid cells expand out to fill window
frame.rowconfigure(0, weight=10)
frame.rowconfigure(1, weight=1)
frame.columnconfigure(0, weight=1)
# Bind F11 to toggle fullscreen and ESC to end fullscreen
root.bind('<F11>', toggle_fullscreen)
root.bind('<Escape>', end_fullscreen)
# Have the resize() function be called every time the window is resized
root.bind('<Configure>', resize)
# Schedule the poll() function to be called periodically
root.after(20, update)

toggle_fullscreen()
root.mainloop()



All times are GMT -5. The time now is 04:50 AM.