Python PySimpleGUi suexpected behavior trying to "copy-paste" inputText - python

Hello i have a small program that gets input from user, I suddenly noticed that after few uses in the program I cant use CONTROL + A / CONTROL + C /CONTROL + D the inputText doesnt respond.
if I restart the program this buttons events work.
layout = [[sg.Text('WELCOME', justification='center', size=(50))],
[sg.InputText(), sg.Text(': ENTER SOME TEXT ', justification='right')],
[sg.Button('Search', bind_return_key=True)]
window = sg.Window('Client Connection V2.0Beta2', layout, element_justification='c')
while True:
event, values = window.read()
user_text= values[0]
if event == sg.WIN_CLOSED : # if user closes window or clicks cancel
window.close()
break
elif event == 'Search: # First step user search for
#some Code....

It should be fine for following code
import PySimpleGUI as sg
layout = [
[sg.Text('WELCOME', justification='center', expand_x=True)],
[sg.Text('ENTER SOME TEXT: '), sg.InputText()],
[sg.Button('Search', bind_return_key=True)],
]
window = sg.Window('Client Connection V2.0Beta2', layout, element_justification='c')
while True:
event, values = window.read()
if event == sg.WIN_CLOSED: # if user closes window or clicks cancel
break
elif event == 'Search':
user_text = values[0]
print(user_text)
window.close()
In your description, it didn't show how about the other keyboard input.
It maybe caused by the focus not on the input element, maybe you press the TAB key by accidentally, then the focus shift to next element, 'Search` button here, then all the keyboard input will not be responded in the input element.
In following figure, button Search focused and with a dash box on it, and then the keyboard input to input element will be not responded.
Try to press TAB key to move focus to input element.

Related

Want to be able to drag the things in the listbox into the workspace

I am trying to get the content in the listbox able to be dragged into the workspace as a block. Like scratch. I used OpenAi to give me ideas of how to do it, and it gave me that there is a draggable option I can put into the code as you can see, but when I try to drag the items in the listbox it wont let me.
import PySimpleGUI as sg
from PIL import ImageGrab
# Create a list of Python code to display in the scroller
code_lines = [
"variable",
"loops",
"types of variables"
]
# Create the window layout
layout = [ [sg.Column([[sg.Listbox(values=code_lines, size=(20, 10), key='Python Code', draggable = True)]]),
sg.Column([[sg.Text('Workspace:', size=(20, 1)), sg.Multiline(size=(50, 30), key='workspace', background_color='dark gray')]])],
[sg.Button('Close')] ]
# Create the window
window = sg.Window('PyDrop', layout)
# Event loop to process events
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Close': # if user closes window or clicks close button
break
elif event == 'Python Code': # if user clicks on an item in the listbox
# stores the value of the clicked item in a variable
dragged_item = values['Python Code'][0]
elif event == sg.DRAG: # if user moves the mouse while holding down the button
# updates the value of the drop target
print('Drag event triggered')
window['drop_target'].update(dragged_item)
# Close the window
window.close()

Widget appears after the user's input

I'm creating a GUI and I had an issue. My GUI is going to interact with the users, so depending on the user's input I want a button to appear. How can I do it? Because so far I can only make the button appear once the window opens.
For example, on the image below I have a sg.InputText isolated, but what I realy want is that this widget appears only after the first sg.InputText is filled.
enter image description here
Create a Button element with option visible=False, update it with visible=True when the value of Input element not empty.
import PySimpleGUI as sg
layout = [
[sg.Image(data=sg.EMOJI_BASE64_HAPPY_JOY),
sg.Text("TRAINING PROGRAM"), sg.Push(),
sg.Button("Check", visible=False)],
[sg.Text("Pass the badge on the reader:"),
sg.Input('', enable_events=True, key='-INPUT-')],
]
window = sg.Window('Title', layout, finalize=True)
shown = False
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
elif event == '-INPUT-':
if values[event] != '':
if not shown:
shown = True
window['Check'].update(visible=True)
else:
shown = False
window['Check'].update(visible=False)
window.close()

Prevent PySimpleGUI InputText event from executing while element is disabled when using FocusIn bind?

My GUI has an InputText box with default text that is to be cleared upon focus; however, the InputText is disabled until a ListBox selection is made. Even if a ListBox selection has not been made and the InputText box is disabled, the default text will still be cleared if the InputText box is clicked. Is there a way to prevent this? Or to check if the InputText is disabled when clicked?
Sample Code:
import PySimpleGUI as sg
def main():
layout = [[sg.Input("Search", s=(30,1), disabled=True, k="-SEARCH-")],
[sg.Listbox(values=["One", "Two", "Three"], s=(30,5), k='-LIST-', enable_events=True)]]
window = sg.Window("Test", layout, use_default_focus=False, finalize=True)
window['-SEARCH-'].bind('<FocusIn>', '_Focus')
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Cancel':
break
if event == '-LIST-':
window['-SEARCH-'].Update(disabled=False)
if event == '-SEARCH-' + "_Focus":
window['-SEARCH-'].Update("")
window.refresh()
window.close()
if __name__ == "__main__":
main()
Per Jason Yang's comment, the solution was to simply add the following to my Input declaration:
use_readonly_for_disable=False
Such that:
layout = [[sg.Input("Search", s=(30,1), disabled=True, use_readonly_for_disable=False, k="-SEARCH-")],
[sg.Listbox(values=["One", "Two", "Three"], s=(30,5), k='-LIST-', enable_events=True)]]

How to have PySimpleGUI default text in Output on window opening

I am using PySimpleGUI to create a text output box.
On opening the program, I would like the Output to display some default text before any button is pressed.
How can I get this to occur? window.Read() waits for a button press. window.refresh() doesn't appear to force the text to the window.
import PySimpleGUI as sg
initialString = "I want this text to display on window opening."
def gui2():
layout = [
[sg.Output(size=(90,20), background_color='black', text_color='white')],
[sg.Button('Do things'), sg.Button('Exit')]
]
window = sg.Window("Funny Title", layout)
#window.read() #I need to press a button before the text will display
#window.refresh() #doesn't refresh the output
print(initialString)
#window.refresh() #doesn't refresh the output
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
elif event == 'Do things':
print("You pressed the button")
window.close()
gui2()
and of course, the answer is found 5 minutes after I post.
window = sg.Window("Funny Title", layout, finalize = True)
This fixes the window, and the subsequent print statement appears in the Output as wanted.
.
Edit:
From the comment below, I've also changed the layout from sg.Outline to sg.Multiline:
sg.Multiline(size=(90,20),
background_color='black',
text_color='white',
reroute_stdout=True,
reroute_stderr=True,
autoscroll = True)],

