PySimpleGUI - Binding shortcut key to one element of a sub-layout - python

Thank you for reading this.
I am searching for a standard solution but couldn't find one.
I have a simple layout made out of two layouts and the first layout is the one used to create the window.
I want to bind shorcut keys to only the right buttons.
They are not receiving the events at all, only always the first InputText element.
I need to have the InputText elements also receiving events and I could achieved that already.
I need that kind of layouts' architecture for a more complex GUI (Tab element and so on).
I have prepared one script that can contain my problem.
import PySimpleGUI as Sg
input_folder_layout = [Sg.Text("input folder",
size=(20, 1),
background_color="#64778D"),
Sg.InputText(default_text="",
key="input_folder",
size=(65, 1),
enable_events=True),
Sg.FolderBrowse("...",
size=(6, 1),
key="input_folder_browse",
enable_events=True)]
output_folder_layout = [Sg.Text("output folder", size=(20, 1),
background_color="#64778D"),
Sg.InputText(default_text="",
key="output_folder",
size=(65, 1),
enable_events=True),
Sg.FolderBrowse("...",
size=(6, 1),
key="output_folder_browse",
enable_events=True)]
ui_layout = [input_folder_layout, output_folder_layout]
Sg.ChangeLookAndFeel("DarkBlue2")
window = Sg.Window("UI Test", ui_layout, finalize=True)
window.bind("<Ctrl_R><i>", "CTRL-i")
window.bind("<Ctrl_R><o>", "CTRL-o")
while True:
event, values = window.read(timeout=100)
if event != "__TIMEOUT__" and event is not None:
if event in ("input_folder_browse", "CTRL-i"):
print("input folder browse event found")
if event in ("output_folder_browse", "CTRL-o"):
print("output folder browse event found")
if event == Sg.WINDOW_CLOSED:
break
window.refresh()
window.close()
window = None
I am using PySimpleGUI==4.60.3 and Python==3.9.13.
Thank you.

The binding for ctrl key is Control, not ctrl.
window.bind("<Control_R><i>", "CTRL-i")
window.bind("<Control_R><o>", "CTRL-o")

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()

PySimpleGui - Possible to alter font per line of sg.Output

I have a simple PySimpleGui screen that I am using for a 'chat' application. I would like to be able to differ between people's messages by changing the font (Ideally colour) used for each row printed... I just output using print('message') but was wondering if I could add something to be like print('message', color=red, weight=bold) or something like that... so I could bold my own messages and have others come in with different colours.
The chat window code is just this:
chatWindow = [[sg.Output(size=(90, 37), font=('Helvetica 10'))],
[sg.Multiline(size=(75, 5), enter_submits=False, key='-QUERY-', do_not_clear=False),
sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]]
Close. It's not color=red though, it's text_color='red' as in print(1,2,3,4,end='', text_color='red', background_color='yellow').
Have a look at the appropriate Cookbook recipe - Recipe Printing - #3/4 Print to Multiline Element
Code reprinted here for convenience:
import PySimpleGUI as sg
layout = [ [sg.Text('Demonstration of Multiline Element Printing')],
[sg.MLine(key='-ML1-'+sg.WRITE_ONLY_KEY, size=(40,8))],
[sg.MLine(key='-ML2-'+sg.WRITE_ONLY_KEY, size=(40,8))],
[sg.Button('Go'), sg.Button('Exit')]]
window = sg.Window('Window Title', layout, finalize=True)
# Note, need to finalize the window above if want to do these prior to calling window.read()
window['-ML1-'+sg.WRITE_ONLY_KEY].print(1,2,3,4,end='', text_color='red', background_color='yellow')
window['-ML1-'+sg.WRITE_ONLY_KEY].print('\n', end='')
window['-ML1-'+sg.WRITE_ONLY_KEY].print(1,2,3,4,text_color='white', background_color='green')
counter = 0
while True: # Event Loop
event, values = window.read(timeout=100)
if event in (sg.WIN_CLOSED, 'Exit'):
break
if event == 'Go':
window['-ML1-'+sg.WRITE_ONLY_KEY].print(event, values, text_color='red')
window['-ML2-'+sg.WRITE_ONLY_KEY].print(counter)
counter += 1
window.close()
See how the text in the edit box changes colour from red to white to red?

How do I create a custom button using PySimpleGUI that will allow me to browse for files?

