Giter Site home page Giter Site logo

lawsie / guizero Goto Github PK

View Code? Open in Web Editor NEW
393.0 24.0 80.0 8.63 MB

A Python 3 library to allow learners to quickly and easily create GUIs.

Home Page: https://lawsie.github.io/guizero

License: BSD 3-Clause "New" or "Revised" License

Python 99.94% CSS 0.06%

guizero's Introduction

version number

guizero

guizero is a Python 3 library for creating simple GUIs.

It is designed to allow new learners to quickly and easily create GUIs for their programs.

Have a go with guizero and see what you can create

from guizero import App, Text, PushButton

app = App(title="guizero")

intro = Text(app, text="Have a go with guizero and see what you can create.")
ok = PushButton(app, text="Ok")

app.display()

Install

If you can download and unzip a file, you can install guizero - no special permissions or administrator rights are required.

If you have administrator rights and are connected to the internet, you can use the command line to install or upgrade guizero.

Documentation

Comprehensive documentation can be found at lawsie.github.io/guizero including:

Aims

The aim of guizero is to make the process of creating simple GUIs quick, accessible and understandable for new learners.

  • Works with standard Python Tkinter GUI library (and no need to install other libraries)
  • Abstracts away details new learners find difficult to understand (such as Tkinter StringVar() objects)
  • Accessible widget naming system to help new learners to build up a mental model
  • Flexible enough to be used for projects up to A-Level standard, yet accessible to primary school children
  • Comprehensive and accessible documentation with examples
  • Generates helpful additional error messages

Contributing

Contributions are very welcome - please see lawsie.github.io/guizero/contributing for notes, build and deployment instructions.

Issues

All issues should be raised on github.com/lawsie/guizero/issues

Book

The authors of guizero have written a book for beginners which you can buy in print or download as a free PDF.

guizero's People

Contributors

bcroston avatar bennuttall avatar bgiobbe avatar bsimmo avatar carlosperate avatar coal0 avatar deejay avatar hyle01 avatar james-pcdr avatar jezdean avatar johnkershaw avatar knowledgejunkie avatar lawsie avatar m4ddav3 avatar martinohanlon avatar mbkulik avatar miyucode avatar objectdisorientedprogrammer avatar paulatdunedin avatar ukbaz avatar wgarrity-1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

guizero's Issues

Add useful docstrings

