Main Menu

search

You are here

GUIzero

[last updated: 2024-09-25]
Python: Programming
widget Colors
(link to:) Github: widget documentation
(link to:) Github: GUIzero Help
Great tutorial: https://dev.to/jr_shittu/getting-started-with-graphical-user-interfaces-...
other good tips: https://lawsie.github.io/guizero/usingtk/
https://github.com/rdbende/Azure-ttk-theme
https://github.com/TomSchimansky/CustomTkinter
also research: tkbootstrap and PyQt
-----

  • A python3 library for creating easy GUI's.
    Can be used along with Tkinter.

  • Installation:
    • Installation: (link to:) lawsie.github
    • Tkinter is (these days) supposedly bundled with rPiOS, so no need to install it separately.
      But if you need to install it:
        $ sudo apt install python3-guizero
        (I have not personally tested this...)
    • Install guizero:
        This was troublesome on my rPi's.
        I hacked around and managed to get it done, but as usual have no clue what actually made it work,
        but here are the things I did:
          $ ... update
          $ ... upgrade
          $ ... dist-upgrade
          loaded new rPiOS (probably what worked...)

        Actual install command, from terminal:

          $ sudo apt install python3-guizero
    • Install gpiozero:
      This is a package that allows easy programming for physical gpio on the rPi.
      It is not required to run guizero, but it IS required if you're going to interface with any of the rPi gpio pins.
      It is bundled with the current rPiOS, but if you need to install it manually...
      (link to:) gpiozero docs
      (link to:) install gpiozero
        $ sudo apt install python3-gpiozero

  • Run:
    • Create testProg.py (or whatever filename you want), and write your GUI code into the python file.
    • Execute it from CLI with:
      $ cd [location of python program]
      $ sudo python3 testProg.py

    -----------------------------------------------------

  • Python GUI program:
    • First line is import line(s):
        from guizero import *

      This is a simple minimum. If you want to preserve ram, you might want to only import the specific guizero modules that you'll be using, eg:

        from guizero import App, Box, PushButton
    • There may be programs that require additional imports, eg:
        from tkinter import *

      I saw one forum note saying if you use tkinter, the import line must be first, ie. above/before the import guizereo line.

    • Next lines in your .py program will be def lines, ie. function definitions
      If your GUI is going to do anything, interact with the user, then you need a function to tell it what to do.
      You define funtions with:
        def funcName():
          [program statements]
          eg:
          print("Hello World")
          varName1 = "sayWhat"
          varName2 = 47

      The "funcName" is the variable you assign to refer to the function.
      As always in python, proper indentation is essential.
      Program statements in a def must be indented 4 spaces.
      The end of the def is signaled by a return to no indent
      -----------------------------------------------------

    • Next you create your main window using the App module:
      • mainWindow = App()
        "mainWindow" is the variable name you assign. App is the guizero module that you call to create the window.
          A lot of online forums and tutorials use "app" as the variable name for your main window, eg: app = App()
          Do not confuse this variable name ("app") with the module name "App".
      • Like all guizero objects, an App object has its own set of:
        • parameters that can be set at time of creation.
        • properties that can be get and set after creation.
          Some properties are also parameters.
        • methods or operations/functions that can be performed on them.
      • When you create an App object (or any guizero object), you can define your desired parameters by placing them inside the "( )".
        Multiple parameters are separated by commas.
        There are no minimum/required parameters for an App object.
          For example:
          mainWindow = App(bg="blue", title="myMainWindow", width=500, height=500)
      • Documentation for the App object is here: https://lawsie.github.io/guizero/app/

      • Parameters: (*** denotes they are also properties)
        • bg = background color (default none) ***
        • height & width in pixels (default 500) ***
        • layout - either "auto" or "grid" (including quotes) ***
        • title - text displayed at the top of the window ***
        • visible - True or False ***
      • Properties: (that are not also parameters)
        • children - a list of widgets in this container
        • font - string fontName for widgets contained
        • full_screen - True or False (default)
        • enabled - True or False
        • image - string pathName to image
        • text_size -
        • text_color -
        • tk - the internal tkinter object
        • when_closed - function name to call if the App is closed
      • Methods:
          see: Documentation link above

      -----------------------------------------------------

    • ADD WIDGETS:
      • Widgets can be placed inside 3 different types of containers/objects: App, Box, and Window. (plus TitleBox ??)
        When you first start your program, the main window (App) is the only one you have, so that's where your first widgets must be placed.
      • This task is complicated, because there are 14 widgets to choose from (by my count, not including App),
        each with its own set of parameters, properties, and methods.
        Important/basic ones you'll surely use include:
        • Box:
          • Create a box:
            boxName = (mainW) - this is minimum declaration (however height and width should also be specified)
            mainW is the name of the widget where the box will be placed. it must be either an App, a Box, or a ... widget.
          • Parameters:
            These are the things that can be specified when you create the widget:
            • master - the name of the container, inside of which the box will be placed
            • layout - "auto" or "grid" - to specify how widgets that are placed inside this box will be arranged ***
            • grid - if the box's master container has layout "grid", ***
              then this parameter specifies where in the master widget's grid this box will be placed.
              Default is None, or you can specify a coordinate with ... = [x, y]
            • align - if the box's widget location has layout "auto" ***
              then you can set align = "top" or "bottom" or "left" or "right"
            • height and width - in pixels or "fill" to span the full dimension of its containing widget ***
            • border - 0 or False for no border, True for a border of 1, or an integer > 1 for a wider border ***
            • visible - True or False ***
            • enabled - True or False ***
          • Properties: (that are not also parameters)
            • bg -
            • children -
            • font -
            • text_size -
            • text_color -
            • tk -
          • Methods:

          ----------

        • PushButton:
          • Create a pushButton:
            PB1 = PushButton(mainW, command=doSomething)
            These are the minimum parameters that must be speficied: master = name of the container where the PB will be placed,
            and command is the name of the function that will be executed when you push the PB.
          • Parameters:
            These are the things that can be specified when you create the widget:
            • master - the name of the container, inside of which the PB will be placed
            • command - name of the function that will be executed
            • args - this is the comma-separated list of arguments you want to pass to the command function
              eg: PBx = PushButton(mainW, command=doThis, args= ...syntax?...
            • text -
            • image -
            • grid - if the PB's master container has layout "grid",
              then this parameter specifies where in the master widget's grid this PB will be placed.
              Default is None, or you can specify a coordinate with ... = [x, y]
            • height and width - in characters or "fill" to span the full dimension of its containing widget
            • padx and pady - pixels of spacing between edge of PB and any text placed in it
            • text - to be displayed
            • visible and enabled - True or False (default True)
          • Properties:
            These are like (and a few are identical to...) parameters used in the widget definition statement.
                They can be get:
                  eg: print(PB1.bg)
                or set:
                  eg: PB1.bg = "red"

          • Using tk.config:
            • I suspect these are tk widget properties...
            • PB1.tk.config(borderwidth = 6)
          • Methods:
            ----------

            • bg - background color
            • align
            • enabled and visible - True or False
            • font - a string name of the font style of the text on the button
            • grid - [x,y] coordinates of this widget in its container's grid
            • height and width - in characters or pixels (???) or "fill"
            • image - string of path to image
            • master
            • text - string to be displayed
            • text_color
            • text_size - in pixels
            • tk - tkinter.Button - The internal tkinter object, see Using tkinter
            • value - int - returns 1 when the button is pressed, else 0

          ----------

        • Text:
          ----------
        • TextBox:
          ----------

        • As said, widgets can get complicated. Here's my page of more details.

        -----------------------------------------------------

      • Layout:
        How/where will your widgets be placed?
        • An important concept to understand:
          • When you create a widget, you must put it inside a container.
            App, Window, and Box objects in your system can all act as containers (masters) to contain other widgets.
          • The first object you create is your mainWindow. It must be done with the App module:
              mainWindow = App()

        • Every subsequent object/widget you create will be placed inside some already existing container (App, Window, or Box).
            This is specified with the first parameter (the 'master' parameter) in your widget definition statement:
              widget2Box = Box(mainWindow)
        • The second object you define (we'll call this your first widget) must be inside your mainWindow, because that's the only container you have when you start.
          Now when you create your second widget, whatever it may be,
          you may have a choice of which container to put it into.
          If your first widget is a Box or a Window or an App, then it can act as a container for your second widget.
          In that case, when you define your second widget, you can choose whether to put it into your original mainWindow (App),
          or whether to put it into your first widget (assuming it's a Box, or a Window, or an App object).
            widget3Box = Box(mainWindow)
            -or- widget3Box = Box(widget2Box)
        • Exact position/placement inside the container where your new widget will be placed
          is determined by the "layout" and other properties that you specify when you create the containers.
        • The "layout" parameter can be either "auto" or "grid"
          • Layout is set when you define your object/widget/window. For example:
              mainWindow = App(layout="auto")
          • If you specify an "auto" layout (the easiest/simplest), for your object/container, then
            widgets placed in it will be centered and stacked vertically
            (unless it's a box and you've specified something different with the "align" parameter).

      -----------------------------------------------------

    • Finally, the last line of your .py program must be:
        mainWindow.display()

      This is the line that executes/renders your GUI creation onto your screen.
      This starts an infinite update loop that continuously waits for (and responds to) events,
      like mouse movements, clicks, or text typed into text boxes, etc.


    -----------------------------------------------------
    from guizero import App, Text
    from tkinter import Label

    a = App()
    text_1 = Text(a, text="text 1")
    label = Label(a.tk, text="label")
    label.pack()
    text_2 = Text(a, text="text 2")

    a.display()
    -----------------------------------------------------

  • Links:

    -----

  • to investigate:

    from:
    https://github.com/lawsie/guizero/issues/434

    from guizero import App, Text
    from tkinter import Label, PhotoImage

    app = App("I have a background image")

    # Some raw tkinter to create the bg image
    img = PhotoImage(file="bgimage.png")
    label = Label(app.tk,image=img)
    label.place(x=0, y=0)

    # Text on top, but it will have a background
    some_text = Text(app, "This is some text")

    app.display()
    ----------------------------------------------------------------

    from:
    https://github.com/lawsie/guizero/issues/399

    You can access the underlaying TK object and set its options, in this case the borderwidth (or bd) property

    from guizero import App, PushButton

    app = App("A picture button")

    picture_button = PushButton(app, image="guizero.gif")
    picture_button.tk.config(borderwidth = 0)

    app.display()
    ----------------------------------------------------------------
    im = Image.open(pathToImage)
    ph = ImageTk.PhotoImage(im)

    label = Label(window, image=ph)
    label.image=ph #need to keep the reference of your image to avoid garbage collection
    ----------------------------------------------------------------

.

.

.

eof