I'm currently trying to create a custom button in python using PySimpleGUI that allows me to browse for files. I am able to do this successfully for a button that submits my entries and one that cancels the process, but am unable to figure out how to do so without having to use sg.FilesBrowse(), which doesn't allow me to customize the button.
I have the current code for my window.
#select theme for GUI
sg.theme('Light Blue 2')
#create custom buttons
submit_button = sg.Button('', image_data=submit_base64,button_color=(sg.theme_background_color(),sg.theme_background_color()),border_width=0, key='Sumbit')
cancel_button = sg.Button('', image_data=cancel_base64,button_color=(sg.theme_background_color(),sg.theme_background_color()),border_width=0, key='Cancel')
#create GUI layout
layout = [[sg.Text('Please select the following files:', font = ('bold', 14))],
[sg.Text('Page Names', size=(15, 1)), sg.Input(),sg.FileBrowse()],
[sg.Text('Files to Replicate', size=(15, 1)), sg.Input(), sg.FilesBrowse()],
[submit_button, cancel_button]]
In place of sg.FileBrowse() and sg.FilesBrowse() I would like to have my custom buttons similarly to how I created submit_button and cancel_button. I tried to follow the same format but am unsure what key I would have to use to have the button behave just like sg.FileBrowse() and sg.FilesBrowse().
Thanks.
Try this.
Create a button
When button pressed call popup_get_file
Take results from popup and fill in the Input element
import PySimpleGUI as sg
def main():
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-'), sg.Button('MyBrowse', key='-BROWSE-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == '-BROWSE-':
file = sg.popup_get_file('', no_window=True)
window['-IN-'].update(file)
window.close()
if __name__ == '__main__':
main()

PySimpleGUI make text selectable with mouse

I'm creating a textbox as follows:
sg.Text(size=(57, 10), background_color='white', text_color='red',
key='_console')
And it works fine, except the text isn't selectable!
I want the user to be able to copy the message to clipboard (by mouse selection and "copy").
How can it be done?
thx
According to the git hub issue related to this, the way to go about doing this is to create a read-only input and format it to look like the normal text elements:
https://github.com/PySimpleGUI/PySimpleGUI/issues/2928
import PySimpleGUI as sg
sg.theme('Dark Red')
layout = [ [sg.Text('My Window')],
[sg.InputText('You can select this text', use_readonly_for_disable=True, disabled=True, key='-IN-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout, finalize=True)
window['-IN-'].Widget.config(readonlybackground=sg.theme_background_color())
window['-IN-'].Widget.config(borderwidth=0)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()

Make a Textbox in PySimpleGUI

I am following the PySimpleGUI documentation and making my own edits as I go along. I am very new to it and have had experience with using Tkinter. There is a Textbox in Tkinter which you an get with the code Text(window, width=?, height=?, wrap=WORD, background=yellow). However in PySimpleGUI with similar code: layout = [[sg.Text('Some text on Row 1')]] - creates a label. My code is:
import PySimpleGUI as sg
sg.theme('DarkAmber') # Add a touch of color
# All the stuff inside your window.
layout = [ [sg.Text('Some text on Row 1')],
[sg.Text('Enter something on Row 2'), sg.InputText()],
[sg.Button('Ok'), sg.Button('Close Window')],
[sg.Text('This is some text', font='Courier 12', text_color='blue', background_color='green')],
[sg.Listbox(values=('value1', 'value2', 'value3'), size=(30, 2), key='_LISTBOX_')]]
# Create the Window
window = sg.Window('Test', layout).Finalize()
window.Maximize()
# Event Loop to process "events" and get the "values" of the inputs
while True:
event, values = window.read()
if event in (None, 'Close Window'): # if user closes window or clicks cancel
break
print('You entered ', values[0])
window.close()
I have attempted using PySimpleGui: How to enter text in the text box? but the Text Box here is actually a list box:
which is nothing like the TextBox I want:
The TextBox is surrounded by the red lines. Can someone please help me find the code that will give me the TextBox that I desire?
You can use sg.Multiline(...) which is Text widget of tkinter.
To get the content of the sg.Multiline, you can assign an unique key to it and use this key to get its content in the values dict.
Below is an example based on your code:
import PySimpleGUI as sg
sg.theme('DarkAmber') # Add a touch of color
# All the stuff inside your window.
layout = [ [sg.Text('Some text on Row 1')],
[sg.Text('Enter something on Row 2'), sg.InputText()],
[sg.Button('Ok'), sg.Button('Close Window')],
[sg.Multiline(size=(30, 5), key='textbox')]] # identify the multiline via key option
# Create the Window
window = sg.Window('Test', layout).Finalize()
#window.Maximize()
# Event Loop to process "events" and get the "values" of the inputs
while True:
event, values = window.read()
if event in (None, 'Close Window'): # if user closes window or clicks cancel
break
print('You entered in the textbox:')
print(values['textbox']) # get the content of multiline via its unique key
window.close()

Categories

Resources