(Not unrelated to #38)

At present if you help() the package itself or any of its components, you basically get the whole Tk stack and no overview. In general, in Python, encourage exploration via introspection (help, dir, inspect etc.). And tools like IPython and the built-in docs browser support that to a considerable extent.

Here's an example from my own networkzero:

Help on module networkzero.discovery in networkzero:

NAME
networkzero.discovery - Advertise and collect advertisements of network services

DESCRIPTION
The discovery module offers:

    * A UDP broadcast socket which:

      - Listens for and keeps track of service adverts from this and other
        machines & processes
      - Broadcasts services advertised by this process

    * A ZeroMQ socket which allow any process on this machine to
      communicate with its broadcast socket

In other words, we have a beacon which listens to instructions
from processes on this machine while sending out and listening
to adverts broadcast to/from all machines on the network.

The beacon is started automatically in a daemon thread when the first
attempt is made to advertise or discover. If another process already
has a beacon running (ie if this beacon can't bind to its port) this
beacon thread will shut down with no further action.

The module-level functions to advertise and discover will open a connection
to a ZeroMQ socket on this machine (which might be hosted by this or by another
process) and will use this socket to send commands to the beacon thread which
will update or return its internal list of advertised services.

As an additional convenience, the :func:`advertise` function will, if given no
specific address, generate a suitable ip:port pair by interrogating the system.
This functionality is actually in :func:`networkzero.address` (qv).

FUNCTIONS
advertise(name, address=None, fail_if_exists=False, ttl_s=20)
Advertise a name at an address

    Start to advertise service `name` at address `address`. If
    the address is not supplied, one is constructed and this is
    returned by the function. ie this is a typical use::

        address = nw0.advertise("myservice")

    :param name: any text
    :param address: either "ip:port" or None
    :param fail_if_exists: fail if this name is already registered?
    :param ttl_s: the advert will persist for this many seconds other beacons
    :returns: the address given or constructed</dump>

In this case I'm using Sphinx's auto-doc features to combine this help() text with some other narrative in the documentation, but I see it as very key that people be able to help(mymodule) and get more than the barebones alpha-orderd breakdown of what's in it.

Add support for JPEG

How difficult would it be to add support for JPEG and png image formats? Both of these are very common and would open up many more options for kids.

'text.after' information

Hello,
After help on the forum I was trying too wrap my head around how to have auto updating text boxs, I was kindly linked to the undocumented auto_update_example.py.

Now I can understand what is happening, if I can get my program re-written to this style will be another thing ;-)

the .after is undocumented , I've look through the docs and some code (to do with text) but cannot find how it's implemented.

anyway,
I'm guessing text.after(1000, update_label)
1000 is time in ms ?
update_label is the function call.

Are there any other options or things I should know.

I appreciate this may be beyond guizero's current released usage.

(Basically I'm trying to add a GUI information screen to the SenseHAT datalogging style program)
Although starting with just a GPS coordinate screen with Lang/Lot and Time for proof of concept.

Improve documentation and install process for use in school environments

The problem with pip is it will by default try to install the package in a 'dist directory' which is mostly in a protected directory on school setups, so that means they can't use this lovely package.

If you documented other install procedures, more schools that have locked down IT systems will be able to use this.

I believe based on discussions just now on twitter that guizero is zero dependency. That means you ca do any of the following:

  1. from github press the clone or download button, then download as zip. Unzip the zip file and copy the guizero folder into the students home folder, and then they should be able to just write python and import guizero and it should all work. This completely avoids bumping into any school protected directory issues.

  2. If the school PC has write access to the distdir on the computer C drive, you might be able to run this from a command line:

python setup.py

My preference is (1) as in all the schools I work in, the dist-dir of python is in a read-only folder on the network or on the local disk and cannot be modified.

The fact that the guizero folder is in the same folder as the children's code means that when you 'import guizero' it will find it (That's the purpose of the init.py in guizero so it is recognised as a package folder).

Hope this helps - but it would be great if someone could update the README to describe this as the preferred method of installation, and offer the pip install option as an alternative route for schools that have much less locked-down environment.

Reading 2 sensors

This program that reads one sensor works very well but when using two sensors it stops working after about five minutes.

I am more then satisfied with this program just not sure what would cause the graphics program to stop reading using two sensors.

``
from guizero import App, Text
def update_writing():

      A = open ("/sys/bus/w1/devices/28-00000781336e/w1_slave")

      B = A.read()

      A.close()

      C = B.split("\n")[1].split(" ")[9]

      D = float(C[2:])

      E = D/1000

      A1 = open ("/sys/bus/w1/devices/28-0000079ee449/w1_slave")

      B1 = A1.read()

      A1.close()

      C1 = B1.split("\n")[1].split(" ")[9]

      D1 = float(C1[2:])

      E1 = D1/1000
      

      if E < 85:

       T = ('S1',E,'S2',E1)      

       print('SENSOR 1: ',E)

       print('SENSOR 2: ',E1)

       
              
       writing.set(T)
       app.after(200, update_writing) 

app = App(height=1000, width=1000,bgcolor="black")

writing = Text(app, text="TEMP C", color="red",size=50)

writing = Text(app, text="", color="red",size=50)

writing.pack(fill="none", expand=True)

app.after(200, update_writing)
app.display()

`ButtonGroup` `horizontal` argument has inverse result

Supplying horizontal=True to ButtonGroup.__init__ makes the widgets pack below one another. horizontal=False (default) causes them to pack next to each other. Isn't that the opposite of what is supposed to happen? I'm kind of confused about this one. Technically, each widget gets assigned its own horizontal line (row), so this could be the expected behavior. Just curious.

Colour as R,G,B

Would it be possible to implement colour/color as R,G,B values.
For instance in waffle.getpixel will return 'white', that means nothing to me, neither would blue or green or pink etc.
Hex values also mean little to me, but I do know what 200, 100, 178 means and I would then easily know and implement reducing the Green colour darker and return it back easily.

I could then set the colour pink to be any shade of pink I wanted, for example
pink=(255,190,200)

Perhaps look at the RPF SenseHat / gpiozero implementations if the have them to keep it consistant*?

Store docs content in markdown not html

I was just about to send a couple of PRs with docs fixes but found you don't store the markdown source on github!

If you keep the markdown in the docs folder, and set it to build html into another folder (or use a different branch for github pages) - would help people trying to contribute :)