PySimpleGUI call a function when pressing button

import PySimpleGUI as sg
import os
layout = [[sg.Text('Velg mappe som skal tas backup av og hvor du vil plassere backupen')],
[sg.Text('Source folder', size=(15, 1)), sg.InputText(), sg.FolderBrowse()],
[sg.Text('Backup destination ', size=(15, 1)), sg.InputText(), sg.FolderBrowse()],
[sg.Text('Made by Henrik og Thomas™')],
[sg.Submit(), sg.Cancel()]]
window = sg.Window('Backup Runner v2.1')
event, values = window.Layout(layout).Read()
How can I call a function when I press the submit button? or any other button?
The PySimpleGUI documentation discusses how to do this in the section on events / callbacks
https://pysimplegui.readthedocs.io/#the-event-loop-callback-functions
It is not lot the other Python GUI frameworks that use callbacks to signal button presses. Instead all button presses are returned as "events" coming back from a Read call.
To achieve a similar result, you check the event and make the function call yourself.
import PySimpleGUI as sg
def func(message):
print(message)
layout = [[sg.Button('1'), sg.Button('2'), sg.Exit()] ]
window = sg.Window('ORIGINAL').Layout(layout)
while True: # Event Loop
event, values = window.Read()
if event in (None, 'Exit'):
break
if event == '1':
func('Pressed button 1')
elif event == '2':
func('Pressed button 2')
window.Close()
To see this code run online, you can run it here using the web version:
https://repl.it/#PySimpleGUI/Call-Func-When-Button-Pressed
Added 4/5/2019
I should have also stated in my answer that you could add the event checks to right after your call to Read. You don't have to use an Event Loop as I showed. It could look like this:
event, values = window.Layout(layout).Read() # from OP's existing code
if event == '1':
func('Pressed button 1')
elif event == '2':
func('Pressed button 2')
[ Edit Nov 2020 ] - Callable keys
This isn't a new capability, just didn't mention it in the answer previously.
You can set keys to be functions and then call them when the event is generated. Here is an example that uses a few ways of doing this.
import PySimpleGUI as sg
def func(message='Default message'):
print(message)
layout = [[sg.Button('1', key=lambda: func('Button 1 pressed')),
sg.Button('2', key=func),
sg.Button('3'),
sg.Exit()]]
window = sg.Window('Window Title', layout)
while True: # Event Loop
event, values = window.read()
if event in (None, 'Exit'):
break
if callable(event):
event()
elif event == '3':
func('Button 3 pressed')
window.close()

Categories

Resources