PySimpleGUI / PySimpleGUI

Python GUIs for Humans! PySimpleGUI is the top-rated Python application development environment. Launched in 2018 and actively developed, maintained, and supported in 2024. Transforms tkinter, Qt, WxPython, and Remi into a simple, intuitive, and fun experience for both hobbyists and expert users.
https://www.PySimpleGUI.com
Other
13.36k stars 1.84k forks source link

[question] control text in input boxes #1119

Closed ihouses closed 4 years ago

ihouses commented 5 years ago

I want to generate an event in a input box in order to prevent that the user introduce a non numerical character in the text (only numeric values allowed), I can manage to do that. But now I would like to limit the number of characters that you can write, for this I would have to compare the old string with the one that is there when the event is generated. Is not a good idea to give access to the previous input string before the event was generated? Checking the object that generates the event I only see 'default_text' attribute. Actually I dont see where the actual text is (out of values[key])

MikeTheWatchGuy commented 5 years ago

PySimpleGUI doesn't save a history of the values that have been previously shown in elements. This is something your application needs to do. Save the value of the input after a read and use it to compare when the next read happens.

MikeTheWatchGuy commented 5 years ago

I would like to limit the number of characters that you can write

Why can't you simply get the "value" of your input and check the length? If it's "too long" then set the input field to your value minus the last character that was input.

MikeTheWatchGuy commented 5 years ago

Here's what I mean... this program will only allow 5 characters to be entered into the input field

import PySimpleGUI as sg

layout = [
            [sg.Input(do_not_clear=True, enable_events=True, key='_IN_')],
            [sg.Button('Exit')]
         ]

window = sg.Window('Window Title').Layout(layout)

while True:             # Event Loop
    event, values = window.Read()
    print(event, values)
    if event is None or event == 'Exit':
        break
    if len(values['_IN_']) > 5:
        window.Element('_IN_').Update(values['_IN_'][:-1])

window.Close()
AndKe commented 4 years ago

This issue is very close to what I wished to ask: how to limit to only numbers int/float entry?

PySimpleGUI commented 4 years ago
import PySimpleGUI as sg

layout = [  [sg.Text('My Window')],
            [sg.Input(key='-IN-', enable_events=True)],
            [sg.Button('Go'), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout)

while True:             # Event Loop
    event, values = window.read()
    if event in (None, 'Exit'):
        break
    if event == '-IN-' and values['-IN-'] and values['-IN-'][-1] not in ('0123456789.'):
        window['-IN-'].update(values['-IN-'][:-1])
window.close()

There ya go....Not sure why this is still open so thanks for flagging it.
[EDIT - Sorry for the edits, I keep making mistakes]

AndKe commented 4 years ago

Thank you ! :)

NordicBrut commented 2 years ago
import PySimpleGUI as sg

layout = [  [sg.Text('My Window')],
            [sg.Input(key='-IN-', enable_events=True)],
            [sg.Button('Go'), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout)

while True:             # Event Loop
    event, values = window.read()
    if event in (None, 'Exit'):
        break
    if event == '-IN-' and values['-IN-'] and values['-IN-'][-1] not in ('0123456789.'):
        window['-IN-'].update(values['-IN-'][:-1])
window.close()

There ya go....Not sure why this is still open so thanks for flagging it. [EDIT - Sorry for the edits, I keep making mistakes]

How would you add a number limit as well as restricting the inputs to just numbers?

PySimpleGUI commented 2 years ago

What's a "number limit"?

The restricting to just numbers is right in the example you've posted. Just remove the "." from the string.

PySimpleGUI commented 2 years ago

If number limit means to limit the length of the input, then you'll add that onto the if statement that's checking for digits. All of the "magic" for input validation is done in this statement. I've added a max length of 3 chars in case that's what you're after:

    if event == '-IN-' and values['-IN-'] and (values['-IN-'][-1] not in ('0123456789') or len(values['-IN-']) > 3):
        window['-IN-'].update(values['-IN-'][:-1])
NordicBrut commented 2 years ago

Yes! I meant this exactly, thank you. I am currently trying an alternative method which will keep track of the no. digits inputted and then compare them to my limit using python's new match case statements.

PySimpleGUI commented 2 years ago

using python's new match case statement

It's definitely fun to play with new language capabilities.

image

This is a scenario I've seen a number of times and think about constantly.... please don't take this as raining on your parade or fun.... that's not what I'm trying to do.... but I do think it's an important thing for all Python developers to think about and act in a very purposeful way when choosing which version of Python to use for their project.

If you plan on distributing your work.... if you want others to use it.... then understand your choice of versions will determine the size of your audience. If it's just for you... go nuts and use 3.11A features. If you want the "world" to use it, understand that a user is highly unlikely to upgrade their Python environment to run your code. They'll move on instead.

Here's why I mention it... if you look at PyPI installs for "all packages" on this website https://pypistats.org/packages/__all__, you'll see the distribution of the versions of Python users are running, now:

image

You can scan down the list and find the version of Python you are going to choose for your project and then pretty easily see the % of the Python world you're going to include or exclude.

TLDR - be intentional in your choices, understand the potential ramifications. Tying your project to a specific Python version will determine how many people will use your program.

NordicBrut commented 2 years ago

I never thought about it like that! (I'm new to programming in general) but it makes perfect sense to create programmes that are tailored to the majority of potential end users.

Luckily, I can play around with Python's newer version and its new features because I am creating a programme to be examined by an official exam board that only looks at my code's complexity and efficiency, not so much the world wide applications, however, I will definitely keep this in mind when moving forward with new projects.

PySimpleGUI commented 2 years ago

I never thought about it

Sorry for stopping your phrase early.... this is what I have seen so many times.... from all of us in programming. A close friend was speaking the other day of recommending on his site that everyone only use Python 3.10 for all their projects. I tried, in vain, to explain what this blanket statement was simply not good advice. It's binary thinking. Good/bad, best/worst, right/wrong. It seems we're wired to want and desire simple answers to complex questions. I'm the same way of course.

It's only been by careful analysis, by looking at the data, the analytics, what's really happening, that I have seen these kinds of patterns emerge.

Here's a bit of data about the PySimpleGUI installs... image

As you can see, our users are all over the map. My decision to make the PySimpleGUI tent as large as it can be has meant a personal sacrifice. The core code is backward to 3.4. That's a LOT of features that are off-limits... but is it really? 3.4 has a TON of capability. I'm not actually missing much at all. The Demo Programs are compatible with 3.6+. For me, 3.6 is the sweet spot. I could code using 3.6 for eternity and not feel any loss.

The point in this chat is to gather data, act in purposeful ways, with great deliberation and thought. Leave as little to randomness and emotion as possible.

Your response tells me you'll have little problems in paying attention to details... to thinking things through. As you said

I'm new to programming in general

It's a topic I see programmers with years of experience, decades, not think about. It's the classic "Know your customer" topic that I dashed out a video no a while back: https://youtu.be/7-cecLZtB1M

It's easy to assume we're building for our clones, people just like us. But if we're building for a larger group, rarely is that group a bunch of our clones.

Sorry for the long and winding tangent. It's been a nice conversation to have. It's as much of a reminder for me as it is an explanation to you.