updating on Raspian -U not --upgrade ?

I think, i.e. I had to use,
sudo pip3 install -U guizero to update the package on the latest Raspbian not
sudo pip3 install guizero --upgrade it say unknown command.

Suggestion: Remove try...catch on the import of tkinter in the controls

Each control has a try...catch to handle failure to import tkinter. However, this is handled in the App and Box classes, whose instances are passed to the controls. To save the expense on performance, having try...catch in the controls should not be necessary for this, if already checked when initiating it in the respective container classes.

Clearing a TextBox

I have followed the documentation for using a TextBox and I have used the following code to use a TextBox to test if the text box is working:

from guizero import App, TextBox, PushButton, Text

app = App()

def save_code():
    stuff = input_box.get()
    print(stuff)
    input_box.clear()
    text = Text(app, text = "It is working!")

input_box = TextBox(app, text = "Type here")

button = PushButton(app, command = save_code)
button.set_text("Save")

app.display()

When I click the button I get the following message:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.4/tkinter/__init__.py", line 1536, in __call__
    return self.func(*args)
  File "/home/pi/Python/text_box.py", line 6, in save_code
    input_box.clear()
  File "/usr/local/lib/python3.4/dist-packages/guizero/TextBox.py", line 31, in clear
    self.delete(0, END)
NameError: name 'END' is not defined

This error message gives me the impression that GUI Zero is at fault.

Edit - I have removed the input_box.clear() bit in my code and it all works perfectly. However, whatever I try the TextBox won't clear!

Grid layout looks nasty

Grid layout looks nasty - things are all squashed up and there is no padding. Suggestions for good and easy ways to improve grid layouts? Here are some ideas I had:

  • Making a "blank" widget which just creates a blank space of a specified width/height?
  • Making a "
    " type widget which would just create a horizontal line (spanning multiple cols?)
  • Just use existing methods in tkinter for changing col/row dimensions, but document them (e.g. http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/grid-config.html) ?
  • Encourage the use of lots of Box widgets to divide up the gui
  • Allow rowspans and colspans to be specified for widgets (already exists in tkinter)

CheckBox not displaying, nothing displays after

from guizero import App, CheckBox
app = App()
checkbox = CheckBox(app, text="Add extra glitter")
app.display()

no checkbox displays, and any elements added after checkbox do not display either.

Python 3.5.2

Suggestion: clarify this is a Python 3 package

Since this package targets users that might have limited knowledge about Python versions it might be a good idea to clearly indicate on the README that this is a Python 3 only package.

I would probably go as far as to add this to the setup.py file:

from sys import version_info
if version_info.major != 3:
    print("This package will only work with Python 3. \n" 
          "If you already have Python 3 installed try 'pip3 install guizero'.")

This way it will not break with cryptic messages during installation or first run.

License for Docs

Just a question/issue concerning the license for the documentation. Am I allowed to use a quote from the documentation? If the answer is yes, is there a bit of text I have to insert to show this is not my work? Thanks in advance,
LouisPi

Combo add_option

If an option is add to a combo box with add_option it will appear in the list but it can not be selected.

Below is a modified version of the example from the documentation where an option 'Test' has been added. However, when it is selected from the list the you_chose function is not called. This seems like a bug.

from guizero import *
def you_chose(selected_value):
    result.set("You chose...")
    if selected_value == "Tiny goblet":
        result.append("wisely")
    else:
        result.append("poorly")

app = App()
instructions = Text(app, "Choose a goblet")
combo = Combo(app, ["", "Huge golden goblet", "Jewel encrusted goblet", "Tiny goblet"], command=you_chose)
result = Text(app)
combo.add_option('Test')
app.display()

Add every() method?

As people are often confused by the use of .after() I was wondering about how to simplify it. I wrote this code whcih 1) exposes the after() method, but converts the time to seconds, and 2) creates a new method called every() which you can attach to a widget. The purpose is to automatically register a callback to a function every n seconds, so that people can just write the function and not have to worry about putting the after() line inside it to call it again. I think this would also need a cancel method.

# Set up a callback to a function
def after(self, time, function_to_call):
    time_in_secs = int(time * 1000)
    self.tk.after(time_in_secs, function_to_call)

# Schedule a function every n seconds
def every(self, time, function_to_call):
   time_in_secs = int(time * 1000)

    # Take their function but make it self-call again
    def func_with_self_callback():
        function_to_call()
        self.tk.after(time_in_secs, func_with_self_callback)

    # Register a callback to this function
    self.tk.after(time_in_secs, func_with_self_callback)

So my question is - is this a total disaster for a reason I haven't spotted? It feels like a trap...
cc @bennuttall

`App` properties calling `tk.update`

It's fine that the App properties call tk.update; in fact, that's required for automated testing. However, three things need to be changed for this to work properly:

  • App.__init__ should call tk.update once, to assure that the tests can initialize a new object and get its dimensions without interacting with the properties.
  • The property getters should not call tk.update. It simply makes no sense.
  • The property setters should call tk.update after calling tk.geometry. This way the window changes are applied just before returning.

If you don't mind, I'll open a PR with these changes.

.value properties for widgets

How do you feel about creating .value getter and setter properties for the widgets?

e.g.

a value property would allow CheckBox value to be get and set as a boolean

class CheckBox(CheckButton):

    @property
    def value(self):
        return (self.get_value() == 1)

    @value.setter
    def value(self, value):
        if value:
            self.select()
        else:
            self.deselect()

check = CheckBox()
if check.value:
    check.value = False
    

The same value property could be created for all widgets allowing a simple interface to get and set its value.

Testing?

So I skimmed over the project directory but I couldn't find a 'tests' folder or similar. It's really helpful to have a way to test commits quickly, especially as the project grows larger. Do you mind if I set up a basic testing file that we can expand later (perhaps under a separate folder?)? Thanks.

Large digital numbers from a sensor

I have combine two programs into one, the first program is reading the temperature from a sensor,
the second program is guizero producing large graphics on the screen, numerals or text.
The two programs work fine separately, when combined the read out is just producing one reading it is
not looping to read further information.

What I am trying to do is produce large digital numbers on the screen from the sensor.

Thanks
"""
``
from guizero import App, Text

#main loop
#while True:
tempStore = open("/sys/bus/w1/devices/28-00000781336e/w1_slave") #change this number to the Device ID of your sensor
data = tempStore.read()
tempStore.close()
tempData = data.split("\n")[1].split(" ")[9]
temperature = float(tempData[2:])
temperature = temperature/1000
#print(temperature)
#-------------------------------------------------------------------------------------------------------------------
def update_writing():

T = temperature
writing.set(T)
app.after(200, update_writing)

app = App(height=2000, width=2000,bgcolor="black")
writing = Text(app, text="", color="red",size=110)

writing.pack(fill="none", expand=True)
app.after(200, update_writing)
app.display()

` ``

"""

enable / disable widgets

Simple methods and properties to enable or disable widgets could be useful.

Rather than the setting of state

mycontrol.state(["disabled"])   # Disable the button.
mycontrol.state(["!disabled"])

create properties and methods to simplify e.g.:

mycontrol.enable()
mycontrol.disable()

or create it as a property

mycontrol.enabled = True
mycontrol.enabled = False

A Mixin could be useful as there are multiple controls which could use the same code:

class EnableMixin(object):
    def enable(self):
        return self.state(["!disabled"])
    def disable(self):
        return self.state(["disabled"])

Then each control which needs it could inherit it, e.g.:

class PushButton(Button, EnableMixin)
class Combo(OptionMenu, EnableMixin)

Adhere to OOP concepts

If we stick to OOP concepts, future development will be a lot easier. I suggest creating a widget class which instantiates an underlying tkinter widget of sorts when called:

import tkinter as tk


class _Widget:
    """An abstract `tk` widget."""
    def __init__(self, widgettype, **kwargs):
        """Instantiate `widgettype(**kwargs`)."""
        self._widget = widgettype(**kwargs)

    def enable(self):
        """Enables the widget."""
        self._widget.configure(state="normal")

    def disable(self):
        """Disables the widget."""
        self._widget.configure(state="disabled")

We can then simply create _Widget subclasses, without the cluttered default Tcl options:

import tkinter as tk

from _widget import _Widget


class Text(_Widget):
    """A Text widget displays text."""
    def __init__(self, text="", size=12, color="black", font="helvetica", grid=None, align=None):
        super().__init__(
            widgettype=tk.Label,
            text=text,
            size=size,
            foreground=color,
            font=font
        )
        # Do stuff with `grid` and `align`...

This has a couple of advantages:

  • Methods that can be applied to all widgets (like enable / disable for switching state, repeat to repeat a callable every x milliseconds and display options for hiding, showing, aligning widgets) can be inherited from _Widget.

  • Reusing methods means having to write only one docstring (e.g. _Widget.enable: 'enables the widget' instead of Text.enable: 'enables the text widget'; Button.enable: 'enables the button widget'; etc.)

  • Validating argument types / values can be done within _Widget.__init__ (or using helper functions) instead of doing this individually for each widget type.

What do you think?

Waffle: Memory and Redrawing Pixels

More a proposal for consideration rather than an issue.
This follows a discussion on Twitter with @scottofthedead1 (me), @coding2learn and @codeboom

  1. Each time the colour of a pixel is changed, a new object is drawn on to the canvas over the top of the existing pixel. This seems to have an adverse behavior of the application if the pixels are changed many times. I have a fix that stores the object id of each pixel in the init function and then uses the canvas.itemconfig method to modify the fill colour of the existing pixel rather than drawing a new one.

  2. Given that I'm saving the object ids of the pixels there is no longer any need to have a separate array containing the colour of each pixel as I can query the fill of each object. With this, I'd propose getting rid of the remember attribute of Waffle and the save_colors array.

Any thoughts about how this might impact existing applications or backwards compatibility?
I have some working code that needs tidying up so can make a pull request against whichever branch.

Tempurature GUI solved

Rewrote the program and fixed some indent errors problem solved working very nicely.
Removing the loop still had problems, then rewrote program made a big difference.
Large print that can be seen from a distance on the screen.
Hard work and late nights paid off.

Thanks

import time
from guizero import App, Text
def update_writing():
        
          D = open ("/sys/bus/w1/devices/28-00000781224h/w1_slave")	#change this number to the Device ID of your sensor
          D1 = D.read()
          D2 = D1.split("\n")[1].split(" ")[9]
          D3 = float(D2[2:])
          T = D3/1000
           # print(T) testing only

          time.sleep(2)
          
          writing.set(T)
          app.after(200, update_writing)
app = App(height=2000, width=2000,bgcolor="black")

writing = Text(app, text="", color="red",size=400)

writing.pack(fill="none", expand=True)
app.after(200, update_writing)
app.display()
`` `` ``

Made a dice rolling app relying on guizero.

It works pretty well. The only thing I could not seem to get it to do was clear the text of the output, so I just wrote spaces over the text each time. :)

Anyway, here is a guizero based dice roller for anyone interested. It's a good way to understand the use of global variables. I usually output everything to the terminal to have a history and validate the operations of the program.

https://github.com/maskedmakrel/VirtualDicePy/blob/master/guiroller.py

Good luck with the guizero project.

GUI has a white background

Program is working fine, the overall GUI has a black background not a problem, with the print out there is a white border surrounding the print out, any way of changing that to black.

Thanks

`from guizero import App, Text

def update_writing():

A = 50

B = 60

C = 70

lst = ['WORLD',A,B,C,'HELLO'] # This line added

D = (' '.join((str(x) for x in lst))) # This line added

writing.set(D)

app.after(200, update_writing)

app = App(height=2000, width=2000, bgcolor="black")

writing = Text(app, text="", color="red", size=100)

app.after(200, update_writing)

writing.pack(fill="none", expand=True)

app.display()`

GUI on screen shows brackets and commas.

I am more then satisfied with this working example, the program works beyond expectation.

Is there any way of stopping the print out on the screen from showing brackets, commas.

Any input would be most appreciated.

Thanks

``from guizero import App, Text

def update_writing():

A = 50

B = 60

C = 70

D = ("WORLD",A,B,C,"HELLO")

writing.set(D)

app.after(200, update_writing)

app = App(height=2000, width=2000, bgcolor="black")

writing = Text(app, text="", color="red", size=100)

app.after(200, update_writing)

writing.pack(fill="none", expand=True)

app.display()
``

Add kwargs to GUI Components

Could you add **kwargs to the constructor of your GUI components and then pass it to the __init__of the base Tk class? This way you could pass variables direct to Tk. e.g. setting a CheckBox to be disabled at initialisation :

class CheckBox(Checkbutton):

    def __init__(self, master, text, command=None, grid=None, align=None, **kwargs):  
      
        self.text = str(text)
        self.description = "[CheckBox] object with text " + self.text
        self.value = IntVar()

        try:
            super().__init__(master, text=self.text, variable=self.value, kwargs)
.....

check = CheckBox(state = "disabled")

I havent tested this but I think it would work.

It would allow you to open up the functionality of Tk without having to add all the variables to each of your components.

Suggestion: when two options are available, use True/False over strings

Just a suggestion, but it's something we we do with gpiozero.

In RPi.GPIO, setting up an input pin looks like:

GPIO.setup(pin, GPIO.IN, GPIO.PUD_UP)

or:

GPIO.setup(pin, GPIO.IN, GPIO.PUD_DOWN)

where PUD_UP means "pull-up or down: up" and PUD_DOWN means "pull-up or down: down".

In gpiozero, we assume pull-up by default, so a button created like this:

button = Button(17)

is pulled-up. To use pull-down:

button = Button(17, pull_up=False)

So the init parameter is pull_up=True by default. The logic of calling the parameter "pull_up" (after the default) rather than the name of the two options (e.g. "pull_direction") means it's unused when set to default, and to do the lesser used behaviour, it's just pull_up=False rather than pull_direction="down".

I wondered if you might do this with things like orient="horizontal" as there are only two options, so it would become horizontal=True by default. This also removes the need to worry about casing (beyond True/true False/false of course...)

Feel free to ignore!

GUI ZERO centre text to the middle of the screen

Gui zero is a great program just having trouble trying to center the text to the middle of the screen.
Is there another function that centers text to the middle of the screen.

Any help would be greatly appreciated.

Thanks

from guizero import App, Text, TextBox

def update_writing():

A = ('World')
writing.set(A)
app.after(200, update_writing)

app = App(height=2000, width=2000,bgcolor="black")

writing = Text(app, text="", color="red",size=110,grid=[4,0], align="center")

app.after(200, update_writing)

app.display()

Unicode character support on buttons

I thought it might be helpful to share my learnings about getting unicode characters to appear (or not) on buttons. It might be good to include an example in the documentation. (Or maybe just have this ticket to refer people to).

I wanted to have arrows on my buttons so sourced the unicodes from:
http://www.w3schools.com/charsets/ref_utf_arrows.asp
To get this to appear on a button you do the following:

button2 = PushButton(box_obj, forward, text=u'\u2191', grid=[0, 1])

I also have got a noise and mute button on my GUI. I found some suitable unicode which works in Python.
For example:

~ $ python3
Python 3.4.2 (default, Oct 19 2014, 13:31:11) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> u'\U0001F508'
'๐Ÿ”ˆ'
>>> u'\U0001F507'
'๐Ÿ”‡'

However this doesn't work in the tkinter as it appear tcl doesn't supprt UTF-16 so I get the following error:

$ python3 python/guizero/examples/bitbot_example.py 
scanning...
Traceback (most recent call last):
  File "python/guizero/examples/bitbot_example.py", line 97, in <module>
    _build_horn_section(buz_btns)
  File "python/guizero/examples/bitbot_example.py", line 77, in _build_horn_section
    buzz_on = PushButton(box_obj, bitbot.buzzer_on, text=u'\U0001F508', grid=[0, 0])
  File "/home/pi/python/guizero/guizero/PushButton.py", line 38, in __init__
    self.config(text=text, command=command, pady=pady, padx=padx)
  File "/usr/lib/python3.4/tkinter/__init__.py", line 1322, in configure
    return self._configure('configure', cnf, kw)
  File "/usr/lib/python3.4/tkinter/__init__.py", line 1313, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: character U+1f508 is above the range (U+0000-U+FFFF) allowed by Tcl

Hide and Show widgets

Implement the ability to hide and show widgets making them invisible / visible.

Add show(), hide() methods to _Widget.

Tkinter docs suggest you would have to use grid_remove, pack_forget depending on the master layout and a then use grid and pack to make them re-appear.

PushButton.py missing Enable and Disable

My code:

`create_story = PushButton(app, command=print_story, text="Tell me!")

if not player_name.get():
create_story.disable()
elif player_name.get():
create_story.enable()`

Error:

Traceback (most recent call last): File "/home/pi/Desktop/python/VisualAdventure.py", line 32, in <module> create_story.disable() File "/usr/local/lib/python3.4/dist-packages/guizero/PushButton.py", line 59, in disable self.config(state=DISABLED) NameError: name 'DISABLED' is not defined

Documentation: Wrong class signatures

I was taking a look at the docs for App and found the class signature is outdated:

class guizero.App(title="GUIzero", height=500, width=500, layout="auto", bgcolor=None)

The correct class signature is

__init__.py(self, title="guizero", width=500, height=500, layout="auto", bgcolor=None)
Source: https://github.com/lawsie/guizero/blob/master/guizero/App.py

(Note the capitalization: "GUIzero" โ†’ "guizero").
I guess this isn't a huge issue, but I got confused because some test cases were failing. I guess this should be fixed all at once in the 0.4 release? I don't know if this is true for other widgets too, but I'll take a look sometime soon.

This error persists in the Parameters section:

Parameter Data type Default Compulsory Description
title string "GUIzero" No The title displayed in the bar at the top of the window.

Button greyed out

Make it possible for a button to be disabled and reenabled (with functions)?

Consider an alternative to extending tk classes

A suggestion: rather than extend tk classes, would you consider creating new classes where the tk object is exposed as a property, so that only the guizero goodness is exposed to most users, but those who wish to (forgive me) tinker below the surface can still get to the nasty tk stuff?

The tk stuff is messy and most of it isn't useful. Using tab completion to find property and methods you're looking for is really difficult:

screenshot from 2017-08-21 12-18-03

For example:

class Slider:
    def __init__(self, master, start=0, end=100, horizontal=True, command=None, grid=None, align=None):
        orient = HORIZONTAL if horizontal else VERTICAL
        self.tk = Scale(master, from_=start, to=end, orient=orient, command=command)
        utils.auto_pack(self, master, grid, align)

    @property
    def value(self):
        return (self.tk.get())

    @value.setter
    def value(self, value):
            self.tk.set(value)

    def add_command(self, command):
        self.tk.config(command=command)

So instead of inheriting Scale and running super()__init__() you create a tk Scale object belonging to the guizero Slider object. You would provide guizero alternatives to anything useful within the tk object, such as value and add_command as shown. Any methods which need access to the tk object just refer to self.tk instead of self.

The result:

screenshot from 2017-08-21 12-43-57

Somewhat related to @martinohanlon's #25

Keep button size the same

Hello again, I have been experimenting with different font sizes in buttons using the config option. However, when I change the font size the button changes size as well! How do I make it so the button maintains the same size even if I change the text size?

Thanks in advance for any help,
LouisP

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.