MikeTheWatchGuy 2018-09-06T20:35:12Z
New use pattern - Element lookup using Keys
keys
can be used to lookup Elements. As a result, all Elements are capable of having a key, including non-output elements such as a Text Element.
To get an element object from a form, you call
form.FindElement(key)
This is the new, preferred method for doing Updates on elements.
Previously if you wanted to output something to a Text Element, you needed to create the text element outside of the form layout and keep that text element variable around so you can call text_element. Update('new text')
The new design pattern is thus:
In your form layout, include a key on your Element:
Later in your code you can update this Text Element by making this call, assuming the variable form is your FlexForm object:
The Demo programs have all been updated to use this new technique. This capability and its impact on the length of programs led to pushing version 2.30 out the door quickly.
MikeTheWatchGuy 2018-09-06T20:38:58Z
Borderless Windows are Here
Try them on your next form.
Add this to your FlexForm call:
no_titlebar = True
You can expect to see some of these in the Demo programs.
You can click anywhere on the window and drag to move it. Don't forget to put an exit key on these windows.
Be sure and make an "exit" button or you'll be running task manager to close your windows. The reason is the when you turn on this option, you will not see an icon on your taskbar for the window. This happens on both Windows and Linux. Thus, if you do not supply an exit button, the user will have no means to close the window.
MikeTheWatchGuy 2018-09-07T00:35:21Z
Grab Anywhere
Tonight's change is perhaps going to be a really cool thing or one that is going to piss people off.
But, hey, I like it this way. If you don't, setgrab_anywhere = False
in your call to FlexForm.
As the name implies, you can grab and drag your window using any point on the window, not just the title bar. I was only enabling this when the title bar was turned off. I think it's a much superior way to interact with a window.
FlexForm is becoming quite the call!
def __init__(self, title, default_element_size=DEFAULT_ELEMENT_SIZE, default_button_element_size = (None, None), auto_size_text=None, auto_size_buttons=None, scale=(None, None), location=(None, None), button_color=None, font=None, progress_bar_color=(None, None), background_color=None, is_tabbed_form=False, border_depth=None, auto_close=False, auto_close_duration=DEFAULT_AUTOCLOSE_TIME, icon=DEFAULT_WINDOW_ICON, return_keyboard_events=False, use_default_focus=True, text_justification=None, no_titlebar=False, grab_anywhere=True):
So, enjoy a lazy way of interacting with windows on me.
You will want to turn if off for forms with a SLIDER. you need the slider to move, not the window. I'll update the Demos that use sliders to turn off the grab_anywhere.
MikeTheWatchGuy 2018-09-07T14:42:06Z
Tables
This one has been requested a number of times. Rather than make a Table Element, decided to see if the current PySimpleGUI is capable of making nice tables using standard Elements. The answer seems to be yes, it's possible with existing Elements. The key was to enable text justification in the InputText element. By right justifying the text in those Elements, it's possible to create a nice looking table.
Here's an example using a ComboBox and Input Elements.
You'll find the code that generated the table in the file Demo_Table_Simulation.py. It requires the latest PySimpleGUI from GitHub in order to use the justification setting.
This is a "live keyboard" demo. It updates the table values as you are typing.
There are 3 fields at the top of the table. If you enter a value into the 3rd field, the cell that the other 2 cells represents will be changed to that value. Enter 1, 2, 1234 and cell (1,2) will be changed to 1234.
There is a new trick demonstrated in this demo that shows off the power of Python. Rather than pass in a string as the key to the Input Elements, I passed a tuple. Nothing about the key requires it to be a string. The only requirement is that you use the same type to look up the element when you call FindElement or use the key to read the return values.
This is the code that makes the Input Elements:
for i in range(20):
inputs = [sg.In('{}{}'.format(i,j), size=(8, 1), pad=(1, 1), justification='right', key=(i,j), do_not_clear=True) for j in range(10)]
See how the key is set to (i,j). This allow me to easily find the Element that is represented by (i,j) later. What to access the cell at (0,0)? This you would make this call:
form.FindElement((0,0))
Hopefully this is enough capability for the folks that need tables in their forms/window.
MikeTheWatchGuy 2018-09-07T22:07:46Z
Three Point Oh!
So maybe I kinda screwed up the numbering when the last one became 2.30. I didn't think about it looking like 2.3 also. Doh!
There have been a lot of changes lately so perhaps it's time for a major bump.
It's a clean slate
MikeTheWatchGuy 2018-09-08T02:20:50Z
keep_on_top = True
What might this setting do in a call to FlexForm? If you guessed create a window that's ways on top you're right.
This one little flag enables cool floating toolbars that stay on top of all of your other windows. I'll admit a large portion of this project is for selfish purposes, that I have a platform to develop tools on top of.
Now I've got this nifty toolbar on the top part of my screen, always ready to launch or do something.
MikeTheWatchGuy 2018-09-08T19:18:32Z 3.0.2 release today to turn off the grab_anywhere feature for non-blocking forms. tkinter is printing out a warning/error message when the form is closed using a button. Doesn't appear to have any effect on the overall functioning, but it's distressing to see. Better to disable this feature for now.
Plan is to add back an override mechanism should a user want it.
MikeTheWatchGuy 2018-09-08T20:26:59Z
RELEASED 3.0.2
MikeTheWatchGuy 2018-09-08T23:42:15Z
Floating Toolbar - New demo program
This is an always-on-top, compact floating toolbar. They are super-handy to leave running. Something satisfying about writing code that then gets used often, especially if they make you much more efficient.
MikeTheWatchGuy 2018-09-09T03:25:25Z
Async Forms
Updated the Readme / primary doc to discuss the use of non-block forms.
As explained in the documentation there are a number of techniques to move away from async forms including using the change_submits = True
parameter for elements and `return_keyboard_events = True
`
MikeTheWatchGuy 2018-09-09T17:35:49Z
Floating Desktop Widgets
I've discovered that in about 30 lines of code you can create a floating desktop widget.
If you click the pause button, it switches to Run.
This "Widget" is always on top of the other windows.
Looking for a way of launching these in a way that have no taskbar icons. If launched from PyCharm it behaves this way. If launched from a Toolbar, the toolbar's window is attached to the timer. Close it and the timer closes.
This demo is the first time I've ever combined a ReadNonBlocking with a Read in the same form. The reason for using it in this program is that while the timer is paused, there' s nothing happening so why have the program running the loop when it can wait for the user to do something like click a button. When the button is clicked we return from the Read call.
Thank you to jfong for sending an interesting version of this program. His ideas have rolled into a into the project code many times.
MikeTheWatchGuy 2018-09-10T03:35:50Z
Menus are done
The last of the big features, Menus, was just released to GitHub. With it comes the ability to get the look and feel of a windows program. I don't know if the architecture will lend itself to being used this way or not, but it did seem like a useful feature to add..
MikeTheWatchGuy 2018-09-10T15:05:52Z
3.7 Support
Thanks to @mrstephenneal we can now say that PySimpleGUI works on Python 3.7. There was a button issue causing trouble. Looks like it's fixed now so I think 3.7 is now safe to with PSG.
MikeTheWatchGuy 2018-09-10T15:31:31Z
Release 3.01.00
Menus! (and a Listbox.Update bug) are the big features.
Since the Menu code is somewhat isolated, and I want to get some users on it, decided to go ahead and push it all out there in 3.01.00
I didn't mention this in the readme section on menus, but by default (you can't currently turn it off) menus are detachable. If you double-click the dashed line then you get a floating version of that menu. Should make for some pretty interesting user interfaces?
MikeTheWatchGuy 2018-09-10T22:31:50Z
3.1.1
There have been enough bug fixes to trigger another PyPI release. People have been doing more and more with the Update method. These fixes were mostly in those methods.
MikeTheWatchGuy 2018-09-11T12:44:26Z
Update methods updated
Added the ability to enable / disable all input elements.
Set parameter disable=True to disable, disable=False to enable, disable=None to leave it alone
A number of Demo programs also refreshed.
Expect a PyPI release soon.
Note that some Update method changes also changed parameter names from new_value to value, new_values to values. Some were different than others. Removed new_ so they all match now. Sorry to those living on the bleeding edge!
Here's a before/after. Elements towards the bottom of the window were disabled.
Yes, even buttons can be disabled now. No more needing to gray out your own buttons!
MikeTheWatchGuy 2018-09-11T20:16:46Z
3.1.2
Big change this time around is the ability to disable widgets. All input widgets have an Update method that has the parameter disabled
that you set to True
if you want to disable it.
A few critical bugs in there too which pushed up the release to today.
MikeTheWatchGuy 2018-09-12T17:51:52Z
Resizable Windows, Font settings for input text elements, beginnings of Treeview Element
You can stretch windows bigger now and some of the elements will resize with the window. **
The Input Text Elements did not have a functioning Font setting. Doh! Don't know how that got missed.
The very beginnings of the Treeview element are in there.
Hopefully nothing was broke. Any time I make changes to the core widget packing I get nervous!
** Had to turn off some of the Resizable windows features....Buttons and other elements were moving / expanding in forms that I didn't want the to expand. The change fucked up too many elements to leave on for now.
MikeTheWatchGuy 2018-09-12T20:55:19Z
Two new Demo programs - CPU Desktop Widget, Spinner Compound Element
Added another Desktop Widget to the demos. This one shows the CPU utilization.
The spinner allows you to change how often it's refreshed
The Spinner Compound Element was done in response from a user wanting to see a different kind of spinner. This one has larger buttons and is laid out horizontally.
The point of this demo is that it's possible to put together multiple Elements into a higher level element. There aren't many of these I can think of at the moment, but given how many user questions are asked, something else is bound to be asked for.
MikeTheWatchGuy 2018-09-13T16:12:33Z
Table Element, Complete rework of Popups, Death of MsgBox
You can blame the Popup changes on this issue:
https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/204
All of the Popups were rewritten to use a long list of customization parameters. The base Popup function remained more or less the same.
Decided while I was going all the Popup work that it's time to completely remove MsgBox. Sorry all you early adopters. You'll need to do a bulk rename and then you'll be fine.
Table Elements
Finally have something to show in the form of tables. The element name is Table
. While the tkinter Treeview widget was used, many of the parameters were not exposed. If they were, the caller could really mess things up. Better to present a nice "Table-friendly'" interface than something specific to tkinter. After all, the plan is to expand PySimpleGUI to use other GUI frameworks.
A Demo program is in the works.
It's possible to add scrollbars to the Table element by simply placing it into a Column element.
There's still work to do and a good number of bugs, but I encourage you to give it a try.
If you do not put the Table Element inside of a Column, then you can still view and scroll the table, it just will not have scrollbars.
There is a problem currently with keyboard input when placed into a Column. The keyboard keys work fine when NOT inside of the Column but stop working when placed inside a Column Element.
This program will read a CSV file and display it in a window.
import csv
import PySimpleGUI as sg
filename = sg.PopupGetFile('filename to open', no_window=True, file_types=(("CSV Files","*.csv"),))
# --- populate table with file contents --- #
data = []
if filename is not None:
with open(filename, "r") as infile:
reader = csv.reader(infile)
try:
data = list(reader) # read everything else into a list of rows
except:
sg.PopupError('Error reading file')
exit(69)
sg.SetOptions(element_padding=(0, 0))
col_layout = [[sg.Table(values=data, headings=[x for x in range(len(data[0]))], max_col_width=8,
auto_size_columns=False, justification='right', size=(8, len(data)))]]
layout = [[sg.Column(col_layout, size=(1200,600), scrollable=True)],]
form = sg.FlexForm('Table', grab_anywhere=False)
b, v = form.LayoutAndRead(layout)
It's another bit of PySimpleGUI "challenge code"..... The challenge is to do the same operation in another GUI framework in less lines of code. I would enjoy seeing the tkinter code required to create the window that this 20 line PySimpleGUI program creates. Most of the code deals with reading the CSV file 👍
MikeTheWatchGuy 2018-09-14T15:07:09Z
Linux Virtual Environment
I finally installed VirtualBox and am running Ubuntu Linux. I tried to install the Mint distro, but the display was scrambled when it booted.
I was surprised how close the Linux screen shots look to the Windows.
Even Pong worked the first time.
I don't believe that Python has been labelled the "go to language" for doing cross-platform GUI work. I guess I never stopped to think about it. I don't recall seeing this kind of thinking in posts or books I've read on Python. Perhaps it's time for that to change?
MikeTheWatchGuy 2018-09-14T16:19:09Z
3.2.0
Released a new release to PyPI. Sorry about all these releases, but features continue to pour into the code. I'm finding even the folks that are actively using PySimpleGUI only run the pip installed version rather than the GitHub version. That means if I want runtime on the code, I'm only going to get any is to do a full release.
There were a number of changes that could f-up, so be on the lookout. The biggest addition to 3.2.0 was the Table Element (beta quality at the moment).
If you are running older programs then you may crash due to missing functions, MsgBox and several others. This is because I've moved 100% to Popup calls. It's not like I haven't been warning people so I don't expect complaints.
Some people are calling ReadNonBlocking
prior to your Event Loop so that the form gets fully made. This call is needed if you want to perform actions on elements prior to calling Read. For example, if you want your form to be shown with some Elements set in the disabled state (using calls to Update), you will need to make an additional call after your Layout call.
Instead of calling ReadNonBlocking
in these situations, you can call Finalize
/PreRead
/PrepareForUpdate
. I have not been able to standardize on a name, so I'm providing multiple. I'm sure a winner will emerge. I've been using Finalize.
The call sequence becomes this:
You'll also find the Finalize call used in the scripts that use the Canvas Element.
See the Readme for more info on what's in the release. Note that the readme has not yet been updated with the Table Element and several other changes. There's only so much I can do.
MikeTheWatchGuy 2018-09-15T17:54:04Z
One Line Progress Meters
PySimpleGUI has always had a one-line progress meter called EasyProgressMeter. However, that function has a limitation of only 1 meter being active at a time.
The new way to do Progress Meters is the function OneLineProgesssMeter.
All of the documentation and examples will reflect this new function.
Have to say it's nice to be able to run as many meters as desired without having to worry about more than 1 being on the screen at a time.
I intend to remove EasyProgressMeter within the next 5 or 6 releases to PyPI. I tried to insert a warning in the code, but too much code was shared to fit the message in.
I'm sorry about the change, but really would like to both add this function and rename the capability to something very descriptive. If there is enough revolt over removing EasyProgressMeter, I'll leave it in and simply drop it from all the documentation.
MikeTheWatchGuy 2018-09-15T20:39:35Z
3.3.0
Yea, yea, it seems like only yesterday that version 3.2.0 was released. That's because it WAS only yesterday. I've been busy.
There are 2 changes I wanted out quickly....
-
The ability to turn off displaying row numbers
-
The new
OneLineProgressMeter
function
The Progress Meter feature alone is a great use of PySimpleGUI. A number of users are using it only for this purpose in their programs.
MikeTheWatchGuy 2018-09-16T19:08:14Z
Graphing
New demo program - graph ping using canvas.
I'm thinking about creating a Graph Element, something that makes it super easy to users tog create graphs, both line and x,y plot. The demo should how to take a canvas element and graph ping times.
There is another ping-graph demo using Matplotlib. This graph only uses tkinter.
Finally, because the pings take a long time, I moved the ping calls outside of the GUI event loop. Calling ping inside event loop was causing the GUI to respond sluggishly. This is because the ping was taking 1 second which means the gui wasn't being refreshed / wasn't responsive during the second. Now the GUI sleeps for 200 ms while the ping is done by a thread.
This is yet another toe in the water with threading. The problems I saw in the past are no longer there, it would appear.
I also checked in the ping.py file that you need for this demo. It's a pure python implementation of ping and works pretty well, even if slow.
MikeTheWatchGuy 2018-09-16T19:36:07Z
Progress Meters
Thanks to @JorjMcKie I've learned more about the performance of the EasyProgressMeter and thus probably the OneLineProgressMeter. The more arguments to display the longer it takes.
Was going to document in the Cookbook / Readme that if you have performance concerns, you can call the progress meter less frequently. You don't have to update it 1 count at a time. It could be like this:
for i in range(10000):
if i % 5 == 0: sg.OneLineProgressMeter('My 1-line progress meter', i+1, 10000, 'single')
This meter is only called every 5 times through the loop. It finished quite a bit quicker than the test updating the meter every single time.
MikeTheWatchGuy 2018-09-16T19:48:45Z
PySimpleGUI programs as an EXE file!
The biggest thing to hit PySimpleGUI since Colors.... the ability to run programs written for PySimpleGUI as an exe file. ALL credit goes to @JorjMcKie for this.
There is no need to distribute Python with your programs. It's all included in the exe and folder of supporting files.
From what I understand of nuitka, this code is compiled C++ code, not python code. The performance is thus potentially better! It's the best of both worlds.
Working to get the process documented. It's tricky and required a special script. Stay tuned....
MikeTheWatchGuy 2018-09-16T21:18:44Z
Graph Element
This one is pretty exciting as it does something new on the screen. The Graph Element allows you to easily create a canvas and draw on it using your own coordinate system. You don't need to do conversions from your graph coordinates to the tkinter canvas graph coordinates.
The Demo program for it is a good example. It displays a pint graph. The graph we're creating is a line graph what we would like to to from 0,0 in the bottom left to 100, 500 in the upper right. This will give us 100 data points along the x axis and up to 500 ms on the y axis.
After creating the Graph Element, we can do 3 operations on it:
-
Draw Line
-
Draw Point
3 Erase
The draw line draws a line from 1 point to another. The points are specified using your graph coordinates, not the tkinter canvas coordinates.
I know I have a LOT of documentation to do.
In the meantime, try using Control+P if you're using PyCharm. Press Control+P while you are typing in the parameters and you'll see a popup showing you what the legal parameters are. This feature is almost necessary when using PySimpleGUI because functions have SO many optional parameters.
I hope to see some cool creations using the capability. I'm starting to see more and more projects pop up on GitHub that use PySimpleGUI! Keep those examples coming! And keep the requests for new features coming too. They have made this such a better package because of your help.
Sample code:
This is your layout:
layout = [ [sg.T('Ping times to Google.com', font='Any 18')],
[sg.Graph((300,300), (0,0), (100,500),background_color='white', key='graph')],
[sg.Quit()]]
form = sg.FlexForm('Canvas test', grab_anywhere=True)
form.Layout(layout)
To draw a line, call DrawLine:
form.FindElement('graph').DrawLine(from_point, to_point)
MikeTheWatchGuy 2018-09-17T08:52:32Z
Movable Graph Element
Made the Graph Element "movable". This means the graph can be shifted when it reaches the "End".
Here's a 1,000 data-point ping graph or 16 minutes woth of pining
MikeTheWatchGuy 2018-09-17T17:10:58Z
Button return values as keys
rather than button text
Just dropped in a sizable change in how buttons work. For buttons that have a key value, the key is returned rather than the button text. This is needed for forms that have multiple buttons with the same text.
The 'best' way to rework existing code is to get your key == button_text
.
Expect a number of Demos and Recipes to change. Lots to do to explain this one.
It's another excellent suggestion provides by @mrstephenneal.
Keep those ideas coming people! They're turning PSG into an event better package! Don't be shy if you need a change.
MikeTheWatchGuy 2018-09-17T17:35:38Z
Nuitka launches only from command window
Not sure what happened, but I can't seem to load the Nuitka .EXE file by double clicking. It doesn't do anything but flash a command window like it has crashed.
However, when I type the exe filename on a command prompt, it works GREAT. Perhaps if I added to a batch file then double-click would work. Will try soon.
MikeTheWatchGuy 2018-09-17T23:04:15Z
Clickable 'text'
I noticed on some GUIs it's possible to determine when someone clicks on text. I experimented and found a way to duplicate this behavior
The 'Clear' text is actually a button with the border_width = 0 and color = black like the background. Poof... instant clickable text
Cross that feature off the list
MikeTheWatchGuy 2018-09-18T02:22:28Z
Frame Element
Just when you think I'm out of new elements to spring on you, I cough up another.
For those people with an eye for design and want their forms to look as good ad possible, give you the Frame
Element
The frame element allows you to group your Elements into a nice box with a text label.
It takes 2 required parameters - title
& layout
.
You can customize the text font, size, color, relief style. I do not yet have a setting where you can specify the location of the label.
You can think of these as Column Elements with a label and an outline because that is exactly what they are, except you cannot scroll a Frame Element.
The implementation uses the tkinter labelframe
widget. I decided to name this Element Frame since that's exactly what it is. I do not have a labelled and unlabeled Frame. If you want a frame without a label, specify None
for the title
This is one of those features that have zero impact on your form's capabilities, but has a big impact on the appearance of a form.
MikeTheWatchGuy 2018-09-18T15:15:47Z
3.4.0
Released 3.4.0 today. I'm sure most of you head straight to the readme file, scroll to the bottom and read the release notes. I'll go ahead and post them here just to humor myself.
There is significant amounts of work to be done on the docs to get the new Frame and Graph elements documented in the readme, Cookbook and tutorial. Soon I hope. In the meantime, all you advanced users can quickly figure them out using PyCharms Control+P feature.
3.4.0
-
New Element Frame (a labelled frame for grouping elements. Similar to Column),
-
New Element Graph (like a Canvas element except uses the caller's coordinate system rather than tkinter's).
-
Set an initial_folder for browsing type buttons (browse for file/folder).
-
Buttons return key value rather than button text if a key is specified,
-
OneLineProgressMeter! Replaced EasyProgressMeter (sorry folks that's the way progress works sometimes),
-
Changed ALL of the Popup calls to provide many more customization settings - changed PopupGetFolder, PopupGetFile, PopupGetText, Popup, PopupNoButtons, PopupNonBlocking, PopupNoTitlebar, PopupAutoClose, PopupCancel, PopupOK, PopupOKCancel, PopupYesNo
MikeTheWatchGuy 2018-09-18T16:23:57Z
Stack Overflow, Reddit
I've been watching both StackOverflow and Reddit for opportunities to help people out using PySimpleGUI.
I answered on StackOverflow question about adding a GUI onto a command line program that I'm particularly proud of. A sample GUI was provided that was made in Visual Studio. It took 15 lines of code in PySimpleGUI to duplicate the design.
Check it out if you get the chance:
MikeTheWatchGuy 2018-09-18T18:32:45Z
Fun with Graph Element
I'm 1/2 way through my 6,000 ping graph :-) The top is 500 ms.
MikeTheWatchGuy 2018-09-18T20:57:28Z
3.4.0 is no more
Deleted release 3.4.0. Everyone will have to wait on the new release. You can always get and test against the Master Branch to see if you're going to have trouble in the upcoming releases. It would be great if someone people could be running from Master rather than PyPI.
This backed out the button change as well as the laundry list of new features and bug fixes. It'll all have to wait until I can make sure all Demos work with new code and there is more documentation updated.
MikeTheWatchGuy 2018-09-18T22:17:00Z
6,000 Point Canvas (6,000 Point Ping Graph)
My ping graph has finally finished and is scrolling nicely. It's spanning 3 monitors
MikeTheWatchGuy 2018-09-18T22:51:11Z
Is there a class using PySimpleGUI??
I see three different repositories popped up, at the same time, with the same structure. They all implement a calculator using PyGame and PySimpleGUI.
It sure looks like some class is teaching PSG!
That's crazy!
I dunno if PySimpleGUI is ready to be used in a class just yet. Heck, I'm still breaking features.
https://github.com/ozone94/Calculator_PySimpleGUI/tree/2d2d8898ce51f2ca223434acd2af6c8682ddf5c3
https://github.com/ATBLightning/PySimpleGUI_AsTheCalculator/tree/db837888c47763a990c5c7e15d66a21b99924c16
https://github.com/poschananT/CalculatorPySimpleGUI_6001012620033
https://github.com/Thanaban/SimpleGUI_calculator
MikeTheWatchGuy 2018-09-19T02:59:51Z
3.4.1
OK, the release is back to being a release, now that there's the required Button.GetText call which allows you to figure out the current text value on a button.
This release shouldn't break anyone's code.... unless you're one of those super-advanced users that are changing the text on their buttons (smarty pants's). Those folks have a the special Button.GetText method just for them so that the button text can be retrieved.
For those of your that are writing a lot of code that uses ReadFormButton, I have created a shortcut, ReadButton, so that you save a few characters in your layout.
Overall this is a pretty strong release with two new elements, Graph and Frame. The Frame element enables PSG windows to look even better, more professional.
I can't WAIT to see what people do with these things. I see something new that you guys create every day and it's quite motivating. Keep the ideas and inspiration coming!
MikeTheWatchGuy 2018-09-19T13:56:54Z
There IS a class using PySimpleGUI
Holy crap.... I saw this in a readme today:
My reference :: Introduction to Computer Science Using Python and Pygame by Paul Vincent Craven
Can't wait to see if more text is added to this:
https://manachanok94.blogspot.com/2018/09/calculator-using-pygame-vs-pysimplegui.html
Sure looks like there's a computer science class using it!
Part of the exercise also appears to be the students
-
Create a GitHub repository
-
Make a readme, structure the GitHub nicely
-
Create a blog and in the blog write the difference between writing a calculator program in PyGame versus PySimpleGUI... really looking forward to getting this feedback from students!
This is one of the goals I originally had for the package, make something usable by students, people just starting so that they get exposed to doing good user interfaces from the beginning of their career. It seems like a good thing to learn how to lay out a screen in a pleasing and functional way.
"Be careful what you ask for" is definitely fitting for this situation.
https://github.com/Manachanok/Calculator
Some students already commenting on how much more compact PySimpleGUI is at their calculator assignment than their PyGame implementations.
One student wrote this:
It's a total of 34 lines compared to Pygame written in a hundred lines. Simple by name
I try to remain neutral when speaking of other packages. Everyone working on these packages has fantastic intentions, works hard, is altruistic, and we all have a slightly different outlook on how to create a simple GUI. It's not my place to knock any, any, of the GUI packages.
MikeTheWatchGuy 2018-09-19T14:45:20Z
Text Element Relief Setting
Oh what a relief it is.
Continuing on polishing the look and feel of PySimpleGUI. Today's feature is the ability to add a relief to Text Elements.
It's part of the Demo_All_Widgets.py code along with the new Frame Element.
The first line of the layout reads:
sg.Text('All graphic widgets in one form!', size=(30, 1), justification='center', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)
MikeTheWatchGuy 2018-09-19T15:32:52Z
Listbox bind_return_key
Previously Listboxes always submitted when the return key was pressed. Now it's controlled using a new bind_return_key. Listbox is like the other Elements now. I also added double-clicking! I find myself double clicking the listbox and nothing happens. I have to click a button or press return key. Now you'll get control back on double-click if you've set bind_return_key
MikeTheWatchGuy 2018-09-19T16:09:02Z
For fun... my desktop
I bet some nuclear power plants have less gauges and controls. 1/2 of one of my monitors. 3 of those widgets are PySimpleGUI powered.
MikeTheWatchGuy 2018-09-19T20:26:04Z
Combining Form and Layout calls
There are a handful of design patterns that we all have been using.
Two of the blocking style ones are:
The simple form:
The perpetual form:
I have disliked the second one of those since I wrote the code. It felt wordy.
In Python, I am constantly scanning trying to simplify, compact, make easier. Nothing is more fun than combining function calls. So I was elated when I stumbled in to a code change that allows this new pattern:
It was a super simple change to the code, and damn, the result is awesome.
You can expect this one to get released quickly and have the demos, cookbook updated too.
MikeTheWatchGuy 2018-09-20T01:17:37Z
Table Demos - CSV & Pandas
It's great when community members write some of this stuff... I get a lot of behind the scenes help from you guys whether it's advice on naming, determining new parameters, how to implement a new element. Otherion wrote a couple of Table Element demos. One uses the CSV library the other pandas. There are more bugs to work out with the table element. I'm not happy with now I used the size parameter and I'm not sure the autosizing it sizing correctly. These Demos will make excellent patterns for folks wanting to work with tables. I have a 3rd one that I'll post soon that works with databases!
MikeTheWatchGuy 2018-09-20T20:55:31Z
Shorter Button Names
The upcoming release will include new shorter names for buttons. You'll still be able to use all the same names as before. However, they'll change in the Demos, particularly new demos, and the Cookbook.
This comes from 2 things. 1 - I'm fundamentally lazy. You may have noticed my frequent use of sg.T() and sg.In() instead of sg.Text and sg.InputText. 2 - I saw the incredibly wordy looking programs the students made. They were calculator programs so naturally the UI was crammed with buttons. There were 20+ sg.ReadFormButton() calls in every program. Ugh, too much clutter.
The change required me to shuffle around some parameters in the Button Element. I learned a big lesson as well in NOT relying on positional arguments when making internal function calls. I have more cleanup to do. I needed to make the Button Element have the text in the first position if I was to steal it and make it a user callable function rather than only internally used. It's such a great name, Button() that it seemed a shame to hide.
Here are the new names:
SimpleButton
becomes Button
ReadFormButton
becomes ReadButton
or RButton
You can easily guess which of these you'll see me using the most.
Thus, all of the buttons, in their shortest form, are:
If someone right a program with a ton of RealtimeButton
then maybe I'll shorten it too. I can't think of another name for that one.
Again, you do not need to change your code. The wordy-buttons will continue to work, but won't be used in examples anymore.
MikeTheWatchGuy 2018-09-21T00:12:45Z
Tooltips
Thanks to the help of @rtrrtr we now have tooltips on all of the Elements... or almost all of them... or the ones that matter.
If you find a tooltip parameter in the call to the Element, then you can add a tooltip to it.
This includes the shortcut buttons like Submit(), Yes(), etc.
It really helps when someone supplies code like this. It enables me to hook in the new feature quickly and easily.
Since this touched every Element and shortcut, there's a good chance I f-ed something up, so be on the lookout.
As usual, it's in the Master Branch. I'll let it sit for a day or two and then off to PyPI it'll go along with the other features and bug fixes made since 3.4.1
MikeTheWatchGuy 2018-09-21T03:54:38Z
3.5.0
Another day, another truckload of features. Seemed like plenty of stuff saved up over the past few days that it's worthy of a released. Seems like pretty much everyone wants to run the pip installed version rather than pulling the latest Master Branch. So, I'm going to push stuff out there and hope that if it breaks someone speaks up quickly. So far that's what happened, someone speaks up when something breaks. Keep speaking up!
The feature list
-
Tool Tips for all elements
-
Clickable text
-
Text Element relief setting
-
Keys as targets for buttons
-
New names for buttons:
-
Button = SimpleButton
-
RButton = ReadButton = ReadFormButton
-
-
Double clickable list entries
-
Auto sizing table widths works now
-
Feature DELETED - Scaling. Removed from all elements
The biggest reason I wanted it out is so I can use Button
and RButton
! That's going to save a lot of keystrokes and it'll compact the code. Maybe I should make Btn
? Or how about just B
? LOL
Then there's tooltips which multiple people asked for.
I also killed off Scaling in this release. That touched SO many parts of the code so I hope it survived OK. If you were using the scaling feature..... uhm, I'm sorry? I don't think anyone is however.
Enjoy!
MikeTheWatchGuy 2018-09-21T05:01:03Z
Graph Element
This is the latest Recipe addition to the Cookbook. I created a 10-line program that created this lovely screenshot.
import math
import PySimpleGUI as sg
layout = [[sg.Graph(canvas_size=(400, 400), graph_bottom_left=(-100,-100), graph_top_right=(100,100), background_color='white', key='graph')],]
form = sg.FlexForm('Graph of Sine Function').Layout(layout)
form.Finalize()
graph = form.FindElement('graph')
for x in range(-100,100):
y = math.sin(x/20)*50
graph.DrawPoint((x,y))
button, values = form.Read()
What I like about working with these Graph Elements is that I don't have to worry about translating into on-screen coordinates. It's always a pain in the ass dealing with the converting into screen coordinates. Having that removed so that I'm working in my desired coordinates is really satisfying.
In this case I wanted a graph that went from -100 to 100 in both X and Y axis. Defining those values as well as the size of the screen area to use is all done in the call to Graph
.
sg.Graph(canvas_size=(400, 400), graph_bottom_left=(-100,-100), graph_top_right=(100,100), background_color='white', key='graph')
The actual graphing of the data points is this little loop, again, working in my own coordinates to draw the points:
And add just a couple more lines of code and you can get axis and another graph
for x in range(-100,100):
y = x**2/20-100
graph.DrawPoint((x,y))
y = math.sin(x/20)*50
graph.DrawPoint((x,y), color='red')
MikeTheWatchGuy 2018-09-22T17:54:21Z
3.5.1 (the "oh shit" release)
It only hit me today how "broken" 3.5.0 was! I didn't realize that older Python3 installs were flat out broken... that PySimpleGUI wouldn't run at all! Doh! It was due to this issue:
https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/298
MikeTheWatchGuy 2018-09-22T21:06:38Z
PyInstaller LIVES.... PyInstaller + PySimpleGUI = WinForms
Gosh, a HUGE mega-thank you is owed to @mrsunday334 and @hpca01 get PyInstaller working.
This is a pretty epic kind of event.
pyinstaller -wF your_program.py
This simple line will make a single .EXE file than when executed opens straight into the GUI. No secondary dos prompt window. AND the .exe file is small at 9 MB in total.
This is huge for IT people that have wanted to deploy their tools to users but installing Python is out of the question.
MikeTheWatchGuy 2018-09-22T23:36:07Z
Posted on Reddit - Not above begging for upvotes
I took a chance and posted about the PyInstaller news on Reddit. I done so well there, but I have picked up some great contributors so I'll take the rocks with the roses.
If you want to see how I fared or want to, ahem, upvote, here's where you'll find the post...
https://www.reddit.com/r/Python/comments/9i41la/i_duplicated_a_winforms_experience_in_python/
After 20 minutes I had 3 upvotes going for me.... which lasted for a few more minutes before out came the downvotes. Not sure why I bother except that I do pick up some great supporters. It's just discouraging when some people can't handle being supportive of someone else's effort or success.
MikeTheWatchGuy 2018-09-23T15:15:38Z
It seemed like only yesterday....
Noticed release history while doing the big update to Readme file. It actually seems like eons ago when theses features were added:
Jul 16 (10 weeks ago) All parameters to Elements changed from CamelCase to lower_case
Jul 26 (9 weeks ago) Slider, Listbox elements. Color options
Aug 9 (7 weeks ago) Dictionaries... yes, dictionaries were added only 7 weeks ago.
Aug 16 (6 weeks ago) Columns
Aug 25 (5 weeks ago) Keyboard and mouse events
And the real shocker for me....
Jul 10 (11 weeks ago) First release to PyPI.. Release 1.0
Over 13,000 downloads since release 1.0 (not a huge number, but beats my expectations)
Thank you to everyone! GREAT feature suggestions, awesome support and encouragement. And it just keeps getting better....
MikeTheWatchGuy 2018-09-23T15:41:36Z
Added PyInstaller Recipe to Cookbook
This is such a cool feature! Had to include it in the Cookbook.
MikeTheWatchGuy 2018-09-23T16:23:53Z
3.5.2
A community member discovered a crippling bug. Elements inside of Frame Elements were not being returned in the return values. That means Frames are badly broken. Can't have that sitting around for long.
Also made the Finalize
method chainable. I have updated all of the Demo programs that use it.
This means that form creation, layout and finalize can be a single line of Python code. It's simple to understand and compacts the code by another line. I'm really enjoying using the chaining capability!
form = sg.FlexForm('My form').Layout(layout).Finalize()
This will get you a form that is completely 'formed' so that you can can address elements using Update.
An example can be found in Demo_Canvas.
Prior to the Read, we want to get the Canvas Element so that it can be drawn on.
form = sg.FlexForm('Canvas test').Layout(layout).Finalize()
cir = form.FindElement('canvas').TKCanvas.create_oval(50, 50, 100, 100)
Without the Finalize the Canvas Element cannot be found.
Hoping that this is an accepted practice. It makes things nicer looking and easy to understand in my opinion.
MikeTheWatchGuy 2018-09-23T16:46:22Z
Removed LookAndFeel
capability for Macs
Sorry Mac people, I need to take away the ability to injure yourself. The button problems are forcing me to do this. If you want to customize the look, you can always do it using the SetOptions
function.
MikeTheWatchGuy 2018-09-23T20:40:34Z
Hokey YouTube Video
https://www.youtube.com/watch?v=0jUvMfRmuog
I've been seeing people post SO many whacky and terrible programming tutorial videos that I just had to try it myself.
I also got a screen capture tool for another project and I've been itching to use it.
In my video I write a guess the number game in under 2:30.
I had to delete the first attempt because you can't see the window that it made.
MikeTheWatchGuy 2018-09-23T20:43:22Z
3.6.0
I jammed 3.6.0 so that I could openly post in documents the new PySimpleGUI method, Window, without it crashing when people used it because the PyPI doesn't have it.
When I made the YouTube video I had not thought through that if someone tried to run the code it wouldn't run. DOH! So, out the door it went...without release notes. DOH!
Whatever... it's done...
MikeTheWatchGuy 2018-09-23T23:13:43Z
Windows, Not Forms
We're all creating windows, damnit, not forms.
It dawned on me that FlexForm is a dumb, non-descriptive name for our windows.
So, I made the executive decision to change from FlexForm
calls to Window
calls.
I LOVE the result, especially if you change the variable names too. It "feels" like a real GUI now!
I've had a bitch of a time replacing the 1,300 spots that Form appears in the documentation alone. I had to examine and fix each one as they were unique situations. But, it's DONE, at least for the docs.
Now it's on to the Demo programs.
I feel like I'm living in "1984" and am going back and changing history, "Forms are no longer used, we will use Window from now on"... as I go through all these documents and erase all references to forms.
Next up are the Demo programs. They all needed to be "refreshed" anyway.
I'm learning that this package is evolving at a fast pace. These design patterns that used to feel so permanent, aren't.
The good news for existing users is that I'm leaving the old names alone. My goal is to catch the new wave of users and get them steered into using the naming conventions that I want people to use. They wont' know any better than to use the new names.
MikeTheWatchGuy 2018-09-24T22:23:19Z
Demo Refresh
Went through each Demo program, all 68 of them, and made 2 changes.
-
Changed all exit calls to sys.exit calls so that PyInstaller doesn't crash when extiing
-
Reworked all of the PySimpleGUI calls to follow the same design pattern.
The new way of doing things that are in the Demos now matches the Readme and Cookbooks.
There were these 3 basic design patterns (Learn it, Love it, Live it)
Simple Read Window Call
layout = [[ some layout ]]
window = sg.Window('My new window').Layout(layout)
button, value = window.Read()
Persistent Window with Event Loop
layout = [[ some layout ]]
window = sg.Window('My new window').Layout(layout)
while True:
button, value = window.Read()
If Element needs updating prior to Event Loop (window needs to be finalized)
layout = [[ some layout ]]
window = sg.Window('My new window').Layout(layout).Finalize()
# need a finalize to do things like scribble on a canvas
cir = window.FindElement('canvas').TKCanvas.create_oval(50, 50, 100, 100)
while True:
button, value = window.Read()
I found myself sometimes not adding the Finalize()
onto the end of the and instead writing it on another line just so it's clear a Finalize was required for an upcoming function call.
Generally speaking, these design patterns cover 90%+ of the use cases
It would be nice if we all agreed on some version of these so that PSG code looks similar whenever possible.
I'm thoroughly enjoying the way the latest code reads or I wouldn't be motivated to make these billions of tiny changes.
The chained methods were a huge help in reducing the number lines of code and improved readability.
Some beginners may be puzzled over the chaining, but due to the number of Cookbook examples and amount of Demo code, they will generally not be starting from scratch and will experience these in a functioning program.
MikeTheWatchGuy 2018-09-24T22:30:53Z
The Suggested Design Patterns
You'll find a new Demo. I'm using this as my "Template" for my programs now. Would be nice to get something we can agree on
# DESIGN PATTERN 1 - Simple Window
import PySimpleGUI as sg
layout = [[ sg.Text('My layout') ]]
window = sg.Window('My window').Layout(layout)
button, value = window.Read()
# DESIGN PATTERN 2 - Persistent Window
import PySimpleGUI as sg
layout = [[ sg.Text('My layout') ]]
window = sg.Window('My new window').Layout(layout)
while True: # Event Loop
button, value = window.Read()
if button is None:
break
# DESIGN PATTERN 3 - Persistent Window with "early update" required
import PySimpleGUI as sg
layout = [[ sg.Text('My layout') ]]
window = sg.Window('My new window').Layout(layout).Finalize()
while True: # Event Loop
button, value = window.Read()
if button is None:
break
MikeTheWatchGuy 2018-09-25T00:55:49Z
New Tab Update
I was gluing elements inside of frames to the bottom instead of to the top. The result was clearly incorrect. It's been fixed, but the fix involved changing how ALL elements are packed all windows. In other words, it's a risky change.
I'm anxious to get the Tabs feature released on PyPI because it's been broken for so long and perhaps this was a make or break feature for someone.. I'm really looking forward to seeing the creations people come up with!
Once I get the documentation ready for Tabs tonight, I'll release to PyPI.
MikeTheWatchGuy 2018-09-25T02:26:59Z
Overseas Adoption of PySimpleGUI
It's fun to see how different people, and different cultures, are using PSG. There are some interesting, obscure ones. I ran across this site that has a GUI portion of their Python class that mentions PSG.
http://www.digisoln.com/?py3
I'm in great company and seemed to be the choice given for doing Desktop GUI work. The other choices were console and Flash.
It's clear that the documentation and sample programs were not just copied and used. Someone wrote some code to explain some of the basic Elements
http://www.digisoln.com/?py3&lesson=GUI__moreFormElements
Then there was these encouraging words that came via a Reddit message:
I came across your package last week from the Chinese Linux and open-source communities, posted in the social media platform called wechat. These two posts about your package have been read 4253 and 679 times, respectively. Obviously, your package is getting a lot of attention.
Posts: https://mp.weixin.qq.com/s/2tR7uhG-bXuT0TecqgAPKA https://mp.weixin.qq.com/s/o8CfyXgm03gs07jbngpBAw
And finally, a mention on Twitter....
Somehow PSG and Soccer go together.... it's kinda weird, but I'll take weird :-)
https://www.tweet247.net/australia/vflw
Tony #-e^(iπ) (7 hours ago)
@Asher_Wolf Seeing the Hawks VFLW and VFLM teams win ... and continuing to get my head around python - pySimpleGUI at the moment for developing user interfaces for solutions..
MikeTheWatchGuy 2018-09-25T05:49:52Z
3.8.0
Tabs tabs and more tabs... that's what I hope to see in some of the new GUIs people are building.
Tabs are FINALLY done as close to "right" as I can currently get them. I was anxious to get rid of the old, hacked together version of Tabs which drove the getting the new Tab Element done and out the door. That and it's such a cool feature! I expect that some nice looking advanced stuff coming from the community.
Check out this bit of recursive Window building! What fun being able to put an Output Element into a small tab in the Window.
As pointed out in the readme not all of the color options are available I expect that will change as soon as I can figure out what needs to be done to get it to work.
As always... ENJOY!
MikeTheWatchGuy 2018-09-25T18:00:27Z
PySimpleGUI27 - 1.0.0
It's officially released, the Python 2.7 version of PySimpleGUI
I didn't wake up this morning thinking I would release a 2.7 version. In fact, I had ruled out 2.7 long ago... swearing not to support it.
But, I see the large numbers of people installing on their 2.7 machines AND someone gave me significant instructions that got me over the hump. The rest was grunt work.
I was able to pip2 install it on my windows machine, but my environment is not fully set up to do the import correctly.
If someone can check to see if it works that would be awesome.
The package name for the 2.7 version is
PySimpleGUI27
Not sure how to get the word out in this one. I'll have to retrace my steps perhaps for the Python 3 marketing effort.
MikeTheWatchGuy 2018-09-26T17:35:57Z
A morning without Issues
Was shocked this morning to see no issues logged.... whew! I thought for sure there would be tons of questions about the new PySimpleGUI27 release. I see plenty of PyPI installs already so I know it's being used 👍
MikeTheWatchGuy 2018-09-26T19:34:57Z
2.7 Pent-up Demand
On the first day of availability, with only a single Reddit announcement, the 2.7 version of PySimpleGUI for 406 downloads. That's a pretty strong showing for day 1 with little marketing.
The Python 3 version almost topped 1,000 with 993 downloads yesterday.
Together there were 1,399 installs yesterday, the most so far for a single day.
OK, so maybe I am watching the popularity. It helps me understand where hear about PySimpleGUI and thus were I should make announcements about cool new stuff.
MikeTheWatchGuy 2018-09-26T21:57:36Z
It's already easy....
I made an error by creating the function window.UpdateElements()
this week and am removing it from the SDK.
I find I need to keep myself from over-doing the "make it easy" mantra. I'm learning that it's already easy is sometimes the answer.
Take for example Graph Axis. I wanted to add axis markers to my sine graph. I was toying with the idea of making methods to the Graph Element that would help draw the axis. However, when I thought about what an axis and the markers are, and I coded it up instead within the application, I quickly learned that it's easy for the user to make their own axis markers.
It was a lot easier when I added the DrawText method... (there was no way to draw text until I added it)
Here's my graph:
Pretty spiffy, huh?
While the code to draw the axis is longer than the code to make the plot, it's still quite straightforward and easy to follow:
# Draw axis
graph.DrawLine((-100,0), (100,0))
graph.DrawLine((0,-100), (0,100))
# Draw markers and text X-axis
for x in range(-100, 101, 20):
graph.DrawLine((x,-3), (x,3))
if x != 0:
graph.DrawText( x, (x,-10), color='green')
#Draw markers and text Y-axis
for y in range(-100, 101, 20):
graph.DrawLine((-3,y), (3,y))
if y != 0:
graph.DrawText( y, (-10,y), color='blue'
MikeTheWatchGuy 2018-09-26T23:28:17Z
3.8.2 + 1.0.4
These dual release are going to be the death of me... so will the dual code bases.
There may be a "Freezing" of 2.7 in terms of features until I can get the dual code base problem solved.
I wanted to get a couple of features out today. In particular I want to turn off grab_anywhere. While I really like this feature and thus defaulted it to being on.... it would seem other people find it puzzling. They simply don't understand why their window moves then clicking on a field.
With the widening of the users by 2.7 and I'm seeing actual classes starting to use the package, I want to get it stable and as wrapped-up as I can get it. I dunno about other people, but it feels like PySimpleGUI is at a "good place". The renaming is done, the design patterns look tight and neat. All of the major elements are done and even some of the advanced complex ones.
There are a number of "soft" areas that need some work. So, while it's fun to crank out new capabilities, there is some cleanup to be done. The docs went through major round of cleaning up, so I don't see more happening there. The areas I'm think of are:
-
A united code base
-
Graph methods are f-ing up with 2.7 (points are drawn like lines, the pixels don't seem square, etc)
-
Finish checking 2.7 demos
-
Finish tabs (colors are not done)
-
I know I'm forgetting stuff.. I have a 2-page list written down and a huge issues list
MikeTheWatchGuy 2018-09-27T19:17:51Z
Programming Class Lesson Examples Posted
I have been conversing on Twitter with a teacher that is putting together a lesson plan for next year that includes PySimpleGUI! It's exciting that someone has signed on to give it a try in a teaching environment. This was a primary goal of the entire project.
I have posted some of his examples here on the GitHub under the folder ProgrammingClassExamples. I'm sure he would accept any feedback people have.
I'm finding it fascinating to see how other people are using the SDK. It's already being used in ways I had not thought of... it's a little scary to be honest.
One thing I really liked about the examples is that he picked up the latest design patterns and naming conventions and is following them. (Window, stringing together the Window and Layout calls, etc). It's nice looking code in my opinion. Go give one or two of them a try. Help out our up future software stars.
MikeTheWatchGuy 2018-09-27T20:43:16Z
Old-Style Tabs Are Disappearing - Please port to new-style
The function call ShowTabbedForm and all other functions relating to the old style of tabs are soon going to be completely removed from the code. You should immediately move to the new-style of tabs if you haven't already.
I want to avoid someone finding old docs or reading the code and then using the old, unsupported and 1/2 broken functions.
Out with the old! In with the new Tabs!
MikeTheWatchGuy 2018-09-28T17:01:57Z
Nobody said it would be easy
Last night I tried my hand at my first pull request and I have to say I failed miserably.
I struggled with the GitHub tools. I eventually went through line by line using PyCharm and made the merge that way.
It was a 3-hour process and now that it's done, I still have to go through and write a test harness to test the changes.
This is a part of the project I had not counted on being difficult.
I do want to say a big 'thank you' to @Venim for making several changes to the code that I incorporated, and for being patient as I work through this process.
I hope to finish all the changes and testing them today so that I can get a PyPI release out.
The Popups in the current release still have grab_anywhere turned on by default. They need to default to off.
I forget which at the moment, but a few of the Demo programs will not run with the PyPI release due to new features.
MikeTheWatchGuy 2018-09-28T23:59:18Z
3.8.4
3.83. was a bad release... sorry about that if you picked it up. I did not run through all the tests and I missed testing a merge that I did... incorrectly. For a couple hours the PyPI code had broken menus. It's working now.
Release contents include:
3.8.3
-
Listbox, Slider, Combobox, Checkbox, Spin, Tab Group - if change_submits is set, will return the Element's key rather than ''
-
Added change_subm3.8.3its capability to Checkbox, Tab Group
-
Combobox - Can set value to an Index into the Values table rather than the Value itself
-
Warnings added to Drawing routines for Graph element (rather than crashing)
-
Window - can "force top level" window to be used rather than a normal window. Means that instead of calling Tk to get a window, will call TopLevel to get the window
-
Window Disable / Enable - Disables events (button clicks, etc) for a Window. Use this when you open a second window and want to disable the first window from doing anything. This will simulate a 'dialog box'
-
Tab Group returns a value with Window is Read. Return value is the string of the selected tab
-
Turned off grab_anywhere for Popups
-
New parameter, default_extension, for PopupGetFile
-
Keyboard shortcuts for menu items. Can hold ALT key to select items in men
-
Removed old-style Tabs - Risky change because it hit fundamental window packing and creation. Will also break any old code using this style tab (sorry folks this is how progress happens)
MikeTheWatchGuy 2018-09-29T17:45:02Z
Hide / UnHide Windows
A couple of new Windows methods.
Hide
and UnHide
work as the name says. It will completely hide a window, include removing it from the taskbar.
Several people have requested a Window disable. I implemented a Disable / Enable pair, but it's not working as well as I had hoped. This is one way to make sure people don't interact with your window while you have another window open.
MikeTheWatchGuy 2018-09-30T00:50:32Z
Menu Shortcuts
If you're making an application that has a menu, you can make it look really professional by using Alt-key shortcuts. You can thank @vemin for this code. This menu definition:
# ------ Menu Definition ------ #
menu_def = [['&File', ['&Open', '&Save', '---', 'Properties', 'E&xit' ]],
['&Edit', ['Paste', ['Special', 'Normal',], 'Undo'],],
['&Help', '&About...'],]
made this professional looking window.
And all it took was adding an & in front of the letter you want to underline.
So, go nuts... fool your friends into thinking you wrote a WinForms app. Ha ha ha! No WinForms needed here in order to get a nice looking Window.
MikeTheWatchGuy 2018-09-30T05:12:14Z
107 Pages
That's how long the ReadMe is when pasted into Microsoft word. That doesn't count the Cookbook which adds another 45 pages. I've created a PDF from the Cookbook and uploaded it to the Docs folder
The question is whether or not people read them. I really don't know if the docs are actively used.
Speaking of documentation and Cookbooks, I created a One Minute Cookbook. The Recipes are shown in a table format with a screenshot. Here's an overview of a few pages.
emallay 2018-09-30T05:37:47Z Personally, I love the docs – when I am looking at using one of PSG's features it is nice to be able to quickly find a realistic usage case and some suggested best practices. Along with the demos, they make it easy to quickly dive into things.
john144 2018-09-30T09:34:51Z I use the docs a lot, too.
On Sun, Sep 30, 2018 at 12:37 AM emallay notifications@github.com wrote:
Personally, I love the docs – when I am looking at using one of PSG's features it is nice to be able to quickly find a realistic usage case and some suggested best practices. Along with the demos, they make it easy to quickly dive into things.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142#issuecomment-425696191, or mute the thread https://github.com/notifications/unsubscribe-auth/AGKiYue4lUYqigDOTJQmbBqELpFyr0_qks5ugFirgaJpZM4WdqH- .
MikeTheWatchGuy 2018-09-30T17:36:29Z
PyCompactGUI
Every time I see a post on Reddit where someone has coded up a GUI in their favorite framework, I like to see if I can duplicate the results using PSG.
This is NOT an attempt to knock anyone else's efforts. I have bundles of respect for anyone with the courage to take what they've produced and put it up for public comment. It takes bravery, this I can state from experience.
There was a cool one posted yesterday that takes my CPU meter one step further. It's a graphics display of system stats. The poster wrote it in Qt. I found this particularly interesting.
https://www.reddit.com/r/learnpython/comments/9k3weg/i_just_made_my_first_python_gui_app_and_im_super/
I was able to use their module that does all of the stats gathering using psutil. I wasn't able to duplicate the stats however as that module kept crashing on certain stats, even when I ran it on Linux as the poster stated they did. For those stats, I re-used the CPU count.
This is the poster's Qt screen:
And this is the screen from PSG:
The layouts are almost identical.
Of course the question that I am seeking the answer to is "how much code" was required.
Not counting the stats collection, just looking at the GUI portion:
Qt - 213 lines of code
PSG - 43 lines of code
I made no attempt to compact code by removing blank lines, however if I did remove the blank lines from the total, the number would be 34 lines of actual code.
Rather than post the code as a file, I'm going to just paste the code here. I don't want to put it in the main GitHub, but I do want to share it to see if maybe I could have done something better.
One reason for the compactness is the data_dict dictionary. With it I'm able to loop through getting Element Keys and the function that should be called to get the value to be displayed using the Key. This compacted the event loop down to only 2 lines of code above the normal Read / Check for quit.
I'm actually really surprised at how short it ended up being, which is why I'm posting it here as an example.
You can knock this package for all the things it lacks, but 'results' is not one of its weak points. It's really hard to argue with the end-results.
#!/usr/bin/env python
import PySimpleGUI as sg
from modules import *
sg.SetOptions(element_padding=(3,1), auto_size_buttons=False, button_element_size=(12,1))
cpu_frame = [[sg.T('Number of CPUs'), sg.T('',key='_cpus')],
[sg.T('Clock Speed'),sg.T('', key='_clock')],
[sg.T('CPU Utilization'), sg.T('', key='_util')],
[sg.T('')]]
power_frame = [[sg.T('CPU Temp'), sg.T('',key='_ctemp')],
[sg.T('GPU Temp'),sg.T('', key='_gtemp')],
[sg.T('CPU Fan'), sg.T('', key='_cfan')],
[sg.T('GPU Fan'), sg.T('', key='_gfan')]]
ram_frame = [[sg.T('Total'), sg.T('',key='_rtotal')],
[sg.T('Used'),sg.T('', key='_rused')],
[sg.T('Available'), sg.T('', key='_ravail')],
[sg.T('Percent Utilized'), sg.T('', key='_rutil')]]
storage_frame = [[sg.T('Total'), sg.T('',key='_stotal')],
[sg.T('Used'),sg.T('', key='_sused')],
[sg.T('Available'), sg.T('', key='_savail')],
[sg.T('Percent Utilized'), sg.T('', key='_sutil')]]
layout = [[sg.Frame('CPU', cpu_frame), sg.Frame('Power', power_frame)],
[sg.Frame('RAM', ram_frame), sg.Frame('Storage', storage_frame)],
[ sg.RButton('Refesh', pad=((350,0),0)), sg.Button('Exit', pad=((10,0),0))]]
window = sg.Window('PC Status Details Under the Hood', auto_size_text=False, default_element_size=(15,1)).Layout(layout)
data_dict = {'_cpus': cpu_count, '_clock' :cpu_count, '_util':cpu_utilization,
'_ctemp': cpu_count, '_gtemp': cpu_count, '_cfan': cpu_count, '_gfan':cpu_count,
'_rtotal': ram_total, '_rused': ram_used, '_ravail': ram_available, '_rutil':ram_utilization,
'_stotal': storage_total, '_sused': storage_used, '_savail': storage_available, '_sutil':storage_utilization}
while True: # Event Loop
button, value = window.Read()
if button is None or value is None:
break
for key, value in data_dict.items():
window.FindElement(key).Update(value())
MikeTheWatchGuy 2018-09-30T18:10:04Z
New 3.8.5 release posting to PyPI today
I'm posting a new version today to PyPI. Anyone have a feature they want to make sure is included?
Currently it has these:
-
Fix for Menus.
-
Fixed table colors. Now they work
-
Fixed returning keys for tabs
-
Window Hide / UnHide methods
-
Changed all Popups to remove context manager
The only "new" functionality Table Hide / UnHide.
MikeTheWatchGuy 2018-09-30T23:57:13Z
Update errors
Would like to know if anyone is using a try block around calls to Element.Update()
I made an error checking change could cause a problem with your code. Please post if use try's with Update.
MikeTheWatchGuy 2018-10-01T00:18:15Z
Use PyCharm's macro capabilities!
Maybe I'm the only one making lots of GUIs on my scratchboards, if so, you can ignore this. I find myself throwing together GUIs a lot while trying to help people, making new Demos, etc.
I got tired of typing the same template code or opening a template .py file, copying, pasting, etc.
PyCharm to the rescue. I used their "Live Template" feature.
I type Control+J and I see this
If I choose the simple one I get this typed into my window:
And if I choose persistent I see this one
"poof! Instant running GUI"
MikeTheWatchGuy 2018-10-01T00:48:01Z
Confirmation GUI
I was adding an item to my toolbar, a Release to PyPI one to be specific and I want to be SURE before something like that happens. So I added this if statement.
if (sg.PopupYesNo('Are you sure?', keep_on_top=True) == 'Yes'):
print('Doing important stuff here')
else:
print('** Cancelled **')
I got this little box popped up on top of everything else
Debug your GUI using the GUI
MikeTheWatchGuy 2018-10-01T02:03:46Z
3.8.6
-
Fix for Menus.
-
Fixed table colors. Now they work
-
Fixed returning keys for tabs
-
Window Hide / UnHide methods
-
Changed all Popups to remove context manager
-
Error checking for Element.Update calls ( no more crashes when calling Update on a bad element!)
MikeTheWatchGuy 2018-10-01T20:23:13Z
tab_location Setting For TabGroup Element
Something for all you advanced Tab-users. You can now specify the location your tabs will show up by setting the tab_location parameter in you TabGroup Element. Choices are top, bottom, left, right.
MikeTheWatchGuy 2018-10-01T21:25:09Z
PySimpleGUI Tutorial on YouTube
It seems like some people want to learn by watching other people code on YouTube.... so, I took a chance and stuck my neck out by making a video that shows how to build a CPU Meter using PySimpleGUI.
Here's my Reddit post if you're interested.
https://www.reddit.com/r/Python/comments/9kkine/tutorial_build_a_cpu_utilization_meter_using/
Personally, I don't think I could stand watching me code for 5 minutes, but who knows, maybe other people like this kind of stuff.
MikeTheWatchGuy 2018-10-01T23:14:39Z
Coding Convention
I've presented a number of Templates and Design Patterns in the documentation, cookbook and demo files.
I openly steal good ideas from the PSG community. I just found a new one that I really like that concerns keys that I'm swiping and modifying that came from @jfongattw.
We're all using keys a lot more since they are used to identify elements. I have modified the way I am naming my keys. I am adding '_' to the beginning and ending of my key values. This makes spotting keys in the code trivial (I like trivial).
The tutorial I did earlier today used keys like this:
[sg.Text('', size=(8,2), font='Helvetica 20', justification='center', key='_text_')],
Later when I needed to update that element:
window.FindElement('_text_').Update(f'CPU {cpu_percent:02.0f}%')
I like this enough that I'm going through the code and docs to rename all my keys this way. I would like to set this as the design pattern newcomers to adopt in their key values. If you're using keys, give it a try and let us know what you think.
MikeTheWatchGuy 2018-10-02T00:07:42Z
New "advanced" widgets
I've been on the lookout for new ways of displaying information. It would be nice to be able to build a Dashboard using PySimpleGUI. I can do this using both Matplotlib as well as other methods.
I just stumbled on an interesting one. This program uses Pillow to create a PNG of a speedometer. I just ran it with a value of 87. The result was this:
I should be able to adapt this to output to an Image Element.
https://github.com/Andrew-Shay/python-gauge
Another COOL METER!
I found this posted on StackOverflow... it's amazing what people post sometimes. Sometimes it's an entire implementation, like this one!
import tkinter as tk
from math import pi, cos, sin
class Meter(tk.Frame):
def __init__(self, master=None, **kw):
tk.Frame.__init__(self, master, **kw)
self.meter = []
self.angle = []
self.var = tk.IntVar(self, 0)
self.canvas = tk.Canvas(self, width=200, height=110,
borderwidth=2, relief='sunken',
bg='white')
self.scale = tk.Scale(self, orient='horizontal', from_=0, to=100, variable=self.var)
for j, i in enumerate(range(0, 100, 5)):
self.meter.append(self.canvas.create_line(100, 100, 10, 100,
fill='grey%i' % i,
width=3,
arrow='last'))
self.angle.append(0)
self.canvas.lower(self.meter[j])
self.updateMeterLine(0.2, j)
self.canvas.create_arc(10, 10, 190, 190, extent=108, start=36,
style='arc', outline='red')
self.canvas.pack(fill='both')
self.scale.pack()
self.var.trace_add('write', self.updateMeter) # if this line raises an error, change it to the old way of adding a trace: self.var.trace('w', self.updateMeter)
self.updateMeterTimer()
def updateMeterLine(self, a, l=0):
"""Draw a meter line (and recurse for lighter ones...)"""
oldangle = self.angle[l]
self.angle[l] = a
x = 100 - 90 * cos(a * pi)
y = 100 - 90 * sin(a * pi)
self.canvas.coords(self.meter[l], 100, 100, x, y)
l += 1
if l < len(self.meter):
self.updateMeterLine(oldangle, l)
def updateMeter(self, name1, name2, op):
"""Convert variable to angle on trace"""
mini = self.scale.cget('from')
maxi = self.scale.cget('to')
pos = (self.var.get() - mini) / (maxi - mini)
self.updateMeterLine(pos * 0.6 + 0.2)
def updateMeterTimer(self):
"""Fade over time"""
self.var.set(self.var.get())
self.after(20, self.updateMeterTimer)
if __name__ == '__main__':
root = tk.Tk()
meter = Meter(root)
meter.pack()
root.mainloop()
MikeTheWatchGuy 2018-10-02T01:27:33Z
New Demo Program - LED Status Indicators
Slowly trying to duplicate what I see on other GUIs out there. One popular use for GUIs is to display status or show a Dashboard. A "Stoplight indicator"or LED indicator is a popular widget on Dashboards.
I created a couple of little functions that make it easy to add these to your Windows.
This layout
layout = [[sg.Text('My layout')],
[sg.Text('CPU Use'), LEDIndicator('_cpu_')],
[sg.Text('RAM'), LEDIndicator('_ram_')],
[sg.Text('Temperature'), LEDIndicator('_temp_')],
[sg.Text('Server 1'), LEDIndicator('_server1_')],
[sg.RButton('Read The Window'), sg.Exit()]]
Produced this window:
To change one of the indicators:
SetLED(window, '_cpu_', 'green')
MikeTheWatchGuy 2018-10-02T04:10:24Z
UNIFIED CODE BASE!
A HUGE thanks is owed to @rtrrtr for help with Pasteurize!! THIS solved SO many problems.
I now have a single code base. I generate the PySimpleGUI27.py file from my core PySimpleGUI.py file. No more completely separate files. Whew! It was really stressful running 2 code bases. The 2 version was lagging already and I wasn't going to be porting stuff over anytime soon.
Now I'm going to publish the thing on PyPI and see if it works!
I've just uploaded it to Master.. but will soon pop it up on PyPI. Experience tells me that having it in Master doesn't actually buy much usage or early testing. Few people download from Master, especially for Version 2.7.
So, I'm going to roll the dice. I'm going to do a unified PyPI release... both at the same time so they're in perfect sync. Yea, I'm cranking through the release numbers, but, heck, I'm cranking through the releases so it's not like I'm inflating the numbers. These are hard earned releases damnit.
MikeTheWatchGuy 2018-10-02T04:38:35Z
3.9.0 & 1.1.0 The first unified release
It's done.... a single PySimpleGUI codebase release.
Let's hope it doesn't go south on us. I think it should be fine, but I've thought that many times when disaster was moments away.
The only feature change for the P3 version is Tab Locations, a really cool feature in my opinion and one I hope people will explore. Surely there's some cool GUI layouts that must exist using tabs on the left or bottom of windows. Try them out. I may need to add more options for locations. You'll soon see there's a top and bottom on the left side :-)
Enjoy!
1.1.1 Ooopss....
I forgot to put in the readme that for the 2.7 version you need to pip install future
jondkelley 2018-10-05T00:33:14Z Love your enthusiasm, this is a great project.
MikeTheWatchGuy 2018-10-05T02:15:18Z Why thank you! I'm certainly "into this project". Glad to see you're a fan of it too. When looking at the results of the project alone, it's a rather remarkable capability. I've never seen anything like it, in any language. Cross-platform GUI development across Windows, Mac and Linux is downright easy / trivial using PSG. Someway, maybe someday, it can be extended to Android and iOS. That would be awesome!
MikeTheWatchGuy 2018-10-05T05:18:31Z
Demos demos demos
I've been adding more demos lately. I've not said much here about them. We're up to 76 Demo programs. Two I added tonight that I like are Pyplot programs that both create bar charts. I thought that maybe a few people would be inspired by the simplicity that they may jump in and try making some of their own. You've got more toes than there are lines of code.
Check out how downright trivial it is to produce these charts. Who said Excel was the best at all-things-numbers. I dunno about you, but I've struggled over the past 5 or 6 years to create simple graphs in Excel. They've made it hard. Cheat and use Python instead next time.
I've started to create Demos in pairs. One for the super-simple case and then another that's more complex. For these bar charts, they are both pretty simple.
The way these demos work is that you paste the Pyplot code into the marked section.
# ------------------------------- PASTE YOUR MATPLOTLIB CODE HERE -------------------------------
import numpy as np
import matplotlib.pyplot as plt
values_to_plot = (20, 35, 30, 35, 27)
ind = np.arange(len(values_to_plot))
width = 0.4
p1 = plt.bar(ind, values_to_plot, width)
plt.ylabel('Y-Axis Values')
plt.title('Plot Title')
plt.xticks(ind, ('Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'))
plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0],), ('Data Group 1',))
# ------------------------------- END OF YOUR MATPLOTLIB CODE -------------------------------
A slightly more complex version
#------------------------------- PASTE YOUR MATPLOTLIB CODE HERE -------------------------------
import matplotlib.pyplot as plt
import numpy as np
label = ['Adventure', 'Action', 'Drama', 'Comedy', 'Thriller/Suspense', 'Horror', 'Romantic Comedy', 'Musical',
'Documentary', 'Black Comedy', 'Western', 'Concert/Performance', 'Multiple Genres', 'Reality']
no_movies = [941, 854, 4595, 2125, 942, 509, 548, 149, 1952, 161, 64, 61, 35, 5]
index = np.arange(len(label))
plt.bar(index, no_movies)
plt.xlabel('Genre', fontsize=5)
plt.ylabel('No of Movies', fontsize=5)
plt.xticks(index, label, fontsize=5, rotation=30)
plt.title('Market Share for Each Genre 1995-2017')
#------------------------------- END OF YOUR MATPLOTLIB CODE -------------------------------
MikeTheWatchGuy 2018-10-05T18:41:49Z
Themes for Tabs
You enable them by adding the theme
parameter to the TabGroup
element.
New feature of the day.... themes for tabs.
Make your tabbed windows look even better by throwing a theme onto theme.
You have 8 to choose from on Windows and 5 to choose from on Linux. I dunno about Mac.... likely only 1 for you Mac people (and you should be happy with that ;-)
I was surprised to see the code crash and burn when using 3 of the themes on Linux. Those 3 are winnative, vista and xpnative. Yes, all windows terms, but damn, can't you at least use those designs on Linux. Linux "borrows" stuff from Windows all the time.
Choices for Windows
No theme parameter
THEME_VISTA
THEME_CLASSIC
THEME_CLAM
THEME_ALT
THEME_DEFAULT
THEME_WINNATIVE
Linux Themes
No theme specified
THEME_DEFAULT
THEME_CLASSIC
THEME_CLAM
THEME_ALT
As usual, the docs are lagging in telling you about this.... so consider it a treat for you "announcement" readers. It'll be released on PyPI soon. There are getting to be enough features for a release. The Tab features are drawing to a close, despite not yet figuring out how to set the tab background color (admitting de-feet)
MikeTheWatchGuy 2018-10-05T20:29:53Z
Ideas for new features
I read a lot of sites, looking for information about ttk or tkinter features I've not yet implemented or that I can implement better.
Today I found this rather remarkable site.
https://pyinmyeye.blogspot.com/
I thought it may inspire some of us to come up with more creative features.... not that I've run out of features!! There is still much work to do in implementing the Tree Element and fixing up the Table Element. Still, it's fun to be able to provide a rich menu of things for you to add to your GUIs.
We've got a good thing going and I need your help and encouragement in order to keep new stuff coming. I clearly am not coming up with these things on my own.
MikeTheWatchGuy 2018-10-05T21:44:10Z
www.PySimpleGUI.org Documentation Improved
Remember that you can quickly get to the read-the-docs for PSG by going to www.PySimpleGUI.org . This is where I send people as an introduction to the package. www.PySimpleGUI.com on the other hand brings you to the GitHub. http://tutorial.PySimpleGUI.org will get you the tutorial.
I went through the "readme" which is actually the User Manual, and updated the outline levels so that now you can quickly jump to individual Element definitions.
The TOC looks like this for the section that covers the Elements:
Clicking on the Checkbox Element brings you straight to the parameters definition for the Element:
While not a huge change to in terms of the number of characters changed, the usefulness of this document just jumped way up.
MikeTheWatchGuy 2018-10-06T00:03:09Z
New coding convention
I've proposed a couple of coding conventions that I've adopted. I'm just now starting this one so I dunno if I'll stick with it.
The Window definitions sometimes have a number of parameters set. While the Elements also have lots of parameters, you can't really do much to improve readability because they are in the middle of a window layout definition.
I've started to break apart the parameters and putting them one per line, just like I did the call definitions on the ReadMe file.
# Make a window
window = sg.Window('My window',
default_element_size=(20,1),
auto_size_text=False,
return_keyboard_events=True,
text_justification='right').Layout(layout)
I think the readability greatly outweighs the downside of taking up more lines of code.
Hoping I can remember to do this! If you see I'm not in something new I'm posting, please say something. I'll do this to the Demo programs, Cookbook, tutorial and readme file as I'm doing other updates.
MikeTheWatchGuy 2018-10-06T16:59:15Z
New Killer Demo!
Another day, another PSG demo....
Today something that we can all actually USE for a change.
It's a process killer using psutil. I've checked it out on both Windows and Linux and it's working great. Sorry Mac people, you're likely left out of the party since all the cool features are broken on mac 👎
The filename is
Demo_psutil_Kill_Processes.py
Follow the on-screen directions.
You can kill more than 1 process by selecting more than 1 in the listbox. To do this, hold the control key while making your selection.
If you have suggestions on making it better, speak up. I thought about making it a "stay on top window" as these utilities tend to be more useful if on top of the windows you want to kill.
I'm creating a hot-key to launch this program and am giving up using taskmanager for this task.
Enjoy!
MikeTheWatchGuy 2018-10-06T17:06:31Z
More Look and Feel
Now you can create your own Look and Feel entry. The table has been exposed for your abuse.
To add an entry, insert a line of code with your definition and another line to pull it up and use it.
sg.LOOK_AND_FEEL_TABLE['Topanga_Dark'] = {'BACKGROUND': '#282923', 'TEXT': '#E7DB74', 'INPUT': '#282923',
'SCROLL': '#E7C855', 'TEXT_INPUT': '#45473D', 'BUTTON': ('#E7C855', '#284B5A'),
'PROGRESS': "#282923", 'SCROLL': '#282923', 'BORDER': 1,'SLIDER_DEPTH':0, 'PROGRESS_DEPTH':0}
sg.ChangeLookAndFeel('Topanga_Dark')
This will enable users to easily share look and feels and it'll give me the opportunity to pull more of them into the standard library of color schemes. I've already stolen one color scheme, Topanga.
MikeTheWatchGuy 2018-10-06T18:45:25Z
SDK Quick Reference
Just released a demo program that will help you with finding the options available for each of the elements. You can use this instead of looking through the source code. It has every parameter currently available documented. Hopefully it won't drift too far out of date.
Get the file Demo_PSG_SDK_Quick_Ref.py
MikeTheWatchGuy 2018-10-06T20:25:43Z
First Serious Tutorial (Is in Chinese)
https://blog.csdn.net/qimi923511491/article/details/82936460
I've stumbled on the first serious looking tutorial on PySimpleGUI that someone else wrote. I've heard from Asian users that PSG is popular in Asia. I see some evidence of this popping up here and there.
It's fun to read someone else's description of the package. I wouldn't expect a tutorial to just straight to using Frames, but it looks like that's what they're doing. Clearly has an eye for making nice looking GUIs 👍
There's a twist to it all however.... it is actually a tutorial on integrating PySimpleGUI and PySerial. I didn't realize it, but PySerial is a HUGELY popular package. Today that got over 46,000 downloads!!!!
I can only hope this program gets picked up by their users and they then develop it further! It's awesome to see people using the package to create something new and usable.
MikeTheWatchGuy 2018-10-06T21:26:27Z
More PSG In The News...
Stumbled upon this document showing PSG on a list of important packages for this programming course.
Further down in the document you'll see PSG...
Of course there are a LOT of GUI packages listed. The point is that we made it onto the list. The course that is using this list is UBLIS 503 at University of Buffalo.
MikeTheWatchGuy 2018-10-07T03:06:25Z
Filtering Design Pattern
While playing around with my "Process Killer" app I came up with a pretty cool new feature that I'm sure I'll reuse.
The feature is a "text filter". The idea is to type in an input box and the program will use that value to narrow down the list of items in a listbox. It happens super-quickly too... as fast as you type!
Here's the list of processes after doing a refresh...
Then I started typing characters into the text input box and the listbox began to get smaller and smaller. I eventually found the task I was searching for after a few letters.
Unfortunately I stumbled onto a bug while writing this. For some reason the list of values doesn't scroll on windows. It doesn't on Linux. Something tells me it has to do with the fact the list was initially empty.
MikeTheWatchGuy 2018-10-07T04:27:37Z
Process Killer Posted on Reddit
https://www.reddit.com/r/Python/comments/9m2dqe/i_made_a_process_killer_utility_with_a_gui/
I decided to post the process killer app on Reddit. I dunno if many people will like it. I do know that some of the best contributors to PSG were introduced to the package through Reddit. So, I make it a habit to post on Reddit on a regular basis.
MikeTheWatchGuy 2018-10-07T05:11:00Z
Turtle Integration
This is one I've been wanting to get knocked out for quite a while. I'm slowly working my way through features and capabilities that kids would be interested in.
Next up along these same lines is the ability to draw willy-nilly on a canvas with the ability to save the result somewhere.
MikeTheWatchGuy 2018-10-07T18:42:38Z
HowDoI
If you've not looked at the very end of the Readme, I highly suggest you do and read the section on a utility named HowDoI. One of the Demo programs is a front-end onto this amazing utility. My programming productivity has grown several-fold since discovering it.
The command-line utility HowDoI is itself a clever front-end to StackOverflow. It takes your query and searches for the number 1 answer to your question. It then presents the code that was included with that number 1 answer.
The result is an encyclopedia of "how can I do this thing".
I use this on average of at least 3, sometimes 10, times a day. It's good for any programming language. I've been doing c# development and it's saved me many times. I use it often enough that I have a hotkey defined that launches it.
For Python, it's a fantastic way to grab simple algorithms or syntax. Sure, you may know how to do one of these things or can figure it out, but why bother if you can instantly get one or more solutions.
Here's an example for today..... Random string of characters. I want to mock something up with a string of characters. Rather than take the 5 minutes to figure it out, I typed
python generate random string
into my how do I utility and I got this:
I simply copy, paste into my code and move on.
Bonus points to the poster for a proper use of the _ variable name. It actually is helpful to see it used in this particular instance as you can instantly see this variable is not used at all in the main expression. BTW, you won't find any use of _ in PySimpleGUI as I really don't recall having a spot where it fit.
I can hear the groans about copying and pasting code. For a seasoned programmer, this is a fine thing to do. If I don't know what's good code from bad now in my career, I deserve to be forever banned from computers. I DO know good code, damnit, so I should be able to use something like this free from guilt.
So, give yourself a "programming power-up". You may be as shocked as I was to find just what a huge help this is.
MikeTheWatchGuy 2018-10-07T19:35:01Z
PopupQuick
There's a new Popup in town.... PopupQuick
It's just what it sounds like... a quick-Popup.
By quick I mean - it doesn't stick around for very long and it doesn't block your code.
It is a self-closing, non-blocking call. Use it to show a quick status message without stopping the flow of your program.
I'm finding it really handy for debugging. If I don't want to parse through the print output and the message is brief, then this is my new goto communication mechanism.
MikeTheWatchGuy 2018-10-07T19:36:13Z
New Releases Posting to PyPI today
There are enough features piled up in PSG that it's getting to be time to push out another release. Will be posting later today so if there's a feature that you want to make sure is in there, now is a good time to say something.
MikeTheWatchGuy 2018-10-08T04:48:39Z
SDK Quick Reference Demo Application
Version 2 of this demo looks a lot better than the first. It could be better still, but this is about as far as I'm taking this one for the time being.
I wanted to try out the tabs located on the left. For this application they worked pretty well. It's similar to a listbox interface
The tab "Styles" / "Themes" need work. I am still unable to change the tab background color nor can I set the font on the tab. I'm sure I'll be coming back around to tabs in the near future. For now it'll have to do as things are at the moment.
MikeTheWatchGuy 2018-10-08T17:11:42Z
3.9.1 & 1.1.2 Released
Just posted to PyPI
-
Tab features
-
Themes
-
Enable / Disable
-
Tab text colors
-
Selected tab color
-
-
New GetListValues method for Listbox
-
Can now have multiple progress bars in 1 window
-
Fix for closing debug-output window with other windows open
-
Topanga Look and Feel setting
-
User can create new look and feel settings / can access the look and feel table
-
New PopupQuick call. Shows a non-blocking popup window with auto-close
-
Tree Element partially done (don't use despite it showing up)
The docs are lagging a tad for some of these features like Tab themes & colors, the new PopupQuick call.
Not the largest release so far, but it does put a bow, for now, on Tabs.
Note that the Tree Element coding has started, and it does show up as a class, but it's not done so it won't do anything useful if you tried it.
MikeTheWatchGuy 2018-10-08T17:50:51Z
GUI Programming Class Materials
I have just uploaded the latest set of materials created by Tony Crewe, a teacher in Australia. These are some of the best examples I've seen yet of using the SDK.
He did clever things like placed windows in locations on the screen in a way that it looks like they were created from a single window. His program "8d Tables - add logo" is one such file. Here's the result from executing it.
It first shows this window:
After you choose a CSV file, the screen changes to this:
There are no doubt many things I'm going to learn from looking at Tony's code! This is one of the most clever things I've seen. For those of you wanting to see "Expanding" windows, here's one way of doing it.
You'll find all of Tony's examples posted in a subdirectory named "Programming Class Examples" in this GitHub
MikeTheWatchGuy 2018-10-08T22:58:09Z
Disabled Elements
I finally got around to adding the disabled
parameter to the remainder of the element. Previously you had to use the Update method to get elements to Disabled. Now you can do it when you create the element. It's checked into the Master Branch.
MikeTheWatchGuy 2018-10-09T01:28:25Z
OpenCV Webcam Integration
I finally got the OpenCV and PySimpleGUI integration to work. I was able to play from a file, but it was a bit of a hack, saving every frame to disk. I've seen a lot of requests posted from people looking to show an webcam using OpenCV with a GUI. Now it can be done easily using PySimpleGUI.
I posted a new Demo file... Demo_OpenCV_Webcam.py or something close to that.
I hope someone makes a really good AI program using it!
MikeTheWatchGuy 2018-10-09T11:51:55Z
Doc-Strings and Disabled Buttons
-
Finished up the Disabled Elements capability by adding parm to all shortcut buttons such as Submit, Quit, RButton, etc.
-
Doc strings added to all Elements
-
Various cleanup of old tab code
MikeTheWatchGuy 2018-10-09T12:03:45Z
New PDFs posted
A few days back I used a website to generate PDF files from the current Readme and Cookbook. I know some of you prefer the PDFs. They are posted on the GitHub site under docs.
MikeTheWatchGuy 2018-10-09T13:33:04Z
Window - Disappear Reappear
This should appeal to those of you creating "Dialog Boxes", Popup windows that appear over the top of your main window. Previously the only option to keep the user from entering data in the main window was to call window.Disable. Now you can make the entire window disappear by calling Window.Disappear.
#!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
layout = [[ sg.Text('My Window') ],
[ sg.RButton('Disappear')]]
window = sg.Window('My window').Layout(layout)
while True:
button, value = window.Read()
if button is None:
break
if button == 'Disappear':
window.Disapper()
sg.Popup('Click OK to make window reappear')
window.Reappear()
MikeTheWatchGuy 2018-10-10T01:47:31Z
Tree Element !
OK, the initial release of the tree element is in Master Branch. You'll find a demo program that shows you how to do it. Also, the Readme / ReadTheDocs has been updated with information on how to use it.
I wanted to do a Demo program that crawled a folder tree and populated the tree with the file sizes, but I got too tired and went with a simple one. Maybe someone else can do the folder version.
Enjoy!
MikeTheWatchGuy 2018-10-10T04:59:17Z
Table Row Colors
In order to make tables more readable I've implemented a new parameter for the Table Element:
alternating_row_color
Every other row will be shaded with this color if it's set.
The effect is something along these lines.
MikeTheWatchGuy 2018-10-10T21:45:57Z
Reddit post on GUIs
https://www.reddit.com/r/learnpython/comments/9mzhqj/best_tutorialsresources_for_python_guis/
I can only do so much shameless promotion on my own. After a while people get a little tired of yet another Demo program using PySimpleGUI
However, I don't feel bad responding to people asking for help / assistance on finding a GUI framework.
This post is a particularly good one to respond to as the poster is asking for GUIs with tutorials.... the only thing PSG has oodles of is Tutorials and Demo programs.
_
If there are any of you fine readers of this announcement that care to second the nomination of PSG as a good framework, I sure would appreciate the help.
_
The only way to get found in the sea of posts and searches, is unfortunately to post. "If you build it they will come" does not at all apply to Python Packages. PyPI is loaded with great Python packages that never get found.
MikeTheWatchGuy 2018-10-11T04:18:51Z
Move over PyGame
Maybe not PyGame, but PyBoardGame ; -)
Demo_Chess_Board.py
Recieved info about an AI project related to Chess and was curious what it would take to render a chessboard like this one. After some new feature additions I found that it takes 100 lines of code.
I think it looks pretty cool and will be even better once it's brought to life by an AI back end.
There are a couple of tabs waiting to be filled out with AI tuning parameters and statistics. This one should be fun.
MikeTheWatchGuy 2018-10-11T19:35:34Z
Chess Anyone?
More progress on the Chess game. I've checked into the GitHub a folder named Chess that has the app and all of the images required. It should work right out of the box.
What it currently does it play back games stored in the PGN file format. First open a PGN file, then click on any square and it'll advance the game by 1 move, moving the piece on the board.
I'm trying to duplicate the user interface found on this site.
It turned out to be a much easier task than I thought it would be. I did have to make some changes to the Button Element to allow for image changes in the Update method. I'll be checking them into PyPI shortly so that you can run this program using the pip installed PSG. I managed to code it all up from scratch, including the core PSG changes, in 1 evening.
I'm also learning that moving large element groups around is quite easy. For example at first all of the controls were on the tab with the board. Pulling them out so that they always stayed visible required adding a Column to the main window that is outside of the tab group.
Sizing the buttons turned out to be easy too. They simply sized themselves to fit the images. The images were easily found on the WikiCommons site. It looks like the site I'm copying also get the pieces from the same location as our boards are identical (except I just noticed I swapped black and white).
Where this is headed is that it will be hooked up to an AI engine. I'm working with a Reddit poster that said they needed some help choosing a GUI framework. I use opportunities like this to drive the features. Without this little project the new button features wouldn't have been available.
MikeTheWatchGuy 2018-10-11T19:50:42Z
Slack Channel
I rarely use Slack, but sometimes it's a real help with debugging, etc. I've created a PySimpleGUI channel. If you use slack and want to drop in, here's a link that's good for a week:
https://join.slack.com/t/pysimplegui/shared_invite/enQtNDUzNzE4Mzg2MDQ4LTc5OGZlMzYxZjBiMDc3OTI5YTUxOWZlOTI1M2NlZDA5Y2JlMDY5N2MwMWQzNWIzNTM4ZmFlOTdhZjU4ZTEyYmM
MikeTheWatchGuy 2018-10-11T20:18:02Z
3.9.3 & 1.1.3
Hefty release this time. Every element was touched in some manner. Plus the new TREE ELEMENT makes its first appearance.
-
Disabled setting when creating element for:
-
Input
-
Combo
-
Option Menu
-
Listbox
-
Radio
-
Checkbox
-
Spinner
-
Multiline
-
Buttons
-
Slider
-
Doc strings on all Elements updated
-
Buttons can take image data as well as image files
-
Button Update can change images
-
Images can have background color
-
Table element new num_rows parameter
-
Table Element new alternating_row_color parameter
-
Tree Element
-
Window Disappear / Reappear methods
-
Popup buttons resized to same size
-
Exposed look and feel table
MikeTheWatchGuy 2018-10-12T05:32:26Z
Getting the word out...
A
BIG thank you
to those of you out there helping to get the word out about PySimpleGUI. I see the posts and they're appreciated.
I've tried to make it easy to recommend by creating some URLs. The best place to send people is the documentation rather than the GitHub site. Simply tell people to visit:
http//www.PySimpleGUI.org
That will take you to the readthedocs entry which has the full doc as well as the Cookbook and the Tutorial.
Note... be careful, particuarly on Reddit, of just typing in www.PySimpleGUI.org by itself. Reddit sticks a "https" onto the front which will FAIL for my site because it has to be http not https because of how it forwards.
MikeTheWatchGuy 2018-10-12T18:46:18Z
Large update to Readme (18 pages added)
The docs now total 206 pages.
As much as I despise updating the damned docs, I know it's the right and only thing to do. There IS no other choice. Actually I suppose the choice is seeing a billion questions posted as well as no one using this package.
This update included listing ALL of the Methods available for the Window object and all of the Elements (the Update methods in particular). I'm surprised they were not already in there. I also noticed the Image Element was not yet documented.
This should bring the docs up to match the current PySimpleGUI.py source code. I added the new parameters to each Element. Also explained the "common" parameters like font, colors, the keys, etc.
It still has a ways to go in explaining how to do "complex" GUIs that use persistent windows and update elements. I make an attempt at it, but it's so deep into the document that I'm not sure if it gets read. Not even sure what the right heading is for that section.
If you notice something not right in the docs, please don't say something... no, wait, DO say something.
I'm confident that without these User Manual (readme) and the Cookbook there would be maybe 1/10th the number of people using PySimpleGUI. I've heard from numerous people that it was the docs that lured them in.
MikeTheWatchGuy 2018-10-13T00:11:48Z
Floating Toolbars
Two new Demo Program just posted. I posted it in folder because one of them uses PNG images. The both implement a button toolbar.
This one reads the PNG files from disk
And this one has the PNG files embedded into the source code.
You can move them by grabbing the edges. You "gran anywhere" however, so dragging it using a button works fine.
The code to implement these is TINY like the buttons. The one with buttons stored in files is 30 lines.
#!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
import os
BUTTON_PATH = '.'
button_names = ('close', 'cookbook', 'cpu', 'github', 'pysimplegui', 'run', 'storage', 'timer', 'checkmark', 'camera', 'house', 'download')
def ShowMeTheButtons():
button_files = [os.path.join(BUTTON_PATH, b+'.png') for b in button_names]
sg.SetOptions(auto_size_buttons=True, margins=(0,0), button_color=sg.COLOR_SYSTEM_DEFAULT)
toolbar_buttons = [[sg.RButton('{}'.format(button_names[i]), image_size=(32,32), image_filename=f, pad=(0,0), tooltip=button_names[i]) for i, f in enumerate(button_files)],]
layout = [[sg.Frame('', toolbar_buttons,)]]
form = sg.FlexForm('Toolbar',
no_titlebar=True,
grab_anywhere=True,
background_color='grey76',
keep_on_top=True,
).Layout(layout)
# ---===--- Loop taking in user input --- #
while True:
button, value = form.Read()
print(button)
if button == 'close' or button is None:
break # exit button clicked
if __name__ == '__main__':
ShowMeTheButtons()
MikeTheWatchGuy 2018-10-13T17:03:28Z
Warning - parm order changing on Button.Update
When I created Button.Update, I did not lay out the parameters in a decent order. The result is that updating the text on the button required using a named parameter because it was the second parameter. I'm moving it to the most logical place, the first parm. It will remain there. This way you can call Update('Button Text').
However, if you're already relying on the order of the parameters being a certain way, this will mess you up. Please let me know if you are calling button update without any parm names.
MikeTheWatchGuy 2018-10-13T18:40:18Z
New YouTube Videos and Reddit Post
I just posted 2 new tutorial videos and am about to make a 3rd. First assumes ZERO knowledge of GUIs and demonstrates an input field and a button
The second one adds Checkbox, Radio Button, and Slider
The third will cover persistent windows where elements get updated.
The Reddit post is actually doing great!
https://www.reddit.com/r/Python/comments/9nvdmw/tutorial_beginning_as_in_your_first_time_gui/
I finally found something Reddit seems to like 👍
MikeTheWatchGuy 2018-10-13T21:37:51Z
Reddit Redemption!
Damn, my Reddit video post has gone crazy. Who would have known that making a couple of videos would have a big impact.
I just posted a third that teaches you how to keep a window open. They are getting longer and longer... but if you think about how much time would be spent teaching these same concepts in tkinter they're short.
MikeTheWatchGuy 2018-10-14T00:49:13Z
How Do I - PSG Front End Now Available As Package
This is a life-changing tool... I know it changed my programming life and it may yours too. I run this program so often that I have a hot-key setup that launches it. I reference it at least 2 or 3 times a day at minimum.
If someone could try it out, I sure would appreciate it!
You need to be on WINDOWS however. I can't seem to get HowDoI to build on Linux.
I promise the payoff is worth it.
Just type
pip install pysimplegui-howdoi
And that will install it.
You will then want to change to the install folder which will be in the site packages. Once there you'll run the PySimpleGUI-HowDoI.py file that you'll find there.
To get the folder where it installed type this and you'll find it under "location":
pip show pysimplegui-howdoi
MikeTheWatchGuy 2018-10-15T01:25:47Z
EXE Maker !
If you enjoy having EXE versions of your favorite Python programs, but find typing the pyinstaller command into the command prompt too tedious, then I've got a Demo program for you!
Demo_EXE_ Maker.py will make EXE files AND it will do it with an embedded windows icon so that when you see your program in Windows explorer, it will show this icon.
I have not yet figured out how to build an EXE file for this program however. There's something about it that is crashing the program.
If you get an error popup and think it was shown in error, you can easily copy and paste the command line that was being attempted from the output window. Paste it into a command prompt to get the full output so you can troubleshoot it.
I have not yet figured out how to get the scrolling output as the command is being executed working. I will look through the old GitHub Issues as I know someone was nice enough to post it there. I was just never able to get it working before. Now that I have a real use for it where I need scrolling output, that'll give me a bit more incentive to get it working.
This is one of those really handy little programs that demonstrates how nice it is sometimes to have a GUI front-end for a utility.
MikeTheWatchGuy 2018-10-15T02:47:17Z
Distribution breakthrough!
I am slowly figuring out how to use these tools, perhaps in a correct ways at times.
I now know ONE way to distribute these "demo programs" in a way that is pip-installable. Don't worry, I'm not going to dump 80 crummy demo out onto PyPI... but I am going to release the programs that I think are really good and useful.
Two that come to mind are HowDoI and Demo_EXE_Maker.
The howdoi one has been re-released as:
pysimplegui-howdoi
Here's how I'm suggesting it be done. First, you pip install the package that has the program in it. Then, invoke the program directly, without having to locate it in the site-packages folders. This is done using a python -m
command.
For example, to run the howdoi program, pip install it:
pip install pysimplegui-howdoi
Then run it
python -m pysimplegui-howodi.pysimplegui-howdoi
I'm not sure if python "applications" are being distributed this way or if I'm using pip in a rather bastardized way that will be shunned. It won't be the first time for me to do something like that.
Oh well, in the meantime, enjoy the programs.
MikeTheWatchGuy 2018-10-15T18:07:42Z
pysimplegui-exemaker Released
I just released another PSG based application. I used the same mechanism as the howdoi and PySimpleGUI-chess.
To install the EXE Maker:
pip install pysimplegui-exemaker
After install to run:
python -m pysimplegui-exemaker.pysimplegui-exemaker
I'm really getting into this method of releasing programs. I hope I don't run into an ugly snag.
I have not, however, tested this on Linux... I suppose that's next!
These will not work with Python 2.7 however as I require PySimpleGUI not PySimpleGUI27.
Someday I guess I'll have to merge those into a single file. Drat.
Anyway, enjoy!
Oh, this utility will create EXE files from your python script. No need to memorize the PyInstaller command line.
It should be used for simple programs that do not require data to be packaged with them. I'm still working on the data part. It will include an optional windows icon that is shown in windows explorer. It doesn't yet support the icon that's shown when you run the program. You will continue to need to have that .ico file in the folder you run the exe from.
MikeTheWatchGuy 2018-10-15T18:51:43Z
Events, not Buttons
Time for a naming convention change. I should have done this long ago, but hey, sometimes it takes a while as these things evolve. Putting together these YouTube videos are causing me to really think about every aspect of the PSG Framework. I have to be able to explain, in plain English, how these things work.
When we call Read(), what is being returned as Button are actually Events. Of course a button click is an event, but so are keyboard presses, double-clicks on listboxes, keys etc. As the capability of PSG has expanded, so has the role of that parameter. Long ago it changed from being just a button to these other things
You can expect a global update... when these things change, they have to change system-wide.... that means the docs, the cookbook, all of the demos, etc. Going forward they will all read:
If I was at a company, I would assign something like this to an intern. But, I'm afraid I'm the intern.
I can't really get away with a global search and replace because that variable "button" is used many times in every Demo. I'll take any volunteers that feel compelled to jump in and start making changes 👍
MikeTheWatchGuy 2018-10-15T20:14:45Z
Double-plus Good Events
It's done. The readme, cookbook and all 81 Demo programs have been updated to use the new Read format:
These changes, like the change from FlexForm to Window, feel like something out of 1984. All of the old ways of doing things are stamped out, erased, replaced by the new way... as if they never existed.
Help stamp out the old method by informing me if you see it somewhere.
I also added another couple of pages to the readme that discussed events, including this bit about the different values that the event variable can communicate:
For all Windows:
Button click
Window closed using X
For Windows that have specifically enabled these. Please see the appropriate section in this document to learn about how to enable these and what the event return values are.
Keyboard key press
Mouse wheel up/down
Menu item selected
An Element Changed (slider, spinner, etc)
A list item was clicked
Return key was pressed in input element
Look for the upcoming "Master Class" on PySimpleGUI that I'm recording for YouTube. I hope to be able to quickly cover all of the elements, events, and coding conventions in under 10 minutes.
I'm getting a lot of feedback that people like these videos. What I'm not getting feedback on is what they would like to see in new videos.
The concept of 'keys' didn't click for a number of people until they saw the video. While I don't watch programming videos, I guess a lot of other people do.
MikeTheWatchGuy 2018-10-16T00:15:25Z
"Cool Buttons" Demo
Requires the latest PSG from GitHub.
Windows
Linux
Mac
??? Who knows... probably not.
The new demo is called Demo_Nice_Buttons.py and shows how you can create really nice looking buttons without having external files. They are part of the source code itself so you don't have to worry about the images being lost.
I may start using some cool buttons from time to time now that this capability exists. The missing piece was the ability to put text on top of these buttons.
It's getting past time to check in a new PySimpleGUI into PyPI so these demos will function correctly.
Themes and Styles - My Downfall...
If I could only crack the Themes/Styles nut then we could have nice looking Tabs, etc. I'm STILL struggling with tkinter styles and themes. I found 2 new books to help me and maybe this time around I'll figure it out. At the moment, you can't mix tabs and combo boxes on t the same page or it messes up the tab.
MikeTheWatchGuy 2018-10-16T04:58:04Z
More YouTube Videos
I made 3 more [badly produced] YouTube videos. The plan is to go much more in-depth with these.
So far I've only made it thought the pop-ups. Things will likely get more interesting with the next one with will be on the Window and the individual Elements.
I don't know how you guys can stand watching them. Let me know what works and I'll try to do more of that :-)
MikeTheWatchGuy 2018-10-16T14:34:37Z
Slider Tick Intervals
I don't feel like I'm making progress unless a get 1 new feature added every day or two.
Today's addition is labels on sliders. Specified using tick_interval when you create the slider. They look much more scientific with these labels.
They are going out in the release later today. I missed getting PyPI posted yesterday. Too busy making those damned videos.
MikeTheWatchGuy 2018-10-16T15:07:28Z
Resizable Windows
I'm caving to public pressure and turning OFF window resizing. If you want to make your windows resizable, you can set the resizable parameter in your call to Window.
This change means all of the popups are now automatically not resizable. If this is a problem for anyone, please let me know. Given that I've heard multiple requests to turn it off I don't think I'll hear from anyone wanting it enabled.
This feature is a good opportunity to show how I use howodi. I knew there was likely an easy way to disable a window. My first stop for these kinds of questions is my howdoi app. It is a single key press away. I typed in the query and got back the exact answer I needed. I dropped it into the code and was done.
MikeTheWatchGuy 2018-10-16T16:09:11Z
3.9.4 & 1.1.4
Released these changes today:
-
Parameter order change for Button.Update so that new button ext is at front
-
New Graph.DrawArc method
-
Slider tick interval parameter for labeling sliders
-
Menu tearoff now disabled by default
-
Tree Data printing simplified and made prettier
-
Window resizable parameter. Defaults to not resizable
-
Button images can have text over them now
-
BUG fix in listbox double-click. First bug fix in months
-
New Look And Feel capability. List predefined settings using ListOfLookAndFeelValues
I'm going to take a moment and give myself credit.... This listbox bug fix is the first user-submitted bug fix in months... I've fixed bugs that I find, and even those are few. Over these months features have continued to be added at a brisk pace.
Of course writing this post is going to cause countless bugs and problems, but hey, I'll take the moment of victory in exchange.
MikeTheWatchGuy 2018-10-16T22:52:24Z
Move & Alpha Channel - New Windows methods / features
Once again applications drive forward features.
I've been working on a new Desktop Widget that checks emails and shows you a summary in the upper right corner of the screen. In order to get the window to the upper right corner of the screen, AFTER it's been created required a new Window method. I added the Move(x,y)
method that allows you to move windows.
I also created a method to adjust the Alpha Channel. With this you can do really cool fade-in or fade-out or just plain fade of your window. Window.SetAlpha(alpha)
where alpha is between 0 (transparent) and 1
I also continued working on buttons.
I really like the close button on the floating widget. I'm experimenting with embedding the button inside the code. For these little buttons it works great!
If you turn off the title bar and move your buttons in the right places, you can make some layouts that perhaps simulate other environments. If I were to create a minimize window method then it would be possible to create windows that look and behave like a Mac window.... hmmmm.... could be interesting to see.....
MikeTheWatchGuy 2018-10-16T23:37:17Z
I was completely unable to resist the temptation to re-create what I think a Mac window looks like.
I even added a new Windows "Minimize" method, However, tkinter was clever and figured out that I was attempting to minimize a window without a taskbar. Thus there was no way to restore it because without a titlebar there is no icon on the taskbar.
Was still a good exercise as it demonstrates that several different looks can be created using the PSG framework.
MikeTheWatchGuy 2018-10-17T15:24:54Z
Alpha Channel
Changed up the Alpha Channel code so that it's a property. If you're into using method calls only , then you can still use the SetAlpha. But the "better" way is to set the property Window.AlphaChannel to the value you want.
Checked in a Demo showing a "notification" window that fades in, partially. It uses an embedded close button. Seems like something that could be used to make a desk-top notifier for things like email or an RSS feed.
Wasn't difficult for the code to do that fade-in thing:
Be sure an set the alpha to 0 when creating the window or else it'll flash on at full visibility before fading in. Also be sure and Finalize the window prior to making the call.
window = sg.Window('',
no_titlebar=True,
grab_anywhere=True,
keep_on_top=True,
alpha_channel=0
).Layout(layout).Finalize()
MikeTheWatchGuy 2018-10-17T16:25:32Z
Nested [[[[[]]]]]
Gnarly nesting can happen if you attempt to write a layout without using intermediate variables.
Check out this tab definition:
tab_window = [[ sg.TabGroup([[sg.Tab('Parms',[[sg.Text(desc_window, font=('Consolas 12'))]]),
sg.Tab('Methods', [[sg.Column([[sg.Text(desc_window_methods)]], size=(500,500), scrollable=True, )]])]])]]
That actually gets put into a Tab inside of a Tab Group, so it's not the completed layout. I count 9 levels of )'s and ]'s. It's what is needed to make this window from the Demo_PSG_SDK_Quick_Ref:
It was that second tab with the scrollable column that was tricky.
MikeTheWatchGuy 2018-10-17T17:14:06Z
Lesson 4 of The Complete Course uploaded.... Windows & System Settings
Another YouTube disaster uploaded. In this one I go through all of the parameters used in the SetOptions and the Window object.
9 minutes seems like a really long time..... but it's not when you're explaining a ton of parameters. I went as fast as I could.
Next one up I'll explain all of the "normal" elements. That one I may have to split up. The last Element video will be on "Container" elements (frame, column, tab).
Current plan looks like this:
5 - Basic elements (there are 17 of them)
7 - Container elements (there are 4 of them)
6 - Window methods
7 - Persistent Window design & Events
If you have a topic that's not covered, speak up.
MikeTheWatchGuy 2018-10-18T03:27:45Z
Timeouts - a new event
Things just got a little more interesting....
You can now put a timeout on your reads. This is helpful for programs that need to do something periodically. Instead of sleeping between checks you can instead do a Window.Read() with a timeout. The effect is that your GUI remains active and responsive during the time you would otherwise be sleeping.
It also means you don't use non-blocking reads. It's cleaner from a design / architecture standpoint and is more responsive from a user stand-point.
The syntax is:
The timeout value is a tuple. The first entry in the tuple is what event you want returned when there's a timeout. The second entry is the amount of time, in milliseconds,, to wait.
The documentation has not been written on this yet, nor has there been a check-in of the Demo programs and Recipes that use reads with timeouts. Expect them in the next few days. Release to PyPI later in the week.
MikeTheWatchGuy 2018-10-18T06:27:01Z
YouTube -- Lesson 5 Part 1 - PSG The Complete Course - The Text Element and Common Parms
Uploaded another video in the "complete course" series. We're getting into the Elements now, starting with the Text Element. Much of the time is spent talking about the parameters that are common with other elements.
MikeTheWatchGuy 2018-10-18T18:51:03Z
Timeout values split (How can I explain Read timeouts?)
Not that I expect that anyone has used the new timeout capability on Window.Read(), but I split the timeout=(key, timeout), into Window.Read(timeout=xxxx, key=kkkk). Having them as a tuple meant people would have to read the documents in order to get the meaning and the chances of that are very slim.
Documenting this is going to be really tricky. This is an advanced feature that likely requires a background in embedded systems to grasp quickly. If you are polling, this is THE right way to do it. It gives the GUI all of the CPU it wants to do things like move the window, respond to clicks on checkboxes, etc. While also "sleeping" for the user so that the event loop ticks at the right intervals.
I timed how long a Read with a timeout takes and on my desktop machine it's taking 1ms or less. That's pretty low overhead to add to an event loop. I made the resolution of the timeout in milliseconds so that it can be tuned to provide timing of the event loop if needed.
If anyone has ideas on how to document this, I'm listening.
People are already "abusing" the ReadNonBlocking call by using it in situations where it's not needed. When it comes to polling devices, the instinct is to use a ReadNonBlocking with a sleep. That's the most straight-forward looking way to do it.
I suppose the right answer is to address this in an exacting way with headings like "How to run an event loop that polls devices"
I'm posting a couple of examples that show how to do this. The two I've already converted are the CPU/task monitor that polls the running tasks every few seconds. The other is the floating-timer-widget that displays a running timer. Both do a good job of explaining it. Posting them right now....
MikeTheWatchGuy 2018-10-18T20:06:25Z
Lesson 5-Part 2 - PySimpleGUI The Complete Course
I've uploaded another video for those of you that are into learning all the ins and outs... Today's video is about the "in's", as in InputText, keys, return values.
https://youtu.be/Z5G70VE-kok
MikeTheWatchGuy 2018-10-19T02:30:13Z
Email Notifier App (Could use help)
I've created a cool Outlook Email Notifier. I don't want to post it with the demos. It's here for now:
https://gist.github.com/MikeTheWatchGuy/96f5108dbf02a5cc3fdea912fd3cde4a
It utilizes calls into Outlook itself... so that means you have to be running Outlook for it work. I'm using Outlook to access Hotmail and it's working great!
However, I am unable to interrupt the program to kill it. I can't close it by right clicking on the taskbar. Nothing works except my task killer or the task manager. If you plan on running the program all the time, then perhaps it's OK.
As far as it working, it works great! Newest emails are shown at the top.
It's semi-transparent to blend in with my desktop better.
If you've worked with the win32com package and can help out, please take a look at the code. Like all of my programs that use PSG, thee're simple to follow. Doesn't hurt that it's less than 50 lines of code.
MikeTheWatchGuy 2018-10-19T16:11:57Z
First PSA I've seen regarding PySimpleGUI
I'm a bit stunned frankly.
https://www.reddit.com/r/Python/comments/9ph1ru/psa_python_beginners_in_gui_programming_dont/
I don't understand why someone would post something like this when the results have been so encouraging so far.
emallay 2018-10-19T16:32:58Z There are always people who don't like it if everyone else doesn't accept their personal approach to programming. The poster shows his narrow-mindedness in his comment "You can't take shortcuts when programming". Of course you can, and you should! Personally I have no desire to create my GUI in assembly and I'm guessing the poster doesn't either...
I don't see myself using PSG (yet) for a complex, commercial GUI but it is an amazing tool for what it does.
Don't fret the haters.
MikeTheWatchGuy 2018-10-19T17:17:52Z Thank you... much appreciated.
I certainly do not suggest PSG be used for complex, commercial GUI. I've openly stated that. I can be honest about what it does and doesn't do.
I'm trying not to take it personally... wear the attack as a badge of honor, but dang, I'm a human being like everyone else and this was taken to an extreme. It's weird. Just plain weird.
MikeTheWatchGuy 2018-10-19T17:26:31Z
On-Screen Keyboard (So cool!)
@jackyOO7 has submitted a really cool Demo program that implements an on-screen keyboard. This is perfect for Raspberry Pi users with a touchscreen.
Wow... I never thought about doing some so complex looking... and yet the code is really elegant with great use of list comprehensions. I'll be lifting sections of this code.
He/She? also submitted changes to make Comboboxes read-only, meaning you can't change the entries by typing them in. This will be a new option when you create the element. I'm going to enable it by default as I think the expected behavior for drop-downs is that you cannot change them.
MikeTheWatchGuy 2018-10-19T17:36:43Z
Submitting Pulls / Changes
I've never stated a policy or process or anything else when it comes to pull requests. Pull requests for new Demo applications or changes to demo applications are fine to make. If they seem like a good fit, I'll accept the merge.
Suggested changes to the core PySimpleGUI file I won't be merging using the Pull tools. If you have changes to make, you're free to make them and submit them to be used. I just won't be using the Pull/Merge process or tools to make the changes. I will hand edit your changes into the code.
I'm not thankful for the changes you may make, the time you commit to making them. I am grateful to anyone spending time to make this a better package. I'll certainly add your name to the list of contributors to the project as well in the readme. You deserve credit and to be acknowledged in a public way.
If you do have a change to the core code, please submit a small test harness that will test this feature. It will improve the chances that the change will be incorporated.
I apologize if how I'm structuring things is not in the spirit of Open Source. I'm just old fashioned I suppose and am the current owner and maintainer of the code. Hand merging the changes, where I type in the code, is the only way I know for me, personally, to absorb and accept the change. I don't mean to discourage participation.
There have been a couple of people suggest core changes that were accepted using this weird process of mine and I hope there are more. If you have suggestions on how to improve this process, you're free and encouraged to make them. I'm into having fun with this stuff and into participation so please do join the party.
MikeTheWatchGuy 2018-10-19T18:41:35Z
How Do I Answer of the Day
It's really fun to be able to ask a question and immediately get back the answer I need. I dunno, something oddly satisfying about being about to ask an oracle of sorts.
I'm posting these in hopes that I can help others craft the right kind of requests to send. It's taken me a while to be able to come up with the right search string, but I think I've gotten it down.
Today... I need to convert a string that's in hex to an integer. I've done it before, but heck, I can't memorize everything. So, out comes How Do I to the immediate rescue....
MikeTheWatchGuy 2018-10-19T18:58:44Z
Table Selections
Yippee! Table Element inches towards being fully complete.
When you get back the values from Read, the Table Element will now return a list of selected elements, starting with 0. If the first and fifth elements are elected, then the list returned from Read will be[0, 4]. It's up to you to determine what that exactly means.
Keep the suggestions coming. I want to get this Table Element complete at some point.
I know sizing is a problem. The window doesn't automatically size and with the new sizing parameter in the Widow call being set to no-resize, you'll have even more issues with sizing. If you want to resize a column smaller, that does work, but you'll have to turn off the no-resize option in your Window call.
MikeTheWatchGuy 2018-10-20T03:13:29Z
Going to 4.0
The version numbers are at 3.9.4 and 1.1.4
I'm going to bump the Python 3 version by a full number to 4.0.0.
Here's why. While I can use 2 digits in any one of the versioning spaces, the reality is that you can't actually use them. If I were to bump to 3.10, there WILL be people confused thinking the version is 3.1. It's happened in the past, several times.
The other reason is the timeouts on the Read calls. This is a bigger feature than a 0.0.1 bump.
Maybe this project suffers from Versioning inflation.. if it does and it bothers you then heck, say something. I would much rather hear someone complain openly, or privately, than stew over it. Email me at [email protected] if you ever have any comments to share.
And with that, the 4.0 bus is leaving soon...
-
Read Timeouts
-
Table rows selected returned in read (YES!)
-
combox read only
-
Alpha channel for windows
-
icon can be base64 image
-
FindElementWithFocus
-
Move and minimize windows
Those are enough for a .1 so it's up to 4.0 we go... I don't tend to make a big deal about what version number we're on. I don't ever recall posting "New Version 3.0!" in any of the marketing type posts I've made (the videos on how to use the package, etc).
MikeTheWatchGuy 2018-10-20T12:32:36Z
3.10.1 & 1.2.1
I've thought about this overnight, and a user was kind enough to point me to some versioning guidelines. I didn't like the idea of rolling over to a major number just because I've run out of minor numbers.
I think a remedy to the confusion between 3.10 and 3.1 is going to be to always include the 3rd digit. I would prefer that third digit be non-zero to be overly sure the message gets across that there are 3 digits in use.
So, we're moving on to 3.10.1 for this next release today.
MikeTheWatchGuy 2018-10-20T12:55:23Z
New Demo - Menus with Toolbar and Status Bar
I think this is the closest I've gotten to writing a program that looks similar to a traditional Windows program.
It uses a new capability for buttons to accept Base64 images which allows me to store the toolbar in the python source file itself.
It possible to tie the toolbar actions directly to the menu actions by setting the toolbar button key equal to the menu item. This will cause the Read to return the exact same event
.
MikeTheWatchGuy 2018-10-20T15:19:06Z
New Demo - Email notification widget
This is one I've been wanting to do for a long time and all of the pieces finally came together to make it happen. This newest release contained several of them including:
-
Move window
-
Set Alpha Channel
-
Read with timeout
-
Button in Base64 format (this one may have already worked, not sure)
This is a great example of when to use a Read with Timeout. Basically any time you've got a program that periodically reads or write something, then it's a prime candidate for Read With Timeout. If your design includes a sleep inside of the event loop, then you should change it to Read with Timeout.
The advantage to using Read with timeout is that the GUI remains 100% responsive during this waiting period. If you used a sleep, the window would appear to be locked up.
Now that I've written a few programs using it, it's difficult to believe I've made it this far without seriously needing it. I think it's another case of developing a feature "just in time". Today I saw the first robotics project using PySimpleGUI.
I'll go post to PyPI the releases now since there are Demos that depend on those changes in order to work. I'm not a fan of Demos that don't work or requiring that PSG be downloaded from GitHub.
Just tested this one on Linux... it's often a coin-toss as to whether it would work... and this one did! It's working from the pip install in fact so that PyPI uploaded seems to have worked too.
MikeTheWatchGuy 2018-10-20T16:07:34Z
3.10.1 & 1.2.1
The docs are done, the files uploaded, it's official... we've got a release.. Here are the contents:
-
Combobox new readonly parameter in init and Update
-
Better default sizes for Slider
-
Read of Tables now returns which rows are selected (big damned deal feature)
-
PARTIAL support of Table.Update with new values (use at your own peril)
-
Alpha channel setting for Windows
-
Timeout setting for Window.Read (big damned deal feature)
-
Icon can be base64 image now in SetIcon call
-
Window.FindElementWithFocus call
-
Window.Move allows moving window anywhere on screen
-
Window.Minimize will minimize to taskbar
-
Button background color can be set to system default (i.e. not changed)
MikeTheWatchGuy 2018-10-20T21:46:17Z
Emergency patch later
I seemed to have not quite coded up the Read with Timeout correctly... I caught it today, of course hours after I did my PyPI release. I'll post tonight.
MikeTheWatchGuy 2018-10-20T21:50:31Z
New Demo - LCD Clock and Weather for Raspberry Pi
I've seen some projects being discussed among Raspberry Pi owners of making a weather station, clock, etc out of their Pi.
I thought coding up a Cookbook Recipe would be helpful.
I took 2 shots, one with a real camera because I thought it was important to see it on the real screen.
The ':' even blinks, as it should, right?
I clearly don't have the entire user interface fleshed out. It's meant to be a skeleton, not a complete solution. It's a starting point.
Like the toolbar programs I've been writing lately, this program does not rely on any external files. All of the graphic images are inside the program file.
I wasn't very efficient with my code writing I'm afraid, so the GUI is a bit long at 60 lines of code. The other 40 lines are all the graphic assets.
For 100 lines of Python code, it's pretty good.
MikeTheWatchGuy 2018-10-21T02:54:44Z
Video Lesson 5 Part 3 Posted on YouTube
https://youtu.be/R40-liiiIRI
Another lesson posted. Covers checkboxes, radio button, and sliders, the last of the "simple" input elements.
Next up are the "list" oriented elements (listbox, combo, etc)
MikeTheWatchGuy 2018-10-21T03:31:31Z
Made it onto the Vinta Awesome-Python page!
Whew! Finally made it onto the page:
https://github.com/vinta/awesome-python
The voting was at 30, well over the 20 mark as required. Thank you to everyone that voted!
MikeTheWatchGuy 2018-10-21T16:26:55Z
Another school picks up PySimpleGUI
This time it's a school in France (I think in France as the page is in French)
PySimpleGUI is on the homepage, not buried somewhere...
https://www.eduba.school/
MikeTheWatchGuy 2018-10-22T14:03:00Z
Note to the forkers.... reformatted PySimpleGUI.py
If you forked the project, then you're likely to see a ton of recent changes between your version of PySimpleGUI.py and the latest version. That is because I ran PyCharm's reformatter on the file. It was looking a bit ragged. It appears the changes had no side effect. I assume it's a feature that's been thoroughly tested long before this project.
MikeTheWatchGuy 2018-10-22T14:08:26Z
VerticalSeparator - New Element
Time for another Element, although this one has quite limited usefulness. What it does, however, is finish up all of the tkinter widgets. I think I can state that all of the tkinter supplied widgets are represented, in some fashion.
I wish I could have supported horizontal too, but the way the PSG Auto-Packer works prevents it from working correctly. To make matters slightly worse, you'll only get a vertical separator that spans a single row. It works great when you've got a column, however. With a column it appears as if it is spanning multiple rows.
MikeTheWatchGuy 2018-10-22T14:48:46Z
Deprecation of Window.ReadNonBlocking
Heads-up... down the road...not now, don't panic.... ReadNonBlocking is going away.
I'll be modifying the Cookbook, Demos, and all other documents to remove this method call.
It is being replaced by the new, preferred call:
window.Read(timeout=0)
Setting the timeout to 0 in fact calls the ReadNonBlocking as it is today. You'll get back the exact same event information. I'm trying to determine if that should change.... that the timeout key should be returned rather than None. That change would hit quite a bit of code however and so I'm hesitating on doing that. For now, just know the two are the same.
This will consolidate things nicely so that Windows have a single Read call... a simplification 👍
It will also shift the thinking of the user into not using a non-blocking read willy-nilly. I want people to think about this decision long and hard as it has implications on the entire system, not just their program.
A read with a fast timeout of 10ms takes a fraction of 1% of the CPU where a timeout of 0ms takes 100%.
The change has been checked into Master Branch and will get released on PyPI soon.. if you want to released sooner than later just speak up. I'll be changing the docs, etc. It needs to be in PyPI prior to those check-ins.
MikeTheWatchGuy 2018-10-22T16:19:35Z
Weather and Clock Program for Raspberry Pi (or Windows)
I've seen a number of people post on Reddit and elsewhere, saying they are going to build an app for their Raspberry Pi that includes a weather forecast. That's a perfect kind of app for PySimpleGUI! Right?
So, I built one to see what was possible, how difficult it was, and to provide a template that other people can use to get a jump-start on their project. I'm on a kick to include graphics inside of the applications and this one was right in line with that trend.
The most difficult part for me was getting the weather data. I looked at a number of packages before finding one that still worked. The package you'll need to install is python-forecastio
. You'll need to sign up for a free key from the nice folks at DarkSky.
It uses the new Read with Timeout call... how did we ever get along without it?? It's used to 'sleep' the GUI in between the blinks of the LED : . If it wasn't for that blink, the timeout could be set to several hours, the frequency you want to check the weather. It takes very little CPU time and it shows the application is still working.
Maybe this will give someone enough of a jump-start to actually do their project. It can't hurt to add one more Demo Application to the GitHub.... we're up to 99 as of today.
MikeTheWatchGuy 2018-10-22T22:22:06Z
More OpenCV Fun
@jackyOO7 strikes again with another excellent Demo App... this time it's an OpenCV demonstration. It's pretty amazing actually.
It shows you a video image, in realtime, and lets you use different image processing functions.
I'm so blown away by the processing power of computers now. Reading individual frames from a web camera and doing image processing on them doesn't make a dent in my processor.
MikeTheWatchGuy 2018-10-23T01:07:00Z
Inching towards no more NonBlockingRead
I realized now that I'm likely to break the API soon... maybe that 4.0 release is coming sooner than I thought.
There are some things about the calls ReadNonBlocking and CloseNonBlocking that bug me. I don't like that there are 2 different reads and it's always bugged me that the event return value is "None" normally for non-blocking windows and means the window was closed for normal windows. The 2 values have been swapped for some time and it's bugged me the whole time.
If you were to switch your code from Read to ReadNonBlocking currently, you would have to change your test for the window being closed or your program would exit immediately.
I also realized that if you want to close a persistent window right now, you call CloseNonBlocking. It feels like a hack... maybe because it is?
I just checked in changes that I think will fix all our mixed up issues.... and I'm tempted to thrust those changes onto the world at some point after fair warning.
The NEW way of doing things is that if you want your reads to be non-blocking, set the timeout value to 0 in your Read call. This will cause "timeout" events to be constantly returned if there is nothing else happening, like a button click. If the window is closed, the event will be None, instead of timeout. This puts both types of reads in sync... it means ALL reads will return None as the event if the window is closed.
Additionally, there is a NEW Window method... Close. It will close the window regardless of what "type" of window it is... blocking or non-blocking.
The result of all these changes is a super-simplification. There is no more 2 types of windows... there is just 1 and that one window behaves the same way when it comes to closing events.
I would like to remove the non-blocking calls at some point, but could use feedback on all this first. I don't want to just spring this on everyone while their code breaks.
All you really have to remember is:
Use Read with timeout=0 if you want non-blocking
Event == None if the user closes the window with the X key
Call Window.Close() to close a window that is open
MikeTheWatchGuy 2018-10-23T17:28:22Z
3.10.3 & 1.2.3
Had a bit of a scare with a bad setting sneaking into the last PyPI release. I was working on resizable windows and forgot to change one of the settings (expand) to false. The result was that some windows look stretched. The elements will not be tightly packed together, if there is room for them to expand into.
It's actually a good time to pop a release out as I got my non-blocking windows calls in there that I've been wanting. Now I can make the changes to the Demo programs and they'll work.
The changes in this release include:
-
New element - Vertical Separator
-
New parameter for InputText - change_submits. If True will cause Read to return when a button fills in the InputText element
-
Read with timeout = 0 is same as read non blocking and is the new preferred method
-
Will return event == None if window closed
-
New Close method will close all window types
-
Scrollbars for Tables automatically added (no need for a Column Element)
-
Table Update method complete
-
Turned off expand when packing row frame... was accidentally turned on (primary reason for this release)
-
Try added to Image Update so won't crash if bad image passed in
MikeTheWatchGuy 2018-10-23T18:36:18Z
Play Chess Against An AI Opponent
Watch me quickly lose a rook...
I finally hooked up a chess playing AI to the chess GUI that was previously released.
You will need to download the EXE file that contains the AI code from here:
https://stockfishchess.org/download/
Then run the program Demo_Chess_AGAINST_AI.py that is part of the Chess folder on GitHub
It will ask you for the location of the EXE file and then you'll be up and running. To play, click on a piece you want to move, it will turn red, and then choose where you want to place it. To cancel the move, click on the original location or on any illegal location.
You can change the difficulty by setting the "Level" located on the right side of the GUI.
I have not yet released this as a package. Wanting to see if others can play it off the GitHub first.
MikeTheWatchGuy 2018-10-23T20:19:08Z
Mentioned in PyCoder's Weekly Newsletter
Hey, we made it into another newsletter... PyCoder's Weekly is one I like and read. PySimpleGUI is at the top of the Projects & Code section this week.
If you don't yet get this one, check them out - https://www.pycoders.com/
MikeTheWatchGuy 2018-10-24T02:04:38Z
Assault on ReadNonBlocking Continues....
I think I have finally put the final nail in the coffin for ReadNonBlocking.
I just checked into Master Branch the change that removes the requirement that ReadNonBlocking be used for RealtimeButtons. Now it works the way it always should have. If the button is pressed, Read will immediately return the button for as long as the button is held down. When the button is let go, the Read will once again block.
Normal buttons will of course return only a single Read call the entire time it's being held.
You can also use RealtimeButtons with Read with Timeout.
MikeTheWatchGuy 2018-10-24T14:36:33Z
Another Educational Use
PySimpleGUI has popped up in another course. This time it's in a Geography lecture at Binghamton University, State University of New York.
https://github.com/giswqs/GEOG-503/blob/8eeb9260bb6d8160b4075fc36fe564841fc950fe/Lectures/GEOG-503_Lecture_W10%20-%20Python%20GUI.ipynb
I'm a bit surprised that PySimpleGUI is being offered as the only GUI package being taught, but I guess for this kind of course, you don't need more than 1 GUI package. Whichever package gets the job done would be considered a winner and it seems that PSG is a winner this time.
MikeTheWatchGuy 2018-10-24T14:47:13Z
FTDI Chips Using PySimpleGUI To Test Devices
This appears to be a company using PySimpleGUI as a front-end to interfacing to their USB to UART chips. Nice to see some commercial uses mixed in with academia and personal projects.
https://github.com/fs000x/ft260UI
MikeTheWatchGuy 2018-10-24T21:09:50Z
Google Text To Speech Front End
I stole this idea from another repository... I'll admit that.... but I'm giving back by providing an answer to a problem everyone seems to have that wants to create more than 1 phrase of speech.
The new demo is called Demo_Google_TTS.py and is located here.
Converting a block of text to speech could be done using a command line, I suppose, but you have to worry about "s being in the text It's a trivial little interface, but it fits the problem perfectly..
The one thing I'm giving back to the internet is my stack overflow answer to the multi-query problem.
https://stackoverflow.com/questions/51741201/gtts-unable-to-save-file-twice/52977492#52977492
Of course feel free to up-vote if you happen to like the answer.
The natural thing to want to do with this program is to add a loop to the query. Asking for multiple lines of text to read back is only natural. However, it presents a problem. The code works the first time through the loop, but crashes with a permission problem the 2nd time through. You cannot overwrite the file you were just playing from.
The solution... double-buffering. Write to one buffer, playback from it, then switch to another buffer for the next time, then back to the first. It requires two files, but having 2 files is a whole lot better than not having a working program, right?
I like these kinds of GUIs because they are so simple yet provide a whole fantastic user experience. Compare typing your words, or pasting your words to be spoken into GUI versus doing the same on a command line. It's difficult to argue in favor of a command line interface
MikeTheWatchGuy 2018-10-26T05:18:32Z
YouTube Lesson # 6 - Menus
Uploaded a brief video on Menus.
https://youtu.be/8KxeB6vp2zU
Still have more "parts" to do for lesson 5 which is a detailed look at every Element.
The next one I'm working up is on Persistent windows, sure to be a popular video considering the questions I've been getting lately about how to work with persistent windows.
MikeTheWatchGuy 2018-10-26T15:54:29Z
Tree Element - new features secret
This morning I jammed out a couple of new features for the Tree Element.
-
Returned values indicate which keys are selected
-
When creating Tree, can indicate the tree should be shown expanded
One of the secret weapons in my ability to quickly add features is..... howdoi.
Here is how difficult it was for me to add the "show expanded feature"
I asked howdoi how to do it... I got back the line of code I needed. I couldn't use it directly, but it gave me the hint I needed and I used that hint to create the feature in less than 5 minutes. This happens a LOT. More than I want to admit. It's why I'm pushy about howdoi. The results can be amazing.
MikeTheWatchGuy 2018-10-26T22:39:08Z
Mac loses another feature - Filetype list on File Browse buttons
A user reported a crash while trying to use a File Browse button. tkinter crashes, complaining of an empty file descriptor list. However, the list I sent wasn't empty. It seems other people are having the exact same issue. It's WEIRD to have this big of a problem. All of the file dialogs broken?
For the time being, I'm turning off the ability to filter files on Mac. If a Mac user wants this feature back, they can research this problem and find the solution. I don't have the ability to test on Macs or I certainly would try to find it.
Here is the issue for background:
https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/562
MikeTheWatchGuy 2018-10-26T22:54:16Z
Multi-window support and more added to Master Branch (risky change so please help me test by running GitHub Master Branch code.
Normally I integrate changes into Master often, almost daily, without making an announcement.
This time the changes will hit everyone's code so I want to send a head-up just in case there's a problem. Let me know if something breaks, please!
The biggest change was to the Window.Read method. You can run multiple windows now. Also, if you are using non-blocking reads, you should change them to Read(timeout=0). This will normalize the return values so that a closed window will always come back as event == None
. Previously the values
was None if a window was closed on a NonBlockingRead
call.
I'll write up a bunch of stuff for the Readme on these new changes, including the new design patterns that are recommended.
We're getting into territory that PySimpleGUI was never designed to go into... but hey, if it works, why not? It was users that helped me figure out it'll work, so thanks to everyone that's been stretching the boundaries.
john144 2018-10-26T22:59:12Z I just tried it. I saw Window 1 and Window 2, but Window 3 showed up somewhere off screen. I ran a WinSpy tool, and it's X and Y were something like -32000.
On Fri, Oct 26, 2018 at 5:54 PM MikeTheWatchGuy notifications@github.com wrote:
Multi-window support and more added to Master Branch (risky change so please help me test by running GitHub Master Branch code.
Normally I integrate changes into Master often, almost daily, without making an announcement.
This time the changes will hit everyone's code so I want to send a head-up just in case there's a problem. Let me know if something breaks, please!
The biggest change was to the Window.Read method. You can run multiple windows now. Also, if you are using non-blocking reads, you should change them to Read(timeout=0). This will normalize the return values so that a closed window will always come back as event == None. Previously the values was None if a window was closed on a NonBlockingRead call.
I'll write up a bunch of stuff for the Readme on these new changes, including the new design patterns that are recommended.
We're getting into territory that PySimpleGUI was never designed to go into... but hey, if it works, why not? It was users that helped me figure out it'll work, so thanks to everyone that's been stretching the boundaries.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142#issuecomment-433564061, or mute the thread https://github.com/notifications/unsubscribe-auth/AGKiYjZWSbthVkYP2cKfAWPHw2LqL04Cks5uo5KZgaJpZM4WdqH- .
MikeTheWatchGuy 2018-10-26T23:01:18Z
I just tried it.
What's it?
john144 2018-10-26T23:10:48Z I hope you can see the attachments. One shot shows the windows as originally displayed. Then I adjusted the Y-coordinate of Window 3, and then I could see it.
On Fri, Oct 26, 2018 at 6:01 PM MikeTheWatchGuy notifications@github.com wrote:
I just tried it.
What's it?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142#issuecomment-433565090, or mute the thread https://github.com/notifications/unsubscribe-auth/AGKiYh2SbiqJbfyFpafn9D5nYjLLnk3uks5uo5Q-gaJpZM4WdqH- .
MikeTheWatchGuy 2018-10-26T23:16:20Z Demo program... now I got it. The coordinates were potentially high if your display resolution is low.
BTW, thanks @john144 for giving it a try!
MikeTheWatchGuy 2018-10-27T04:27:09Z
New Desktop Widget.... psutil Dashboard
Demo_Desktop_Widget_psutil_Dashboard.py
I've set out to slowly replace the Rainmeter widgets. I didn't think this was a project I was going to do, I just seem to have ended up doing it. I write them to get an idea of what it's like to use the different Elements and Window methods as well as for the fun of it. Something really enjoyable about writing these GUIs where you can immediately get feedback on the screen.
What I like about these graphs is that they're super simple to make using Graph Elements. This is because when you create the Graph Element, you set your own coordinate system. So, if I'm working with graphing percentages, then it makes sense that the graphs go from 0 to 100. To make an area chart I simply draw a line at each datapoint up to the value being graphed. If my data point is 28%, then I draw a line from 0 to 28. It's just that simple.
While the real estate is compact, there is a bit of code required as there are 6 different data sets being collected and graphed.
Like the Email checker widget, I made this one have an alpha channel so that it's dimmed and I also used the same graphic Red-X as a close button.
I just completed it, so I'm not quite sure how accurate it is. I think the graphs are hooked up to the right stats.
MikeTheWatchGuy 2018-10-27T22:29:48Z
PySimpleGUI On Android!
Yes, believe it or not PySimpleGUI will run on Android now!
Use this program, Pydroid 3
https://play.google.com/store/apps/details?id=ru.iiec.pydroid3&rdid=ru.iiec.pydroid3
You will have to insert an import at the top of your code:
import tkinter
And for some reason using a Slider Element caused it to exit the program entirely with no errors or other info (weird).
I was able to run the dashboard that I just created that uses the pip installed psutil! I supports pip installs too. That's how I loaded both PySimpleGUI and psutil.
I find this absolutely shocking. I'm amazed that PySimpleGUI runs and I'm even more amazed that psutil runs. I guess it was only a matter of time before someone ported over tkinter. It even support Qt. Sorry I don't yet have PySimpleGUI-Qt running yet.
It's only an IDE so you can't make an "application" that runs standalone.... yet. That too seems like it's only a matter of time, right?
MikeTheWatchGuy 2018-10-28T00:50:24Z
Shortcut Buttons No Longer Closes Window!
I saw another post tonight of someone not understanding why their OK button closed the window. That's it... it's time to fix this thing.
Thinking it through, it no longer makes sense for these buttons to close the window. The behavior goes back to when PSG was a Forms GUI only. There it made sense that the buttons closed the window. Back then ALL buttons closed the window.
This change needs to get out into the hands of new people trying the package out. That means I'm wanting to release it right away... however, the "risky" Read code is in there. Then again, the only way to get something really tested seems to be to let it lose on PyPI.
I think I'm just going to have to have faith in my code and go ahead and release both to PyPI tomorrow. What the heck, I'm only changing code that deals with every Read call and most likely buttons on everyone's windows.
When I tested this change on several programs, it didn't matter that the window remained open. The program exited and closed the window. The side effect seems to be small.
It's REALLY tempting to change the definition of Button to be a ReadButton, and create a new QButton to replace it (QuitButton). I'll open an issue to see what the thoughts are.
MikeTheWatchGuy 2018-10-28T04:50:10Z
More fun with Desktop Widgets
Demo_Desktop_Widget_CPU_Dashboard.py
I've been really getting into these desktop widgets. It's like I can now make my own Rainmeter widgets, easily! I've always wanted to do that but didn't have the chops to do it using Rainmeter. I needed something much easier, more simple... like PSG.
This time it's a view of all of the CPU's cores. I have a core i9 processor, so windows is reporting a whopping 20 cores are available. Damn, that's a spicy meatball.
By the way, this is what happens when you use ReadNonBlocking, or Read(timeout=0). Check out Core 14. It would be solid at 100% all the way across if windows would let it.
And this is how it looks if you set a timeout of 400 ms. The CPU time does spike while the code is running and updating the graphs, but the time between goes to 0 near 0 in between. Be nice, don't use ReadNonBlocking. OK, I'll stop my assault soon on ReadNonBlocking. I'm tempted to completely do away with the thing. Hmmmm.... I DO provide a call that does the same thing... maybe it's getting close to time to remove it.
MikeTheWatchGuy 2018-10-28T05:47:51Z
3.11.0 & 1.11.0
Pushing one of the riskier releases out the door, on time. I really WANTED to change Button completely over to being the same as RButton. I've already added the code for a CButton, CloseButton.
Anyway, next time. There are enough things in this release already that can go bad. Don't need to add one more risk.
There's what you'll enjoy this time around...
-
Syncing up the second digit of the releases so that they stay in sync better. the 2.7 release is built literally from the 3.x code so they really are the same
-
Reworked Read call... significantly.
-
Realtime buttons work with timeouts or blocking read
-
Removed default value parm on Buttons and Button Updates
-
New Tree Element parm show_expanded. Causes Tree to be shown as fully expanded
-
Tree Element now returns which rows are selected when Read
-
New Window method BringToFront
-
Shortcut buttons no longer close windows!
-
Added CloseButton, CButton that closes the windows
MikeTheWatchGuy 2018-10-28T16:46:51Z
Button no longer closes the Window
Having slept on the decision, I'm moving forward with making the standard button no longer closes the window. I'll let this change run on my machine for few days and then push it out.
The reason for this is that the majority of the programs I'm writing and that I see questions posted on are persistent windows. More and more PySimpleGUI is being used to create 'traditional' windows. This is actually an exciting development.
LOTS OF documentation and code has to be changed so that the design pattern is followed. I've just made a sh*t-ton of work for myself.
Why this is a safe change.... I believe that 99% or 100% of the applications running at the moment will drop off the end of the program after a close button is clicked. If not, people are going to notice it right away and will come to the site to protest, but I doubt this is going to happen.
There is a NEW BUTTON in town... the CButton
or CloseButton
will close the window. It acts like the 'old' Button.
You will no longer need to specify ReadButton
or RButton
in your code once you switch to the new release. You can still use these calls of course. Just know they are the same as Button
.
You may want to add window.Close()
calls to the end of your programs if you don't want to change your Button calls to CButton. Or not... it's up to you as there are no problems that I see from simply exiting the program and letting Python do the cleanup for you.
MikeTheWatchGuy 2018-10-28T19:22:35Z
Reddit... she's a fickle one
https://www.reddit.com/r/Python/comments/9s0h3w/rainmeter_style_desktop_widget_in_python_graph_of/
Can't keep me down for long... so it's been back to Reddit as a way to introduce PySimpleGUI to potential users. Almost every day someone is asking a Python GUI question where they are looking for a package.
The last few Rainmeter style desktop widgets had fallen flat on Reddit. Not a lot of interest. Last night I tossed another up where, the CPU core dashboard. I'm convinced the right title and search terms a key to being found. I posted it last night.
I was shocked this morning when is was upvoted 164 times, viewed 10.8K times and 95% upvoted. Great response!
I keep thinking people have to be tired of seeing this SDK, that all Python readers have seen it, but doesn't seem to be the case from the comments that get posted. The comments read like it's the first time they've heard about PySimpleGUI.
MikeTheWatchGuy 2018-10-29T00:17:23Z
3.12.0 & 1.12.0
OK, it's DONE! Button no longer closes windows. And, all of the shortcut buttons no longer close windows.
If you want your button to close the window you'll need to make it a CButton
or CloseButton
You can also call window.Close()
to close the window instead of having the button do it.
I decided to go ahead and release this today. There was a HUGE surge in the number of installs over the weeks... they tripled overnight. Given that large number of installs, if the previous release broke something, people would have surely complained.
So, I assumed the previous release from today was fine and went ahead and let this one go.
I have also updated ALL of the Demo programs and ALL of the docs. It's been a busy, not very fun day as a result.
The Cookbook needs reworking. I did some work on getting solid Persistent Window Design Patterns defined up front. Before they were much much later in the document because they were a new feature.
It seems like the way PySimpleGUI is being used has completely flipped. At first, it was a one-shot, forms like window with a few people pushing the envelope by creating windows that stayed open. Over the past couple of months the number of people using one-shot windows has dwindled and the number of people using persistent windows surged.
So, it only seemed natural to make the default Button
be a button that reads the windows contents without closing the window.
This change was likely not very risky in the grand scheme of things because the one-shot programs tended to exit right after the window was read so that it's not a problem that the window remained open after the Read.
PLEASE open an Issue if you have any trouble with the new release!
MikeTheWatchGuy 2018-10-29T20:47:49Z
All Demos Updated to Use NEW Button Definition
PLEASE be sure and update to 3.12 or later when using the Demo code!
I went through all 100 of the demos and changed RButton / ReadButton to Button
This means if you run these Demos using older code, these buttons will CLOSE the Window.
It was a decision I had to make of whether I support the old releases in the Demos, or present the best possible design patterns using the new code. I went with best possible design patterns. I want to see people not using ReadButton anymore so the way to do that is to eradicate them from the Cookbook, Readme/User Manual, and Demo programs.
Sorry for the confusion this is going to cause, but it's better than the previous confusion.
MikeTheWatchGuy 2018-10-30T02:44:12Z
3.13.0 & 2.13.0
Jammed out another release tonight.
Despite it being an emergency release of sorts and there was a release just last night, it's still got a lot of good features....
-
Improved multiple window handling of Popups when the X is used to close
-
Change submits added for:
-
Multiline
-
Input Text
-
Table
-
Tree
-
Option to close calendar chooser when date selected
-
Update for Tree Element
-
Scroll bars for Trees
The biggest one is that multiple windows is finally working the way I wanted it to work.
There are a couple of other things that I still want to do with it that, but for now it should get us quite a ways. The big fix tonight was Popups not closing correctly. Now you can have windows that launch Popups and they work fine.
Sorry for the large number of releases over the past few days. Trying to get through some big changes that it's been a little bumpy is all.
MikeTheWatchGuy 2018-10-30T16:25:49Z
Copy Button Added to SDK Quick Reference App
Some people don't use PyCharm (weird, right?) and don't use an editor that gives you the function parameters. These folks rely on the docs or on the SDK Quick Reference application.
I added a Copy button to the application. It will copy what you see onto the clip board, ready to paste into your code. That generally means all of the parameters to a call. You would rarely need all those parms, so you may spend more time deleting than you do adding.
MikeTheWatchGuy 2018-10-30T17:28:54Z
New "Design Pattern" Demo Program
I've been getting a good number of new-comer type requests from people looking for a persistent window GUI that takes input and updates the window with an output.
I didn't have a simple version of a program that did this. The prior examples had more complex things it was doing, like browsing fonts.
This may be a new "short-cut" pattern for me. The program is called
Demo_Design_Pattern_Persistent_Window.py
Here's the code:
# -------------------------------------#
# DESIGN PATTERN 2 - Persistent Window #
# Update a text field based on input #
# -------------------------------------#
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
layout = [[sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_') ],
[sg.Input(key='_IN_')],
[sg.Button('Show'), sg.Button('Exit')]]
window = sg.Window('Window Title').Layout(layout)
while True: # Event Loop
event, values = window.Read()
if event is None or event == 'Exit':
break
if event == 'Show':
# change the "output" element to be the value of "input" element
window.FindElement('_OUTPUT_').Update(values['_IN_'])
MikeTheWatchGuy 2018-10-30T18:43:23Z
2,000 installs yesterday
New record number of pip installs yesterday. I can't explain it. Huge spike over the past 3 days. I cannot tell if traffic comes from Reddit, Facebook a newsletter, etc. If you see something in a newsletter, drop a post. PySimpleGUI was in PythonBytes last week.
MikeTheWatchGuy 2018-10-30T19:43:46Z
Mention in PyCoder's Weekly
https://www.pycoders.com
Another mention in a newsletter, but it was in a roundabout way.... In the "Discussions" section I spotted this:
Discussions
Plot Your CPU Usage With Python Desktop Widget
Renders an animated graph of your entire system by watching the utilization of each of your CPU cores. Built with PySimpleGUI.
REDDIT.COM
I clicked the link prior to making it down to PySimpleGUI... I wanted to learn how the heck someone did something like I just posted about. I was led to a popular post I made on Reddit. It does read sorta like an article so I can see where it made for interesting reading. I've no doubt there will be a spike in traffic from this one even though the post is a few days old.
I'm starting to believe this post I made that shows a Rainmeter-style widget is that increased the traffic over the past few days. It DOES look pretty cool and now anyone can make little widgets that look like Rainmeter, without learning all that pesky Rainmeter code.
MikeTheWatchGuy 2018-10-30T23:47:55Z
Latest design patterns updated in Cookbook and Readme
FYI... for newcomers, these are the "Design Patterns" I suggest they follow as a starting point. Here is how they are presented in the Cookbook.
Pattern 1 - "One-shot Window" - Read int list (The Most Common Pattern)
This will be the most common pattern you'll follow if you are not using an "event loop" (not reading the window multiple times). The window is read and closes.
Because no "keys" were specified in the window layout, the return values will be a list of values. If a key is present, then the values are a dictionary. See the main readme document or further down in this document for more on these 2 ways of reading window values.
import PySimpleGUI as sg
layout = [[sg.Text('My one-shot window.')],
[sg.InputText(), sg.FileBrowse()],
[sg.Submit(), sg.Cancel()]]
window = sg.Window('Window Title').Layout(layout)
event, values = window.Read()
window.Close()
source_filename = values[0]
Pattern 2 A - Persistent window (multiple reads using an event loop)
Some of the more advanced programs operate with the window remaining visible on the screen. Input values are collected, but rather than closing the window, it is kept visible acting as a way to both output information to the user and gather input data.
This code will present a window and will print values until the user clicks the exit button or closes window using an X.
import PySimpleGUI as sg
layout = [[sg.Text('Persistent window')],
[sg.Input()],
[sg.Button('Read'), sg.Exit()]]
window = sg.Window('Window that stays open').Layout(layout)
while True:
event, values = window.Read()
if event is None or event == 'Exit':
break
print(event, values)
window.Close()
Pattern 2 B - Persistent window (multiple reads using an event loop + updates data in window)
This is a slightly more complex, but maybe more realistic version that reads input from the user and displays that input as text in the window. Your program is likely to be doing both of those activities so this will give you a big jump-start.
Do not worry yet what all of these statements mean. Just copy it so you can begin to play with it, make some changes. Experiment to see how thing work.
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
layout = [[sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_') ],
[sg.Input(key='_IN_')],
[sg.Button('Show'), 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 event == 'Show':
# change the "output" element to be the value of "input" element
window.FindElement('_OUTPUT_').Update(values['_IN_'])
window.Close()
MikeTheWatchGuy 2018-10-31T00:35:21Z
PopupQuickMessage
Time for a new Popup.... it's been a while.... I saw an app tonight that did something very clever. I didn't recognize it as a PySimpleGUI application because of this clever trick.
The trick was to show a Popup with no titlebar, no buttons, with a timeout. The result is a message that flashes up on the screen for a short period of time. It took setting a number of parameters in order to create this Popup. I like it enough to create a call with these settings set for you. It's similar to the PopupQuick. Since it basically shows you a message, I added "message" to the name.
Here is the code that produced the video...
while True: # Event Loop
event, values = window.Read()
if event is None or event == 'Exit':
break
if event == 'Show':
sg.PopupQuickMessage("My message", 'This message will disappear in 2 seconds', text_color='red')
The message disappears while the program is in the call to Read. It is a completely asynchronous event to the loop.
NOTE, you still have to call Read or Refresh on the window if you want it to disappear. You can't, for example, sleep for 6 seconds right after the call and expect it to disappear.
MikeTheWatchGuy 2018-10-31T04:06:26Z
Day 112
I have been reviewing the issues, to-do lists, notes, etc. It seems like PySimpleGUI has reached a good spot in terms of functionality and stability. It has all of the windowing behaviors I wanted, timeout work, all of the tkinter widgets are represented, input values are returned for everything and there is plenty of customizations available. If development were to stop right now, it wouldn't be a bad package to live with. A great number of "Simple" applications could be built with what is currently available.
I find it hard to believe that it has been "only 112 days" since the initial check-in on July 11. It gives me a lot of hope for the next PySimpleGUI project....
I'm still pondering if Qt or Driod is next. I'm leaning towards Droid / Kivy because it's something completely different and it could really open up some pretty cool things if making Android applications becomes as easy as it is to make the current PSG style applications. It also takes the user's creations off of their computer and into their pocket, on their phone. How cool it will be to be able to show your friends your latest program by handing them your phone? Right? Well, I think it would be cool.
There is no doubt plenty more development left to do on PySimpleGUI-tkinter, so it's not like the development is going to halt on. But there may be some slowing of the pace from what it's been at for the past 112 days.
Thank you to everyone that has posted, emailed, contributed to this effort. My initial narrow focus could not have led me to where we are now. I couldn't have done it without your assistance.
MikeTheWatchGuy 2018-10-31T15:42:09Z
Risky Change - "Master Root Window"
Let's start the day off with a risky, hits every program change.
I just checked in a change that I made overnight that's a bit risky, but gets rid of a nasty problem.
Previously, the first window created became the "Parent window" to all other windows. If that first window happened to be the "Debug print" window, then when you close the debug print, it closed all other windows created after it. Not good.
I tried this change once before with a not-good outcome. This time it seems to work perfectly.
When the first window is created, another hidden window is first created that is the parent to all other windows. This should work, in theory.
I could use a couple of people to use the GitHub code for their projects, particularly if multiple windows are used.
I thought I had all of the windowing stuff DONE, but clearly not quite.
This will make the Debug print window much more usable as you'll be able to simply close it if you don't want it anymore and it won't close your other windows.
MikeTheWatchGuy 2018-10-31T16:23:56Z
New Cookbook and Readme Design Patterns
I give in.... the do_not_clear parameter has been added to the design patterns in the documentation and demo program.
I've gotten numerous issues logged over the past few weeks of people getting tripped up by this... no more shall this happen, I hope...
Also notice that I've started to not only surround the Keys with _, I also make them upper case now. I've found it really helps show where in the code the elements are being referenced. The _ alone wasn't drawing enough attention.
Here is one of the new patterns....
Pattern 2 B - Persistent window (multiple reads using an event loop + updates data in window)
This is a slightly more complex, but maybe more realistic version that reads input from the user and displays that input as text in the window. Your program is likely to be doing both of those activities so this will give you a big jump-start.
Do not worry yet what all of these statements mean. Just copy it so you can begin to play with it, make some changes. Experiment to see how thing work.
A final note... the parameter do_not_clear
in the input call determines the action of the input field after a button event. If this value is True, the input value remains visible following button clicks. If False, then the input field is CLEARED of whatever was input. If you are building a "Form" type of window with data entry, you likely want False, the default setting (you can remove the parameter completely).
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
layout = [[sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_') ],
[sg.Input(do_not_clear=True, key='_IN_')],
[sg.Button('Show'), 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 event == 'Show':
# change the "output" element to be the value of "input" element
window.FindElement('_OUTPUT_').Update(values['_IN_'])
window.Close()
MikeTheWatchGuy 2018-11-01T18:38:03Z
Write Only Elements
Another day, another new PySimpleGUI feature.
You can indicate you do not want an element to have a return value by add to that element's key the value WRITE_ONLY_KEY.
Here is an example layout
layout = [
[sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_')],
[sg.In(key=sg.WRITE_ONLY_KEY+' my key')],
[sg.Input(do_not_clear=True, key='_IN_')],
[sg.Button('Show'), sg.Button('Exit')]
]
Elements like the Multiline can be both input and output. If you've used a multiline to output 3 MB worth of data, you do not want to read that data back.
BTW, I'm much more likely to implement a feature this way than I am by adding more parameter's to the Elements themselves. I would like to keep the Elements simple if possible by minimizing the number of parameters.
Please don't hardcode the value of the variable WRITE_ONLY_KEY in your code as I've been known to change constant values. I changed the timeout one today in fact so be careful if you've hardcoded that old string value in your code (I may be guilty of that myself which is why I'm saying something)
MikeTheWatchGuy 2018-11-02T04:39:10Z
Input Validation Example
I'm finally at a spot where I can demonstrate what I've had in mind for "input validation". Rather than setup callbacks or pass in validation strings, I've always had my eyes set on the user doing the validation... in a SIMPLE way.
This demo program will do that, AND, it will automatically advance from one field to the next. I don't know about you, but some days I impress the sh*t out of myself.
You'll need to get the latest code from Master Branch for the SetFocus to work. Just delete that line if you want.
The input fields for the time only accept numeric digits. When 2 digits have been entered, the cursor will automagically move on to the next field.
Notice that the line of code that does the validation, is A LINE of code:
window.FindElement(event).Update(re.sub("[^0-9]", "", values[event]))
No callbacks, no pattern match strings being passed in. Just straightforward Python code using reg exp.
import PySimpleGUI as sg
import re
sg.ChangeLookAndFeel('LightGreen')
layout = [[sg.Text('Time Input Validation Demonstration', font='Any 18')],
[
sg.In(key='_TIME1_', size=(4,1), change_submits=True, do_not_clear=True ), sg.T(':', pad=(0,0)),
sg.In(key='_TIME2_', size=(4,1), change_submits=True, do_not_clear=True), sg.T(':', pad=(0,0)),
sg.In(key='_TIME3_', size=(4,1), change_submits=True, do_not_clear=True)],
[sg.Multiline(key='_M_', do_not_clear=True)],
[sg.OK()]]
window = sg.Window('Demo - Input Validation', font=('Helvetica 14')).Layout(layout)
while True:
event, values = window.Read()
if event in (None, 'Quit'):
break
if event in ('_TIME1_', '_TIME2_', '_TIME3_'):
window.FindElement(event).Update(re.sub("[^0-9]", "", values[event]))
if event == '_TIME1_' and len(window.FindElement(event).Get()) == 2:
window.FindElement('_TIME2_').SetFocus()
if event == '_TIME2_' and len(window.FindElement(event).Get()) == 2:
window.FindElement('_TIME3_').SetFocus()
if event == '_TIME3_' and len(window.FindElement(event).Get()) == 2:
window.FindElement('_M_').SetFocus()
window.Close()
MikeTheWatchGuy 2018-11-02T05:13:00Z
Starting Date Parameter added to date chooser
If you are using the CalendarButton and your dates are a long ways away from today, you're going to be happy to see the new parameter added to that button!
Set the tuple to the date you want and the calendar chooser will open to that date:
default_date_m_d_y=(12,2,1999)
It actually doesn't choose the day for you, but rather opens you to that month and year. Choosing the date will automatically close the chooser window too.
This test code demonstrates how to use it:
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
layout = [
[sg.Input(do_not_clear=True, key='_IN1_'), sg.CalendarButton('cal', '_IN1_')],
[sg.Input(do_not_clear=True, key='_IN2_'), sg.CalendarButton('cal','_IN2_', default_date_m_d_y=(12,2,1999))],
[sg.Button('Show'), 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
window.Close()
MikeTheWatchGuy 2018-11-02T16:30:26Z
3.14.0 & 1.14.0
It's only been 3 days since the last PyPI release and already features were beginning to pile up. There are some cool ones I'm eager to get out, including the change submits that now enables input validation much more easily. As usual, the docs are lagging a tad. These new API calls and functions are not yet in there, and there are plenty of them including new methods on the Window object. Lots of parameters for debug window.
You can enjoy these new features by upgrading
More windowing changes...
using a hidden root windowing (Tk())
all children are Toplevel() windows
Read only setting for:
Input Text
Multiline
Font setting for InputCombo, Multiline
change_submits settinf for Radio Element
SetFocus for multiline, input elements
Default mon, day, year for calendar chooser button
Tree element update, added ability to change a single key
Message parm removed from ReadNonBlocking
Fix for closing windows using X
CurrentLocation method for Windows
Debug Window options
location
font
no_button
no_titlebar
grab_anywhere
keep_on_top
New Print / EasyPrint options
location
font
no_button
no_titlebar
grab_anywhere
keep_on_top
New popup, PopupQuickMessage
PopupGetFolder, PopupGetFile new initial_folder parm
MikeTheWatchGuy 2018-11-02T23:00:54Z
change_submits
for File & Folder Browse Buttons
Buttons that "hold" and return information in the values list now have the ability to return back their values immediately upon selection. This will enable you to fill another field with file / folder information. You could, for example, populate a Listbox Element with a list of files rather than populate a single line input element.
I'm still looking at adding it to the Color chooser and calendar elements. I'm having difficulty because these 2 buttons do not return values in the list of values so they can't have themselves be the target. Once I add the ability for these buttons to hold and return a value, then change_submits will be appropriate.
I got this idea by reading someone else's code that was posted on GitHub. This clever engineer bypassed the SDK and manipulated internal class variables in a way that implemented the feature without having any sdk changes. Has to be the most clever use I've seen yet, especially because the variable being manipulated didn't even exist as part of the class.
This little bit of code demonstrates how to fill in a multiline and a listbox using the list of files returned from browsing.
import PySimpleGUI as sg
layout = [
[sg.Text('Select some files')],
[sg.FilesBrowse('Select Files', change_submits=True, target='_FILES_', key='_FILES_')],
[sg.Multiline(size=(60,8), key='_MULTI_')],
[sg.Listbox([], size=(60,6), key='_LIST_')],
[sg.Button('Read')]
]
window = sg.Window('Main').Layout(layout)
while True:
event, values = window.Read()
print(event, values)
if event is None:
break
if event == '_FILES_':
window.FindElement('_MULTI_').Update('\n'.join((values['_FILES_'].split(';'))))
window.FindElement('_LIST_').Update((values['_FILES_'].split(';')))
MikeTheWatchGuy 2018-11-03T16:32:30Z
disable_close
for Windows
You can now stop the X from closing a window by setting the disable_close
parameter to the Window() call to True.
hpca01 2018-11-03T18:28:11Z Hey Bud, if you want to add my app to the repo of tools made using your lib:
https://github.com/hpca01/BatchPDFFile
On Sat, Nov 3, 2018 at 9:32 AM MikeTheWatchGuy notifications@github.com wrote:
disable_close for Windows
You can now stop the X from closing a window by setting the disable_close parameter to the Window() call to True.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142#issuecomment-435601547, or mute the thread https://github.com/notifications/unsubscribe-auth/AccLM7I2hpI4bk5wkxMA3rz3CFnrkr8rks5urcUfgaJpZM4WdqH- .
MikeTheWatchGuy 2018-11-03T18:37:27Z I was looking at your code earlier. I opened an Issue commenting on one section of it. I'll add you to the list of people using PySimpleGUI in their projects.
MikeTheWatchGuy 2018-11-04T18:44:59Z
Graph Element Mouse Events
New changes checked into Master Branch.
I've been working on the interactive capabilities of Elements recently. The Table Element just got a new double-click event for example.
This time I turned to the Graph Element. There are 2 capabilities that I've been wanting to add that just got added:
-
Ability to receive mouse-clicks
-
Ability to receive mouse-drags
sg.Graph((800,800), (0,450), (450,0), key='_GRAPH_', change_submits=True, drag_submits=False)
To get these mouse events, set change_submits
in the graph element. To get a continuous stream of mouse events as the the mouse is click and dragged, also set the drag_submits
parameter. With this set you'll get events as long as the mouse button if held down. This capability is needed for "drawing" type programs.
With change_submits, you'll also get a value of None, None when the mouse is released. However, you will not receive this (None, None) value when the button is released if you have drag_submits set. Sorry but it wasn't architecturally possible.
These 2 features can enable things like a drawing application to be built. I built a Crossword Puzzle demo program to demonstrate the mouse click capability
MikeTheWatchGuy 2018-11-04T21:43:46Z
PySimpleGUI_Qt
Development has officially started on PySimpleGUI for Qt.
Today was the Hello day! I'm actually really surprised at the outcome of this test and the port I'm doing.
The first PySimpleGUI program running on top of Qt was this one....
import PySimpleGUI_Qt as sg
layout = [[sg.Text('Hello PySimpleGUI!')]]
window = sg.Window('My first QT Window').Layout(layout)
event, values = window.Read()
For a while, the code is going to be the same, boring, simple PySimpleGUI code that you've been used to. It's all going to look the same, but eventually there will be some really cool widgets and capabilities. Before you know it you'll be writing Qt applications! You just have to be careful not to tell anyone you're using PySimpleGUI as a way to get them written.
This is going to be fun! And may even be easier than originally thought.
Making lots of quick progress today!
Here's the current list of Elements that are up and running... This screenshot was taken from Linux
MikeTheWatchGuy 2018-11-05T04:19:40Z
QT Reads Working....
For the first day of working with Qt, I sure got a long ways. I'm thrilled to say the least. I thought it would be a week or more before I would be able to read values coming back from a Qt window.
This Window reads and returned these values:
Test ['Input text goes here', 'Combo 2', ['Listbox Item 2'], 57, 4, True, False, True, False, True, False, 7]
Here is the code used to generate the window:
import PySimpleGUI_Qt as sg
layout = [
[sg.Text('Hello PySimpleGUI!'),sg.Text(' '*5), sg.Text('Multiple Elements on 1 row works...'), ],
[sg.Text('Input something here'), sg.Input('default text')],
[sg.Combo(['Combo 1', 'Combo 2', 'Combo 3'])],
[sg.Listbox(['Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'], size=(30,5)),
sg.Slider((1,100))],
[sg.Slider((1,10), orientation='h')],
[sg.Checkbox('Checkbox 1'), sg.Checkbox('Checkbox 2')],
[sg.Checkbox('Checkbox 3'), sg.Checkbox('Checkbox 4')],
[sg.Radio('Radio1', group_id=1),sg.Radio('Radio2', group_id=1)],
[sg.Spin((5,8))],
[sg.Button('My Button')],
]
window = sg.Window('My first QT Window').Layout(layout)
while True:
event, values = window.Read()
print(event, values)
I have a feeling this entire project is going to come together rather quickly.
I'm not yet able to determine what the button clicked was specifically, only that a button was clicked. I'm not able to open multiple windows, etc etc etc. It's super early.
Because I need the stuff backed up, I checked it all into GitHub so you're welcome to try it if you really want to experience the early results (I don't recommend it but knock yourself out).
I was really surprised at how easy it was to install PySide2, particularly on Linux. It's obvious that the windows will look really very nice running Qt and I'm betting there are some awesome widgets awaiting us so stay tuned, good times ahead!
MikeTheWatchGuy 2018-11-05T17:38:40Z
Dial - The First New Qt Element
Progress is moving along swiftly. 11 Elements are completed and returning values when read. The Buttons are all hooked up correctly too. Popups are working.
And, now the first new element in a while... meet... the Dial Element...
layout = [
[sg.Text('This is the new Dial Element!')],
[sg.Dial(range=(1,100), key='_DIAL_')],
[sg.Button('Show'), sg.Button('Exit')]
]
This Qt stuff is working out quite well within the PySimpleGUI framework. I expect a good number of these new Elements to be popping up along the way. There are too many of these goodies to pass up!
Soon it will be to the point that I can turn lose some users on it. What's missing at the moment are the Size. font, and color parameters. They should be straightforward to complete. I may be far enough along by the weekend to post an official Alpha version.
MikeTheWatchGuy 2018-11-06T02:55:44Z
Qt Progress
And there they are! The PySimpleGUI blue buttons. Can't miss 'em when someone posts a screenshot.
Guess what today's focus was on? Perhaps fonts and colors? Managed to crack the font and color nut today. I'm hacking my way though this and so far so good!
I'm on target for sure now to have a "tech demo" available by the weekend. I would like to make progress on some Update Methods by then so that some of the more interesting programs can be tried. If you've got a program that you want to see running on Qt then get ready! It's almost here!
MikeTheWatchGuy 2018-11-06T21:43:06Z
Qt - Done with base widgets
Everything bagel anyone?
The only Element that didn't make it was the "Option Menu", a widget that's unique to tkinter.
Everything else that you see is working!
The big breakthroughs today was getting those recursive "Container Elements". I've got Frame and Column working so you can pretty much layout your Window exactly how you would like it.
Font sizes work, colors work, returning values works. It may already be in a pre-Alpha condition ready for some brave soul.
Here is the code for that mess....
# ------ Column Definition ------ #
column1 = [[sg.Text('Column 1', background_color='lightblue',text_color='black', justification='center', size=(100,30))],
[sg.Spin((1,10), size=(100,30))],
[sg.Spin((1,10), size=(100,30))],
[sg.Spin((1,10), size=(100,30))],]
layout = [
[sg.Menu(menu_def, tearoff=True)],
[sg.Text('(Almost) All widgets in one Window!', size=(600, 50), justification='l', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)],
[sg.Text('Here is some text.... and a place to enter text')],
[sg.InputText('This is my text', size=(300,30))],
[sg.Frame(layout=[
[sg.Checkbox('Checkbox', size=(185,30)), sg.Checkbox('My second checkbox!', default=True)],
[sg.Radio('My first Radio!', "RADIO1", default=True, size=(180,30), ),sg.Radio('My second Radio!', "RADIO1")]], title='Options',title_color='red', relief=sg.RELIEF_SUNKEN, tooltip='Use these to set flags', ), sg.Stretch()],
[sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(300, 80)),
sg.Multiline(default_text='A second multi-line', size=(300, 80))],
[sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(150, 30)),
sg.Slider(range=(1, 100), orientation='h', size=(150, 30), default_value=85)],
[sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))],
[sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(200,100)),
sg.Frame('Labelled Group',[[
sg.Slider(range=(1, 100), orientation='v', default_value=25, tick_interval=25),
sg.Slider(range=(1, 100), orientation='v', default_value=75),
sg.Slider(range=(1, 100), orientation='v', default_value=10),
sg.Column(column1, background_color='lightblue')]]), sg.Stretch()],
[sg.Text('_' * 80)],
[sg.Text('Choose A Folder')],
[sg.Text('Your Folder', auto_size_text=True, justification='right'),
sg.InputText('Default Folder', size=(300,30)), sg.FolderBrowse()],
[sg.Submit(tooltip='Click to submit this form', size=(120,30)), sg.Cancel(size=(120,30))]]
window = sg.Window('Everything bagel', default_element_size=(40, 1), grab_anywhere=False, font=('Helvetica', 12)).Layout(layout)
event, values = window.Read()
MikeTheWatchGuy 2018-11-07T02:36:23Z
Great Widget Access
PSG-Qt is providing greater access to the underlying Qt objects. The original PSG was not designed to be used this way, but the architecture certainly doesn't prevent it. It was more of a philosophy then a design constraint. I wanted to "shield" from tkinter as much as possible.
With Qt I want you to have full control of the widgets. You'll still have to go through the layout process prior to accessing them (i.e. you'll call Finalize should you want to configure them prior to a Read() call.) Finalize is a Read Non-blocking call, by the way.
This means your Window will be visible prior to you configuring your widgets. This is an architectural limitation and the objects are created when the window is "built". There are no easy ways around this. Maybe down the road. I've not heard any complaints about this so far so I'm not considering it to be a big issue.
I've named the Qt objects using this naming convention:
All Qt objects begin with QT_. The remainder of the variable name is the object
For example QT_ComboBox = QComboBox()
By opening up access, you guys can go nuts customizing your PySimpleGUI Elements. If I don't provide access to come particular setting that you want to get to, you'll have easy access now.
I think I'm more excited about Qt than I was tkinter. You ability to interact with your data is going to go up significantly. I hope I can do a great job on the Table Element because there are some cool things that Qt enables you to do.
A downside is that it's LARGE. PyInstaller creates a 200 MB .exe file. Not very viable for distributing your applications to other people. But is at least usable and I was able to compile a PySimpleGUI_Qt program and it worked!
Hoping to keep up the pace and get a lot more of it written quickly. I'm stumbling around at the moment working on multiline line output and also the Output Element itself which is the re-routed stdout
MikeTheWatchGuy 2018-11-07T05:52:00Z
Qt - Files and folders buttons operational
The FileBrowse, FilesBrowse, SaveAs, and FolderBrowse buttons are all operational. They open the dialog box to get the info from the user and then fill in the information in the target element. They also support the change_submits parameter. Starting to add some of that interactive stuff now too that uses the change_submits flag.
MikeTheWatchGuy 2018-11-07T18:47:05Z
Output Element and MultilineOutput Element!
Two more output Elements are done. The Output Element reroutes stdout and stderr to a multiline window. The Multiline Element is basically the same kind of widget visually. You manually update the contents of a MultilineOutput Element using the Update method.
These both moved the project forward a ways as there are a number of Demo programs that can now run using PySimpleGUI_Qt.
My target program to get up and running is HowDoI, which is what drove the Output Element. The next thing to do for that program is get the "enter_submits" parameter working for the MultilineInput Element so that you can type in a query and press enter.
This is how I generally go about feature development... find a need, implement the feature. While I'm in there I usually look for other things to implement. Slowly it all fills out into a full-featured port!
Here's the current condition of that program. Everything works except for the enter_submits thing.
It's hard to tell the difference between the tkinter one and the Qt one. It's encouraging that I'm able to duplicate the same layouts using the PySimpleGUI framework. The source code isn't exactly the same because of the size parameter now being in pixels, but other than that the layouts and Read calls, etc, are identical between the 2 programs.
MikeTheWatchGuy 2018-11-07T21:01:13Z
How to Submit a Pull Request
It's really rare for me to accept pull requests directly. If contributing and getting GitHub recognition via the pull requests is an important thing for you, then don't submit a request. I hand merge changes 99% of the time. It's pretty rare to get Pull Requests anyway.
If you do have a new thing to add or a bug to fix, please submit a "Test Harness" to go with it. It should exercise the change and also demonstrate that nothing else was broken in that area of code.
I made a change today to the Update method of Multiline Elements. You can now change the background color and text color using Update. If this was submitted as a Pull Request, I would like to see a file that resembles something like this:
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
layout = [
[sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_')],
[sg.Input(do_not_clear=True, key='_IN_')],
[sg.Multiline(key='+MULTI+', do_not_clear=True, size=(20,10))],
[sg.Button('Normal'), sg.Button('Text'), sg.Button('Background'),sg.Button('Reset'),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 event == 'Normal':
window.FindElement('+MULTI+').Update(values['_IN_']+'\n', append=True)
elif event == 'Text':
window.FindElement('+MULTI+').Update(values['_IN_']+'\n', text_color='red', append=True)
elif event == 'Background':
window.FindElement('+MULTI+').Update(values['_IN_']+'\n', background_color='gray20', append=True)
elif event == 'Reset':
window.FindElement('+MULTI+').Update(values['_IN_']+'\n', text_color='black', background_color='white', append=True)
window.Close()
MikeTheWatchGuy 2018-11-08T01:23:07Z
Qt Padding....
What a huge difference now that I got control over padding!
My desktop toolbar just got replaced! One by one the Demo programs are being picked off. I've been trying hard to replace HowDoI, but I just can't get the enter key binding code to work.
The toolbar I use is a good example of the tight layouts that are again possible.
MikeTheWatchGuy 2018-11-08T06:38:00Z
Qt Speed Test
If you've attempted to create a lot of buttons using tkinter or a large number of individual text fields, you're in a for a bit of a wait.
I'm happy to report better load times for these windows with lots of Elements.
This Demo program has always been a bit of a CPU killer in the past.
Here's the verdict on load times. It's not close enough to be a contest.
MikeTheWatchGuy 2018-11-08T20:48:03Z
pip install PySimpleGUIQt
Fun command line command of the day!
It's officially a pre-alpha release.
Here is what works and doesn't work
Functioning features
Features are being added daily to this Qt port of PySimpleGUI.
These Elements are "complete":
-
Text
-
Input single line
-
Input multiline
-
Output multiline (new)
-
Dial (new)
-
Output - reroute stdout
-
Spinner
-
Sliders
-
Buttons - RButtons, CButtons, Short-cut Buttons
-
Checkbox
-
Radio Buttons
-
Listbox
-
ComboBox
-
Labeled Frames
-
Columns - enables you to make pretty much any layout!
-
Alpha channel for windows
-
No Title Bar setting
-
Enter submits for multiline
-
Fonts
-
Colors for text and background
Complete is a relative term
Missing Features
Notable MISSING features at the moment include:
-
Timeouts - nothing dealing with timeouts has been ported
-
Tables, Graphs, Trees - the more complex Elements have not yet been ported. Stay tuned, new ones being added daily!
-
Change submits - enter submits works for multiline
MikeTheWatchGuy 2018-11-08T23:26:49Z
Qt - Non-blocking Read Calls!
Wow, this really opened up the number of possible applications that can run. You can now set a timeout value of 0 in the Read call and PySimpleGUIQt will do a non-blocking read. I've go the Desktop Timer demo running. Qt is FAST too. I thought it would be slower than tkinter and it may be faster. Exciting stuff to see work.
I REALLY want to get the Table and Graph widgets done. Those will produce some pretty spectacular results. I'm trying to get to the point that the Rainmeter style programs will all run. So far the CPU meter does, including semi-transparent.
MikeTheWatchGuy 2018-11-09T14:17:42Z
Qt inches towards desktop widgets
Just completed and checked in the "Grab Anywhere" feature. This feature is needed for windows with no titlebar, like the desktop widget or this HowDoI window.
I'll confess that I have been using HowDoI extensively for this port. It's my secret to cranking out features at a record pace. Here's the response I got from HowDoI regarding dragging windows. I copied, pasted, and slightly modified the code and poof, instant feature completed. It took less than 5 minutes.
MikeTheWatchGuy 2018-11-09T15:12:48Z
Qt Table Element
Told you I was working hard to get that Table Element working... and now I've got a crude version working!
It supports setting colors, obviously. Displaying the table is all that's currently working. Can't set the column headings, indicate if row numbers should be present, shading every other row, etc, are all not completed. You also will not get back a Read Result that's meaningful (always returns a value of '0').
This is going to be one very difficult element to complete. There will be more options available than on the tkinter version. Stuff like selecting columns, perhaps sorting, etc, are down the road.
MikeTheWatchGuy 2018-11-09T15:54:09Z
Qt Summary
These are the "Completed" Elements. 16 down, 6 to go! Not bad for 5 days.
Note that each of the "Completed Elements" are not fully complete. For example, the only element that support any kind of change_submits is the multiline input's enter_submits.
Completed Elements
-
Text
-
Single Line Input
-
Multiline input
-
Multiline output (2 different ones now)
-
Output (stdout)
-
Button
-
Listbox
-
Combobox
-
Spinner
-
Radio
-
Checkbox
-
Slider
-
Table
-
Column
-
Labelled Frame
-
Dial (brand new element!)
Elements to be completed:
-
Graph
-
Image
-
Tree
-
Option menu (may not be possible)
-
Progress Meter
-
Tab & Tab Group
I'm likely going to focus on completing in this order for unfinished elements: Graph, Progress Meter, Tabs, Image, and the dreaded Tree. Of course along the way I'm adding the change submits, timeouts, etc. Slowly filling in features more or less as they are required in the applications I'm using to test and drive the features.
Today I'm focusing on reading the Table Element.
MikeTheWatchGuy 2018-11-09T16:04:55Z
Qt Table Reads Work...
Well, that was quick. Thank you HowDoI!!
Just like the original PySimpleGUI, the Qt version returns which rows are selected.
Check out the query and response.
Now check out the code used to generate the response to a window.Read()
value = []
indexes = element.QT_TableWidget.selectionModel().selectedRows()
for index in sorted(indexes):
value.append(index.row())
IF you are an experienced engineer, then this tool is downright deadly for this kind of coding. I need these widgets to basically work. I only have to get them to work once
MikeTheWatchGuy 2018-11-09T18:15:14Z
Qt Element Summary for Release 0.3.0
New PyPI version posted this morning. This is a quick-reference of the available Widgets in your toolbox.
Here is a visual summary of the currently operational Elements as of version 0.3.0
MikeTheWatchGuy 2018-11-09T19:02:40Z
change_submits
For Dial Element
I just finished getting the change_submits
feature working for dials. The reason I chose dials was to demonstrate how you can create your own set of extended widgets. It's very easy and straightforward.
I didn't like the fact that the Dial Widget supplied by Qt had no indicator as to the value it is currently set at. The way I solved it was to use a Text Element that displays the dial value. It is one line of code in the event loop to do this.
window.FindElement('+DIAL_VALUE+').Update(values['_DIAL_'])
Update the text element with
import PySimpleGUIQt as sg
layout = [
[sg.Text('This is the new Dial Element!')],
[sg.T(' ', size=(70,10)), sg.T('0', key='+DIAL_VALUE+', font=('Helvetica', 15))],
[sg.Dial(range=(1,100), key='_DIAL_', change_submits=True)],
[sg.Button('Show'), 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
window.FindElement('+DIAL_VALUE+').Update(values['_DIAL_'])
window.Close()
MikeTheWatchGuy 2018-11-10T18:08:59Z
634 People Tried PySimpleGUIQt Yesterday!
Awesome to see the number of people trying out Qt surge so much! Damn, I'm going to have to get going on finishing all of the features.
Thank you to everyone that's giving it a try.
MikeTheWatchGuy 2018-11-10T18:22:28Z
Qt Timeouts!
Great news! Timeouts work on Window.Read calls. This enables all sorts of fun applications like the Timer and other desktop widgets that poll. It also enables multiple window support.
I just ported someone's code that did a 2-window application. The second window is a pop-up of sorts that is running a timer. When the timer is completed, it updates the first window and closes. To move it over to Qt required only TWO changes. The import, and the size statements. That was ALL that was required. It was amazing to see come up and work.
Here is the tkinter version:
And this is the Qt version
They are strikingly similar in appearance. In fact, the tkinter version could flatten out the buttons and tighten up the spacing and it would look even closer. Doing this, I get this window... running tkinter:
MikeTheWatchGuy 2018-11-10T20:51:59Z
Qt Background Images... more reasons to try PySimpleGUIQt today!
Come join the Pre-Alpha fun! PySimpleGUIQt is doing better than expected.
There have been numerous requests background images on your windows. I've not been able to deliver that feature on tkinter.
For Qt, however, it's possible to do... so, you can now have background images as the background to a window. All you have to do is add this parameter to your Window call:
background_image = 'yourpngfile.png'
I haven't done it for columns yet... I'm waiting to see what the demand is for that feature.
Coming very soon.... the Graph Element! That's now my focus. I'm dying to get the CPU Core Usage Rainmeter display working. There are a lot of methods to handle for that Element so it could take a minute to do. Now that I can display images, I expect the Image element to get nailed down soon too. I am taking requests for feature priority for brave people wanting to use PySimpleGUIQt for their project.
MikeTheWatchGuy 2018-11-10T21:42:17Z
0.4.0
More features rolled out including
-
Images as background
-
Timeouts
-
Change submits
There are a bunch of others that I'll document in the readme. I'll be doing a real ReadMe this weekend.
These are not small features, btw. You can already read one element and update the value of another and also run non-blocking windows... using a timeout value instead of running non-blocking at all.
MikeTheWatchGuy 2018-11-11T04:02:20Z
"It just worked"
I've been racing towards getting the CPU Cores Utilization Graphics to work. I finished coding the Graph Element and the DrawLine route. Then I changed 1 line in the CPU Dashboard program and bam! Up pops this graph!
The source code was 100% backwards compatible. Even the transparency was correct.
MikeTheWatchGuy 2018-11-11T16:56:13Z
Qt Graph Widget working!
"I would rather be lucky than good" applied to this one too.
Check out this one.... tkinter on top, Qt on the bottom. Both are running as fast as possible and they look roughly the SAME in terms of graph speed.
Last night was unable to figure out how to correctly move the graphs. I toyed around this morning and it suddenly worked.
I continue to struggle a bit with getting the layouts "tight".
Well on the way to getting this Graph Element in the bag and soon!
MikeTheWatchGuy 2018-11-11T18:10:42Z
PySimpleGUIQT 0.6.0
Just posted 0.6.0 to PyPI. The Graph Element was the new addition. Getting closer and closer to "Feature complete" in terms of the individual elements. The major ones left to go - Tree, Image, Tabs, Menus.
Next up... Image
Then Tree, Tabs, Menu
MikeTheWatchGuy 2018-11-11T18:18:39Z
4 times the number of people downloaded Qt versus tkinter yesterday!
Even though Qt is at "Pre-Alpha" status, it was pip installed over 500 times yesterday. tkinter version 130. It's a LOT more popular than I expected, especially since it's not feature complete and it requires a lot more setup (PySide2).
MikeTheWatchGuy 2018-11-11T19:52:32Z
Qt 0.7.0
Fix for Popups not closing. Surprised no one noticed.
Partially done with Image Element. One test of it passed. Not sure how well it works yet. Trying to get the Base64 version working.
MikeTheWatchGuy 2018-11-11T21:28:04Z
TABS!
Yes, Tabs are among the slain features. It took a lot of wrestling with Qt
I don't have the styling stuff completed, but I can see that it's going to be AWESOME because we'll be able to change fonts, sizes, colors, etc.
MikeTheWatchGuy 2018-11-11T22:34:02Z
Trees!
I've even got the little icons hooked up this time!
The only thing left until "Feature complete" is Menus!
I'm determined to be done by Tues, when PySimpleGUI is going to be highlights on a popular podcast.
MikeTheWatchGuy 2018-11-12T01:12:51Z
Base 64 Images
You might recognize this little clock / weather app. I finally got the help I needed in order to get Base64 images displayed. Next thing I want to do with those is add them to buttons so that I get my little red X button back again. Custom button graphics will always deliver a nice boost to a layout.
MikeTheWatchGuy 2018-11-12T02:07:16Z
Stretch Element
There is another new Element that is part of PySimpleGUIQt called the Stretch Element. What it does is pushes Elements around left and right within the window. If you want 2 elements to be on oppposite sides of a window, put a stretch between them. If you want them to remain together, put a stretch on one side of them.
You can also use it to push an element to the right or left side.
For example, to push a button to the far right, add Stretch to the left of it:
layout = [[sg.Column(clock, background_color='black')],
[sg.Column(weather_cols[x], background_color='black') for x in range(NUM_COLS)],
[sg.Stretch(), sg.RButton('Exit', button_color=('black', 'black'),
image_data=orangeround[22:], tooltip='close window')]]
Having the stretch on the left side of the Button caused the button to go to the far right.
MikeTheWatchGuy 2018-11-12T18:10:02Z
Menus!
And another feature falls... ONE more to go... progress meters.
I hate working on the menu code. It's recursive which is a bitch for my brain. I fumble around until it magically works. It took a couple of days.
I'm on schedule to be FEATURE COMPLETE today, 1 week from when I started this port.
All I have to do is get Progress Bars done today!
I've got more work to do on menus, such as adding keys to them, a feature I don't have in the current PySimpleGUI but is one I want to do so that menus can have duplicate names if desired. Right now you cannot use the same text for 2 menu entries or else your event will be identical and you won't know which was chosen.
MikeTheWatchGuy 2018-11-12T19:36:37Z
0.9.0 ALPHA
PySimpleGUIQt is "Feature Complete". That means all of the elements are represented in some fashion. Some are more complete than others. Over the coming week the elements will be fleshed out more and the other features refined.
I think it's ready for most people to use. It's going to take a while before a proper User's Manual is done. You should use the code as a guide for what the valid parameters are for calls.
And even better news.... the Progress Meter code is 10 times faster.
Here is what the final list of Elements looks like:
MikeTheWatchGuy 2018-11-12T20:41:42Z
PySimpleGUIQt + PyInstaller
Good news.... PySimpleGUIQt applications can be turned into .EXE files! That's awesome!
The bad news... they 210MB in size, a 20X increase. They're normally under 10MB. Clearly a LOT of modules are being pulled in. I was careful to import EACH widget / object I used individually on the import statement. It should have resulted in a smaller EXE file (I would think), but clearly did not.
MikeTheWatchGuy 2018-11-13T18:06:07Z
Qt - Autoclose Windows, multi-window support, auto-conversion of sizes
New release on master branch. Will push to PyPI later today. It's got some great new features.
One of the best, still experimental, is the conversion from tkinter character sizes to Qt pixel sizes. It's a very rough, simple multiplication method, but it works.
This enables you to run your PySimpleGUI-tkinter code without making ANY changes other than the import.
No other changes required at all to your code! That's pretty amazing, right? ;-)
It's always working well with multiple windows. In fact it was working better than the tkinter version until I fixed the tkinter problem this morning.
Give it a try! You never know, you may really like it. I changed the requirements on PyPI so that it now will automatically install PySide2 when you pip install PySimpleGUIQt.
MikeTheWatchGuy 2018-11-13T19:58:12Z
PySide2 and PyQt5 both work
I found that PyQt5 will work as well as PySide2!
I'm checking in a change that will load PyQt5 if it finds it, if not PySide2.
MikeTheWatchGuy 2018-11-13T20:03:11Z
0.10.0 Qt
Just released PySimpleGUIQt version 0.10.0
It supports both PySide2 and PyQt5.
MikeTheWatchGuy 2018-11-13T21:09:05Z
MikeTheWatchGuy 2018-11-15T18:10:49Z
# Coolest PySimpleGUI application of the day
I cruise GitHub on occasion to see how people are using PySimpleGUI. I ran across this code today:
https://github.com/jeejz/pythonProjects/blob/branch1/Sudoku%20Solver/jij/sudoku/main.py
import PySimpleGUI as psg
def DrawBox():
column = [[]]
input1 = []
for i in range(1,10):
for j in range(1,10):
key = str(i)+str(j)
input1.append(psg.InputText(default_text=key,do_not_clear=True, size=(3, 3), key=(key)))
if j%3 == 0 :
input1.append(psg.VerticalSeparator())
column.append(input1)
input1 = []
if i%3 == 0:
column.append([psg.Text('_' * 50,justification='CENTER')])
layout = [ [psg.Column(column, size=(800,800))],
[psg.OK(), psg.Cancel() ]]
window = psg.Window('Submit Question',auto_size_text=True ).Layout(layout)
while True:
event, value = window.Read()
print(event, value)
if event is None or event == 'Exit' or event == 'Cancel':
break
DrawBox()
I couldn't figure out exactly what he was drawing. Check out this screen!
What a beautiful creation.
I took the code and "ported" it to PySimpleGUIQt. I had to change 3 lines of code. The result was this:
MikeTheWatchGuy 2018-11-16T18:47:37Z
WxPython...
Text, Input, and Button elements are done in PySimpleGUIWx
These screens are from:
PySimpleGUI
PySimpleGUIQt
PySimpleGUIWx
I've got a long ways to go yet on Qt, so I have to stop working on the Wx port. I wanted to see how difficult it would be to get those basic 3 elements done in Wx. It's looking pretty easy.
Here's the code that drew these. The only thing changed between them is the sizes.
def main():
layout = [[Text('You are running the PySimpleGUI.py file itself')],
[Text('You should be importing it rather than running it', size=(50, 2))],
[Text('Here is your sample input window....')],
[Text('Source Folder', size=(15, 1), justification='right'), InputText('Source', focus=True),
FolderBrowse()],
[Text('Destination Folder', size=(15, 1), justification='right'), InputText('Dest'), FolderBrowse()],
[Ok(), Cancel()]]
window = Window('Demo window..', default_element_size=(300,25)).Layout(layout)
event, values = window.Read()
window.Close()
MikeTheWatchGuy 2018-11-17T02:14:58Z
PySimpleGUIQt
All the Qt without the ugly.
MikeTheWatchGuy 2018-11-17T17:37:12Z
Python Bytes Podcast
Another Podcast mention in Python Bytes....
https://pythonbytes.fm/episodes/show/104/api-evolution-the-right-way
This means more traffic... a great and terrible thing, especially for Qt.
There is a long ways to go on Qt and I'm relying somewhat on the users to guide the priorities. By that I mean, when someone write an issue complaining a feature doesn't work, I get busy and get it fully functional.
I ran into a number of issues with Tables while making a sample application that summarizes all the Elements. Ugh, I hate tables.
MikeTheWatchGuy 2018-11-17T21:39:00Z
New Demo "Everything Bagel" App
Tired of the unorganized look of the window that has all of the elements shown. This one includes graphics and tabs too....
MikeTheWatchGuy 2018-11-18T18:05:40Z
Popups title
parameter
All Popup calls now have a parameter, title
that will be used. For normal Popups, if no title is given, then the first parameter to be displayed is used (the old behavior). If you don't want any title, then set title=''
MikeTheWatchGuy 2018-11-18T21:26:15Z
New YouTube Tutorial - Lesson 7 - Multiple Windows
https://www.youtube.com/watch?v=uxu5C7q67gk
MikeTheWatchGuy 2018-11-19T00:51:11Z
Finally a REAL machine learning application
I found a great little machine learning project that I got through email. I'll have to figure out how to point you guys to it.
It's a Yolo *you only look once" demo. You've seen these things before. Boxes are put around objects. One of the big "problems" in machine learning that I see / experience is that they're all command line driven ... and that SUCKS. It's difficult to change parameters and re-run tests.
Here's a sample frame from a video:
Notice it's running in a PySimpleGUI window.
You'll find a video of the entire sequence here:
https://youtu.be/o0G02LGxUl0
The experience WITH a GUI is nice. I can browse, or copy and paste, my input file. Common paths like the path to the pre-trained data files can be filled in as defaults. The result is that you can slide around sliders to change parameters, hit the OK button and watch the video in real-time.
The alternate approach and the one that I started with, required a command line for all of those parameters and file paths with the output being dumped into a video file. I wasn't able to get the video files it produced to play. But thanks to the GUI that I wrote, I didn't need them as I can watch the algorithm produce the images in real time.
I would like to hear from folks that are working on machine learning or want to get involved with machine learning projects. I've been cranking out the Demo programs in hopes that someone would pick them up and do something. Perhaps this Yolo stuff will draw in more of the scientific crowd.
MikeTheWatchGuy 2018-11-20T13:10:03Z
YOLO Demo Program Posted to GitHub
You'll find the Yolo demo here:
https://github.com/MikeTheWatchGuy/PySimpleGUI/tree/master/YoloObjectDetection
You will need to download this 242MB training data file in order for it to work.
https://www.dropbox.com/s/0pq7le6fwtbarkc/yolov3.weights?dl=1
You will also need openCV.
pip install opencv-python
After the install you'll be able to run the demos.
Demo 1 - process a single image, output with objects detected.
Demo 2 - process a video, display the output to the screen (option in code to save to file commented out...uncomment to enable writes)
I've wanted this kind of demo for the GUI for some time.
Since there's an opencv demo program already posted that integrates with a webcam, it only seems logical to try and combine these 2 programs, so that's what I did. The original version is posted and a version with an option to use your webcam is also posted. Both can write the output to disk as well.
Had this remained a command line program, it would have really gotten messy to try and duplicate this GUI:
The advantage of using the GUI front-end is pretty obvious. The parameters are already filled in for you with default values. When you run the file yolo_video.py
, all you'll have to do is press enter or click OK
and the demo will run. It doesn't get any easier.
This demo comes courtesy of Dr. Adrian Rosebrock. You'll find a PDF full of information about how you can learn more about computer vision and deep learning via his pyimagesearch organization.
There is an excellent article that accompanies the posted source code where you can learn more about this awesome technology:
https://www.pyimagesearch.com/2018/11/12/yolo-object-detection-with-opencv/
MikeTheWatchGuy 2018-11-20T16:12:42Z
3.15.0 & 1.15.0
Release contents:
Error checking for InputText.Get method
Text color, background color added to multiline element.Update
Update method for Output Element - gives ability to clear the output
Graph Element - Read returns values if new flages set
-
Change submits, drag submits
-
Returns x,y coordinates
Column element new parm vertical_scroll_only
Table element new parm - bind return key - returns if return or double click
New Window parms - size, disable_close
"Better" multiwindow capabilities
Window.Size property
Popups - new title parm, custom_text
-
title sets the window title
-
custom_text - single string or tuple string sets text on button(s)
This is the longest I've gone between releases in a very long time. Part of the issue is the Qt port ate up a fully week.
There are a number of features in this release that users requested and are already using. If you're one of those users, you should delete your PySimpleGUI.py file and use the pip installed one.
If you are a multi-window user... please give this release a try. This should be the last time I mess with multiple window problems as it looks like they may be finally fixed.
The documentation is lagging. As usual, look at the code using your IDE for the most up to date function parameters. Control Q and Control P in PyCharm are your friends.
MikeTheWatchGuy 2018-11-20T17:43:23Z
0.12.0 - 20-Nov-2018
Getting to be quite the chore to stay on top of 3 releases at a time while doing development on 2 frameworks.
Multiple windows should be working correctly in this release (finally). It would appear that I have both tkinter and Qt working correctly with more than 1 window. Sick of working on race conditions from having multiple windows open.
Correctly restore stdout when OutputElement is deleted
Added Finalize ability
Better multiwindow handling... maybe it's finally fixed!
Radio button default value
Dial element default value
Show expanded option for trees
Titles for popups
MikeTheWatchGuy 2018-11-20T18:07:24Z
YOLO From Webcam, Arg Parsing
In the "I would rather be lucky than good" category, I learned that the dictionary return values that PySimpleGUI produces is exactly the same kind of dictionary that the argparser utilizes. This means that if you have a program that uses the argparse module, you can replace this statement:
args = vars(ap.parse_args())
with
event, args = win.Read()
Then in your window layout you will set your keys to the values that you expected argparse to return.
For example, if your code added arguments using this:
ap.add_argument("-o", "--output", required=True, help="path to output video")
then you want your key to be 'output'
[sg.Text('Path to output video'), sg.In(o_vid,size=(40,1), key='output'), sg.FileSaveAs()]
Here is what it looks like all put together...
MikeTheWatchGuy 2018-11-21T15:30:17Z
More Yolo
Added ability to adjust the parameters in realtime while watching the video.
This is the real power of having a GUI versus a command line. With a command line you wouldn't be able to do any adjustments of the parameters. Now you can adjust them and immediately see the impact.
MikeTheWatchGuy 2018-11-21T15:37:35Z
GitHub Scraping
Finally a PySimpleGUI Demo Application that will scrape a site and do something with it.
This program will scrape the PySimpleGUI GitHub site and display a popup when a new issue is logged or if any open issue is updated.
You can easily modify it to scrape your favorite sites.
https://github.com/MikeTheWatchGuy/PySimpleGUI/blob/master/PySimpleGUIQt/Demo%20Programs/Qt_Scrape_GitHub_Issues.py
Even though this demo program is located in the Qt section, it will run on tkinter by simply changing the import statement. This ability to seamlessly move from one GUI Framework to another continues to surprise me.
I find it shocking that so the differences under the PySimpleGUI SDK are great and yet the same source code produces nearly identical windows. I'm always surprised when it works. Maybe I should have more faith in my code?
MikeTheWatchGuy 2018-11-21T23:28:45Z
Qt - Touch keyboard demo
I need applications in order to move forward the packages. It helps generate a priority list. I'm going through the cleaning up phase for Qt.... I'm writing the rest of the features. For example, to complete the InputText element, I needed to write the set and get focus capability. This feature I recalled was written for this demo program that is a pop-up keyboard.
So, I ported the popup keyboard over to Qt.
This program was one of the very first multi-window programs... back before multiwindow was a thing. It was written by a community member.
It's actually 100% source-code-compatible between PySimpleGUI and PySimpleGUIQt. You only need to change the import and it runs. Here is how it looks in both tkinter and Qt.
MikeTheWatchGuy 2018-11-22T13:02:34Z
Qt 0.13.0
The assault on the Qt feature set continues.
Focused on finishing the Text, Input Text and Multiline Input Elements.
NEW Vertical and Horizontal Separator elements
Focus for Input Text and Multiline Input
-
Get focus
-
Set focus
Multiline input
-
Change submits
-
Update - disabled, append
Multiline output - Update value, append, disabled, get value
Text clicked submits
File types for open files
Initial folder, file types, for browse buttons
File types standardized on tkinter data format
Find Element With Focus now works for input and multiline input
Yet more multiwindow handling
Relief for Text element
Input text disable
Correct sizing of Comboboxes using visible items parm
Correct default values for input and multiline input
Change submits for multiline
Horizontal and Vertical separators
PopupGetFile and PopupGetFolder - no_window option works
MikeTheWatchGuy 2018-11-22T14:05:48Z
Source Code Compatible
I never dreamed that PySimpleGUI code would be portable between GUI frameworks, but that's exactly what it's turned out to be.
I just completed the Vertical and Horizontal Separators in PySimpleGUIQt. I wanted to see if a program like a Sudoku solver could be laid out using PySimpleGUI and these Elements.
To my surprise it worked. I only changed the import statement.
There is a gotcha behind this however.... it is another level of complexity on top of everything else. I have to maintain that backwards and forwards compatibility of PySimpleGUI source code. It doesn't always work out to be 100% compatible, but it gets you at least 99% of the way there most of the time.
MikeTheWatchGuy 2018-11-22T14:26:51Z
Qt Separators (cont)
import PySimpleGUIQt as psg
psg.SetOptions(border_width=0)
lines = []
lines.append([psg.HorizontalSeparator()])
for line in range(4):
cols = []
col = []
for cell in range(4):
col = []
cols.append(psg.VerticalSeparator())
for x in range(3):
row = []
for y in range(3):
row.append(psg.InputText(default_text='', do_not_clear=True, size=(3, 1), change_submits=True, justification='center'))
col.append(row)
cols.append(psg.Column(col))
cols.append(psg.VerticalSeparator())
lines.append(cols)
lines.append([psg.HorizontalSeparator()])
layout = [*lines,
[psg.OK(), psg.Cancel() ]]
window = psg.Window('Submit Question',auto_size_text=True ).Layout(layout)
prev_val = {}
while True:
event, value = window.Read()
This the nicest I've been able to make the Sudoku puzzle layout using the new Separator Elements in PySimpleGUIQt.
MikeTheWatchGuy 2018-11-22T17:55:02Z
New Shortcut - Element instead of FindElement... be thankful that you've got an easier way
Not liking the way the SDK looks with all these FindElement calls all over the place. I have added a short-cut function, Element.
If you use the shortcut, Element, then your update calls will go from this:
to this:
I think it reads really well. We're all used to seeing these calls in the design patterns. It shouldn't be too big of a shock. I'll make sure PyPI is updated prior to releasing any Demo Programs that use it.
MikeTheWatchGuy 2018-11-22T18:07:59Z
50,000
Today PySimpleGUI hit 50,000 pip installs across the 3 different releases (PySimpleGUI for Python 3, PySimpleGUI for Python 2.7, PySimpleGUIQt)
Doesn't this somehow show that there is a "there there"? There is a real need for a simple, easy to use GUI for Python.
Gotta get Qt done so Wx can get done so that Kivy can get started!
MikeTheWatchGuy 2018-11-23T20:40:08Z
ButtonMenu -- New Element!
I have a surprise element to announce. I wasn't planing on creating this element, but the opportunity arose and I took advantage of it. I'm supposed to be finishing the Qt port, not adding new features. While I was working on finishing it, I ran into how to build a button with a drop-down menu.
The ButtonMenu element is a combination button and a menu.
You define the menu using the exact same notation as a normal menu, except that it's only 1 entry instead of a list of entries.
You can get this capability by upgrading to the PySimpleGUIQt.py file located in the master branch. I'll release to PyPI soon.
There are a number of element sizing changes that are in this release that I want more testing time on before releasing so I'm not doing it today.
I would like to get them working with the system tray, but that's a whole other effort.
I didn't believe that tkinter could do this, but evidently it is possible. So,I'll be back-porting the code over to PySimpleGUI at some point. For now, if you want the feature, go with Qt.
import PySimpleGUIQt as sg
sg.SetOptions(element_padding=(1,0), text_color='white')
menu_def = ['&File', ['&Open', ['1','2','3'], '&Save', '&Properties', 'E&xit']]
layout = [
[sg.ButtonMenu('Menu', menu_def, key='_MENU_'), sg.T('This is a button bar '), sg.Button('Normal'),sg.Button('Another one'), sg.Stretch()],
]
window = sg.Window('Window Title',
size=(80,20),
no_titlebar=True,
background_color='black',
grab_anywhere=True,
).Layout(layout)
while True: # Event Loop
event, values = window.Read()
print(event, values)
if event is None or event == 'Exit' or values['_MENU_'] == 'Exit':
break
window.Close()
MikeTheWatchGuy 2018-11-24T13:34:20Z
Qt 0.14.0
Biggest features - "correct" element padding, fonts.
Completed feature list is now at:
Text, Input, Multiliine, Multiline Out, Output, Slider, Checkbox, Radio Button
The development continues to be focused on completing each of the elements and thus completing the Qt support.
If you've got a program using Qt that has trouble or you your code uses a particular feature not yet complete, post an Issue so that it gets priority support.
Slider tick positions set using relief parm
ButtonMenu Element
Multiline.Update font parm
Text.Update color and font now work
Button.Update font support
Window.Element = Window.FindElement
Better font support for all elements - underline, bold
Element padding - complete rework
Text element padding
Button padding
Input Text padding
Input Text password char
Listbox padding
Combobox padding
Multiline padding
Checkbox padding
Radio padding
Progress Bar padding
Output padding
Image padding
Graph padding
Slider - set tick marks using relief parm
Dial - set tick information using resolution and tick interval
Table padding
Tree padding
Seperator padding
Force window sizing should mean windows are better sized
Popup - better layout
MikeTheWatchGuy 2018-11-25T00:16:45Z
System Tray Icons! (On Qt only)
It's been a while since a major new feature, right. The ButtonMenu Element seems so long ago. At least "earlier in the week" long ago.
This is real unusual treat... the ability to run tasks in the system tray. You can show cascading menus as a way of interacting with your program.
I don't have any fancy read with timeouts on this one.... yet...
I'll at least add a polling capability, a timeout value of 0. For now, there's just a Read call.
menu_def = ['&File', ['&Open', '&Save',['1', '2', ['a','b']], '&Properties', 'E&xit']]
tray = sg.SystemTray('My Tray', menu=menu_def, data_base64=logo)
while True:
menu_item = tray.Read()
print(menu_item)
if menu_item in (None, 'Exit'):
break
You can supply your icon in 3 different ways, same as the Image Element.
-
A filename
-
An in-ram image
-
A Base-64 image (my favorite because it doesn't require any other files)
For these types of applications in particular it seemed super important to support base-64 icons. These are PNG files by the file, not icons that we're dealing with. Although, I'm guessing if you fed it icons it would also work.
This is a feature that I will port over to Wx for sure. Tkinter doesn't have this capability built-in that I'm aware of.
You can get this release from the Master Branch. It's not been released to PyPI yet. This one is fresh off the line.
MikeTheWatchGuy 2018-11-25T02:32:39Z
0.15.0 Qt
If you're keeping count, yes, there have been TWO PyPI releases of PySimpleGUIQt today.
I had a bug that I wanted to get fixed right away and I really wanted to get this new SystemTray feature out there!
New SystemTray feature! Read about it in the Readme now
margin paramter for Text Element. Takes 4 ints
Corrected button colors when disabled. For now am restoring them to original colors
Border Depth for all elements that support it (inputs, slider, table, tree, etc)
Fix for Element padding done incorrectly!! Sorry about this one
MikeTheWatchGuy 2018-11-25T02:50:55Z
Windows users... you may need to perform a regedit in order to see system tray balloons
I had to add this registry key before I was able to see any notifications when running windows. Works great on Linux right out to the box.
MikeTheWatchGuy 2018-11-25T13:55:55Z
Menu keys (Qt) - You asked for it, you got it
Menus, on PySimpleGUIQt, now support KEYS.
To specify a key, insert a :: after the menu item, followed by your key value. This menu has keys on all items except for exit.
Menus also show up in the 'values' return values. If you get a menu item selected, the entire menu entry including the key is returned
In our above example, if "Open" were chosen in the GUI, then the event / value of the menu entry will be Open::KeyOpen
This way you will get back the maximum amount of information.
Should you not like the :: separator characters, you can change them by modifying the variable MENU_KEY_SEPARATOR
Note that the return values so not include the & character.
Enjoy!
Lesson in this feature, ask for features!
MikeTheWatchGuy 2018-11-25T21:42:32Z
0.16.0 Qt 3rd PyPI release today
Sorry for all the updates, but I've been kinda busy implementing stuff that I want to push out there because I've got a lot of Qt installs happening and want these features used and tested.
Easier forcing to use PyQt5 for testing
Predefined events for Tray Icons
-
Double Clicked
-
Icon Activated
-
Message Clicked
-
Timeout key for polling
Tray icon tooltip
Menu keys with programmable separator
Better element padding hierarchy
Menubar now returns values as does the ButtonMenu
MikeTheWatchGuy 2018-11-27T04:13:38Z
0.18.0 Qt
This has the completed SystemTray feature in it's entirety. I think it's officially "done" with nothing left to do. Other changes included in the release:
Tooltips for all elements
Completion of all SystemTray features
Read from SystemTray with or without timeout
Specify icons from 3 types of sources
Show message with custom or preset icons
Update
-
Menu
-
Tooltip
-
Icon
PopupScrolled - new location parameter, fixed bug that wasn't closing window when completed
MikeTheWatchGuy 2018-11-28T19:27:27Z
0.19.0 Qt
Big new thing - being able to mark menu items as disabled
Update methods fully completed for several more elements
Ability to disable menu items by adding ! to the front
Disable menu works for menus, button menus, sysytem tray menus
Combo - Update Method - Value, values, disabled, font
Listbox - Update Method - Values, disabled
Listbox - SetValue Method - sets the selected items
Radio Button - Update Method - value, disabled
Checkbox - Update Method - value, disabled
Spinner - Update Method - value, values, disabled
Spinner - change_submits works
Image - New feature! click_submits option (acts like a button in a way)
Window - Get screen dimensions
Slider - disable
Dial - disable
MikeTheWatchGuy 2018-11-29T23:33:23Z
PySimpleGUI Under The Hood
PySimpleGUI Architecture
PySimpleGUI is a "wrapper" for tkinter and Qt, with more on the way. Their are a number of "tricks" / architecture decisions that make this package appealing to both beginners and experienced GUI developers. Both will appreciate the simplicity. Simple doesn't mean shallow. There is considerable depth to the PySimpleGUI architecture.
What is it?
PySimpleGUI is a code-generator in many ways. When you get and configure a "Text Element (Widget)", PySimpleGUI makes exactly the same tkinter or Qt calls that a developer would.
Here is part of the code that is executed when you create a Text Widget.
element.QT_Label = qlabel = QLabel(element.DisplayText, toplevel_win.QTWindow)
if element.Justification is not None:
justification = element.Justification
elif toplevel_win.TextJustification is not None:
justification = toplevel_win.TextJustification
else:
justification = DEFAULT_TEXT_JUSTIFICATION
if justification[0] == 'c':
element.QT_Label.setAlignment(Qt.AlignCenter)
elif justification[0] == 'r':
element.QT_Label.setAlignment(Qt.AlignRight)
if not auto_size_text:
if element_size[0] is not None:
element.QT_Label.setFixedWidth(element_size[0])
if element_size[1] is not None:
element.QT_Label.setFixedHeight(element_size[1])
The "beauty" or PySimpleGUI is the code you see above was specified with this line of code
Text('Text', justification='left', size=(20,1))
You can see just how little effort it took to generate, and configure on your behalf, code that resembles hand-generated Qt code.
Architectural Decisions / Direction / Goals
-
Present a GUI interface that is not object oriented
-
Run an event loop within the user's application
-
Events (button clicks, keystrokes, menu choices, etc) are funneled through a single interface, Window.Read()
-
Users can use simple 'if' statements to act upon the GUIs events.... if this button press, do this.
-
There are no callbacks
-
-
Can change a widget's settings is a single call
-
Widget interaction is modeled simply, through simple widget updates
-
Change Widget A's value to value of Widget B is a single call
-
A widget's current value is returned in a dictionary when there is an event
-
-
Can duplicate nearly any window layout created by coding directly in tkinter/Qt.
-
Create complete documentation with a LOT of illustrations
-
Don't try to solve all GUI problems.
- Be the 80% of 80/20. Leave the difficult 20% to the major frameworks. Solve the other 80% of GUI problems.
This is the magic combination that is PySimpleGUI. It's a unique design that is approachable and enjoyable to use.
Window Definition
Widgets (Elements in PySimpleGUI-speak)
Creating widgets and placing them into a window definition is done with a single object, named appropriately in a simple manner. There are no "Label" widgets, but there is a "Text" one.
PySimpleGUI takes advantage of the Python named parameter feature. Object calls and methods are loaded up with lots of potential parameters. An IDE is a must. Let's look at a Text widget.
Text(text, size=(None, None), auto_size_text=None, click_submits=None, relief=None, font=None, text_color=None, background_color=None, justification=None, pad=None, margins=None, key=None, tooltip=None)
There are 13 different values and settings that can be specified when creating a Text widget. They are set when you create the widget, not several lines away.
The amount of code required to set those 13 values is certainly greater than 1 line of code per value. Closer to 2 or 3.
Not only are you setting the visible settings for a Text widget, but you're setting some behaviors. For example, enable_events
will cause this Text widget to inform the application when someone clicks on the text. In 1 parameter we've done the work of several lines of code dealing with callbacks. Callbacks are not something PySimpleGUI have to deal with. There are no callbacks.
Defining a Window
Break a window can be broken down into rows like this:
Then stack row "rows"up and you've got yourself a window.
If you were to break down the sketched out window into Widgets, you would get something like this:
"Filename"
Input Text, Browse for files
Ok button, Cancel button
To create PySimpleGUI from this, you simply make a list for each row and put those lists together.
Example Code - Simple Form-style Window
import PySimpleGUI as sg
layout = [[sg.Text('Filename')],
[sg.Input(), sg.FileBrowse()],
[sg.OK(), sg.Cancel()] ]
event, values = sg.Window('Get filename example').Layout(layout).Read()
Here is a complete program that will show the example window, get the values from the user.
That's all you need. It's "simple" after all.
Your layout
is a visual representation of your window. You can clearly see 3 rows of widgets being defined. If you would like your text to be red, then your layout would look like this:
layout = [[sg.Text('Filename', text_color='red')],
[sg.Input(), sg.FileBrowse()],
[sg.OK(), sg.Cancel()]]
Event Loops
Example Code - Window with Event Loop
The event loop in PySimpleGUI is where all the action takes place. There are no callbacks in PySimpleGUI. All of the code is located in 1 place, inside the loop.
Getting user input is achieved by calling Window.Read()
A typical call to Read:
event, values = sg.window.Read()
event
will be the event that happened. values are all of the window's widgets current values, in dictionary format.
Adding an event loop to the previous example results in this code:
import PySimpleGUI as sg
layout = [[sg.Text('Filename', text_color='red')],
[sg.Input(), sg.FileBrowse()],
[sg.OK(), sg.Cancel()]]
window = sg.Window('Get filename example').Layout(layout)
# The Event Loop
while True:
event, values = window.Read()
if event is None:
break
Within your event loop you take actions based on the event.
Let's say you want to print whatever is in the input field when the user clicks the OK button. The changed event loop is:
# The Event Loop
while True:
event, values = window.Read()
if event is None:
break
if event == 'OK':
print(values[0])
For buttons, when they are clicked, they return their text as the event, or you can set a "key" that will be what it returned to you when the button is clicked. Adding a key to our OK button is done by adding the key
parameter to the OK()
call.
sg.OK(key='_OK BUTTON_')
Now when the OK button is clicked, the event value will be _OK BUTTON_
.
Widget Interaction
Reading a widget
Any time that an event happens, you are provided a dictionary containing all of your widget's values.
event, values = window.Read()
Thevalues
return code is a dictionary of the widget's values. Adding a key
to the Input
widget will cause that key to be what is used to "loop up" the value of that widget in the values
variable.
If our Input
widget was changed to have a key:
sg.Input(key='_INPUT_')
Then the value for that input field can be obtained from the values
variable. The value of the Input widget in this case will be:
values['_INPUT_']
Changing a widget's value
Every widget has an Update
method that will the widget's value or settings.
To update an widget, you must first get the object. You can either save it in a variable when you create it or you can look up a widget by it's key. Remember widgets are called Elements in PySimpleGUI. To get the Input Element in the previous example, you could call Element
or FindElement
.
window.Element(key)
Once you have the element, then you can call the Update function:
window.Element(key).Update(value and settings)
Widget interaction
Building further on the key
idea and Updating widgets, let's look at an example where the text 'Filename' is replaced by whatever you type in the input box.
The basic logic:
If button == 'OK':
change text to input field's value
import PySimpleGUI as sg
layout = [[sg.Text('Filename', text_color='red', key='_TEXT_')],
[sg.Input(key='_INPUT_'), sg.FileBrowse()],
[sg.OK(key='_OK BUTTON_'), sg.Cancel()]]
window = sg.Window('Get filename example').Layout(layout)
# The Event Loop
while True:
event, values = window.Read()
if event is None:
break
if event == '_OK BUTTON_':
window.Element('_TEXT_').Update(values['_INPUT_'])
As you can see, the pseudo-code on the real code look very similar.
Note the statement if event is None
is what catches the user clicking the X to close the window. When the user does that, we want to exit the program by breaking from the event loop.
Async Designs
Asynchronous designs are possible using PySimpleGUI. To use async, add a timeout
parameter to the window.Read()
call.,
Example
Let's say you wanted to make a GUI that displays your latest emails, checking every 30 seconds. Rather than spin off a thread for the mail checker, run it within your GUI's event loop. Ideally we want the GUI to run as much as possible so that it's responsive. This is how it's accomplished
If you don't want to GUI to delay at all then set timeout=0. Setting timeout=0 will run in a completely non-blocked, async fashion.
Wrap-up
The overall architecture was meant to enable someone to duplicate both the GUI at a near-pixel-level and the behavior of a program written directly in the tkinter or Qt framework. PySimpleGUI provides a way of interacting with the native widgets in a more Python-friendly, novice-user-friendly manner. It is not meant for large, commercial applications. Those types of applications are in the 20% not covered by PySimpleGUI.
Portability
Both PySimpleGUI code and the PySimpleGUI package itself are highly portable. Taking a PySimpleGUI application from tkinter to Qt requires changing the import from import PySimpleGUI
to import PySimpleGUIQt
. That really is all that is typically required.
The PySimpleGUI module itself is highly portable too. Porting from tkinter to Qt took 1 week to get all of the widgets up and running with their basic operations.
MikeTheWatchGuy 2018-11-29T23:54:57Z
enable_events
There is a new parameter that has been added to all, or nearly all, Elements. It is a rename of the change_submits
parameter. The reason for this change is that I want all of the elements to have a common name and I wanted it to be descriptive. Now there's a direct correlation between reading events and enabling those events. This makes it clear you're enabling events from that Element.
You can still use change_submits
. The internal value is an 'or' of the two settings. I will be changing all of the sample code and all of the documentations to use this new variable. So that the old code will continue to function, the change_submits
parameter will be kept.
MikeTheWatchGuy 2018-11-30T00:39:40Z
Disabling Menus
This week's big feature is the ability to enable/disable menus as well as updating menus after the window has been created and is running.
You can use the Update method to change the menu definition for all versions of PySimpleGUI and for all Elements that use Menus. On Qt this means not only the Menubar, but also ButtonMenu and the SystemTray.
This should really help those applications that rely on menus as a primary form of user interaction.
Sorry it's taken so long to get to this one. Better late than never.
MikeTheWatchGuy 2018-12-01T21:12:55Z
Auto-Complete Input Text Box
I just helped a user implement an auto-complete input textbox.
It's a really fancy auto-complete with a pop-up window.
What's AMAZING and AWESOME about this demo is that the tkinter code and the Qt code is identical. Given the sophisticated behavior of the widgets, that's doing pretty good!
It's features like this one that drive new features (or drive the completion of features being ported). So, speak up when you have trouble or want to do something with PySimpleGUI that you can't figure out how to do. I'm likely to implement something to help you if it extends the package in a way that's in line with the overall charter.
In total, the implementation took 90 lines of code, although only about 70 of those are code.
Keep those ideas coming!
MikeTheWatchGuy 2018-12-02T19:39:52Z
3.17.0 2-Dec-2017
Tooltip offset now programmable. Set variable DEFAULT_TOOLTIP_OFFSET. Defaults to (20,-20)
Tooltips are always on top now
Disable menu items
Menu items can have keys
StatusBar Element (preparing for a real status bar in Qt)
enable_events parameter added to ALL Elements capable of generating events
InputText.Update select parameter will select the input text
Listbox.Update - set_to_index parameter will select a single items
Menus can be updated!
Menus have an entry in the return values
LayoutAndRead depricated
Multi-window support continues (X detection)
PopupScrolled now has a location parameter
row_height parameter to Table Element
Stretch Element (DUMMY) so that can be source code compatible with Qt
ButtonMenu Element (DUMMY) so can be source code compat with Qt. Will implement eventually
MikeTheWatchGuy 2018-12-02T21:47:53Z
Discord Channel
There's now a #PySimpleGUI-help
discord channel you can post your questions to.
https://discord.gg/HweJCcP
Discord has made it easy to copy and paste images and code. Be sure and surround your code with markdown formatting strings.
Put this on your first line: \```python
then paste your code
Then put this on the last line: ```
MikeTheWatchGuy 2018-12-03T16:23:39Z
Centering In Window Using Qt
Here's a PySimpleGUIQt trick for you.
This window done in PySimpleGUI-tkinter would involve a lot of 'padding'.
Using Stretch Elements in Qt it is an easy task.
The Stretch Element will "push" an element to one side or the other. To push a Button to the far right side of the window, put a Stretch to the left of it. To center elements, place a Stretch on both sides of the Element you wish to center.
The above code was made using this layout:
layout = [[sg.Stretch(), sg.Text('Add New Classes', font=("Helvetica", 25)), sg.Stretch()],
[sg.Stretch(), sg.Text('Course Code', font=("Helvetica", 15)), sg.Stretch()],
[ sg.Stretch(), sg.Input( size=(20, 2), ), sg.Stretch()],
[sg.Stretch(), sg.Text('Period Number', font=("Helvetica", 15)),sg.Stretch()],
[sg.Stretch(), sg.Input( size=(20, 2)), sg.Stretch()],
[sg.Stretch(), sg.Text('Year',font=("Helvetica", 15)), sg.Stretch(),],
[sg.Stretch(), sg.DropDown(('2016', '2017', '2018', '2019'), size=(12,2),font=("Helvetica", 15) ), sg.Stretch(),],
[sg.Stretch(), sg.ReadButton('Add Course', key='add_new_courses_button', size=(20, 2),
bind_return_key=True),sg.Stretch(),]
]
MikeTheWatchGuy 2018-12-03T18:39:57Z
Kivy
I couldn't stay away. Was too tempting.
Here's the first PySimpleGUIKivy program to run:
import PySimpleGUIKivy as sg
layout = [[sg.Text('My first Kivy Window!')]]
window = sg.Window('Title of first Kivy Window').Layout(layout)
window.Read()
It's a nothing window, but it's a huge first step. Real elements are being populated into a window and shown.
And to show that indeed the layout is being parsed, I did 2 lines:
import PySimpleGUIKivy as sg
layout = [[sg.Text('My first Kivy Window!')],
[sg.Text('A second line just to prove'), sg.Text('that it actually works')],]
window = sg.Window('Title of first Kivy Window').Layout(layout)
window.Read()
MikeTheWatchGuy 2018-12-04T21:52:58Z
Visible / Invisible Elements
I have just made changes to Qt, not yet checked in, that enable elements to be created invisible. They can also be made invisible/visible using their Update call.
I am unsure if I should have spent time on this technique or spent time on being able to "add" elements to a window.
Adding elements to a layout
The only way I've been able to come up with that this could work is for the user to define Column Elements that are populated later. I will need to add the ability to create a new column layout and to "finalize" it which is how the actual widgets get created and placed.
This will require a bit of work and I don't yet know if it's going to work nor be worth the effort.
What I'm lacking at the moment is a concrete example of a need. If someone has a program that will use this feature then I'm more likely to develop it. I need targets for features like this and at the moment one doesn't exist.
I don't know many examples from normal day to day programs that I can point to for inspiration.
Visibility extends to Columns and Frames
With the visibility code I'm going to check in soon, you can control an entire Frame or Column's visibility by Updating the Frame or Column. It will automatically hide all of the Elements inside of the container element.
MikeTheWatchGuy 2018-12-05T01:11:43Z
HowDoI Query of the Day
I use this tool all day every day and I learn some really clever things from it. Needed a way to change from Qt's color format to the PySimpleGUI color format. First try I got this clever way of turning a color tuple into a hex string.
I find it stunning how much is FREE these days. We are awash in tools and technologies that are at our fingertips, cheaply. The IDEs and toolchains are free. The GUI frameworks are free for most of us. There are little to no barriers to creativity now. It's a great time to be programming.
MikeTheWatchGuy 2018-12-06T01:22:37Z
Qt Tab Colors
I can finally check tabs off the list on Qt.
It took forever to get this one right. There remains an issue if you nest tabs where the border gets lost but hopefully you won't hit it. If you do, say something and I'll go back in there to see if I can fix it.
Qt is still in Alpha status. Some features are not fully complete. I'm working my way through them all, one at a time.
Tables and Graphs have gotten little attention and they need work, so be prepared if you use them.
I took a big hit when I created these invisible elements. It required hitting all of the elements and all of their Update methods. Plus I did it for part of the tkinter implementation.
MikeTheWatchGuy 2018-12-06T03:24:39Z
Self-Deprecating PySimpleGUI 3.17.1
Had an "emergency" patch go out today. It seems the PopupGetFolder crashes because it was calling LayoutAndRead, a function that was recently deprecated. Doh!
MikeTheWatchGuy 2018-12-06T14:18:14Z
Qt - size_px
Size in Pixels
For Qt, all elements now also have a parameter size_px
. This enables you to size your elements using either pixels or characters! Be aware, however, that using this parameter will cause your code to no longer run using tkinter as this is a Qt only feature.
I'm surprised no one has asked for the ability to size down to the pixel level. My conversion routing must not have been a bad guess. I needed to get down to the pixel level when I created a spinner consisting of items rather than integers. See #859.
MikeTheWatchGuy 2018-12-06T19:03:18Z
0.20.0 Qt
It's felt like I've been getting nothing done lately. Then I put together this Qt release and realized I got quite a bit done. I did all this AND got the Kivy port up and running, creating Text, Input and Button Elements on the screen.
Here are the release notes
-
Ability to change calculations between characters and pixels
-
size_px added to ALL elements that have a size parameter
-
General Element.Update(widget, background_color, text_color, font, visible)
-
visible parameter added to ALL elements
-
enable_events flag
-
Input text - enable events, visibility, size_px
-
Input text update added capabilities
-
ability to highlight the input string
-
background, text colors and font
-
-
Combo - enable events, visibility, size_px
-
Combo - auto complete feature
-
Combo - added to Update - background color, text color, font, visible
-
Listbox - enable events, visibility, size_px
-
Listbox - better scaling from characters to pixels
-
Listbox - ability to Update with set to index, text color, font, visibility
-
Radio - enable events, visibility, size_px
-
Radio - Update additions - background_color, text_color, font, visibility
-
Checkbox - enable events, visibility, size_px
-
Checkbox - Update additions - background_color, text_color, font, visibility
-
Spin - enable events, visibility, size_px
-
Spin - Update additions - background_color, text_color, font, visibility
-
Multiline input - enable events, visibility, size_px
-
Multiline input - Update additions - background_color, text_color, font, visibility
-
Multiline input better character to pixel scaling
-
Multiline output - enable events, visibility, size_px
-
Multiline output - Update additions - background_color, text_color, visibility
-
Text - enable events, size in pixels
-
Text - Update addition of visibility
-
Output - visible, size_px
-
Output - added update capablity with new value, background_color, text_color, font, visibility
-
Button - enable events, visible, size_px
-
Button - Color Chooser feature completed
-
Button - Color Chooser can target (None, None) which will store the value to be returned with the values from Read()
-
Button - fixed bug in SaveAs button code. Bad filter variable
-
Button - Updated added font, visibility
-
Button - new SetFocus() method will set the focus onto the button
-
ButtonMenu - Update method implemented that includes menu definition changes, text, button color, font, visibility
-
ProgressBar - added visibility, size_px
-
ProgressBar - added Update method for changing the visibility
-
Images - events, size_pix, visibility
-
Images - can now get click events for images!
-
Images - Update added visibility
-
Graph - visibility, size_px
-
Graph - Update method for changing visibility
-
Frame - visibility, size_px
-
Frame - Update method added that controls visibility
-
ALL elements inside of a Frame that's invisible will also be invisible
-
Tab - visible parameter added, however not yet functional!
-
TabGroup - enable events, visibility
-
TabGroup - Update for controlling visibility
-
Slider - enable events, size_px
-
Slider - Update method now includes visibility
-
Dial - enable events, size_px, visibility
-
Dial - Update method added visibilty control
-
Column - visibility added
-
Column - Added Update method to control visibility
-
ALL elements inside of an invisible Column Element will also be invisible
-
MenuBar - added visibility
-
MenuBar - Update can now change menu definitions at runtime, and control visibility
-
Table - enable events, size_px, visibility
-
Table - Update method can control visibility
-
Tree - enable events, size_px, visibility
-
Tree - Update method can control visibility
-
VisibilityChanged() function that must be called when using Qt so that the window will shrink or grow
-
window.GetScreenDimensions can now be called prior to window creation
-
window.Size property
-
enable_events added to all of the shortcut buttons and browse buttons
-
Ability to set a button image from a file
-
Combo - ability to set a default value
-
Combo - Readonly setting. Allows for user editing of value
-
Menus - Ability to disable / enable any part of a menu by adding a ! before the entry name
-
Tabs - ability to set tab text color, background color, background color of seletected tab
-
Tabs - ability to set widget area's background color
-
Sliders - paging works properly (using page-up page-down or slider slider area to advance slider)
-
Tree - Setting number of visible rows implemented
-
Added 5 pixels to every window. Have been having issues with text being cutoff on the right side
-
SetOptions - ability to change default error button color for popups
MikeTheWatchGuy 2018-12-07T00:07:11Z
If you downloaded a PySimpleGUI.py file from GitHub....
Don't forget to upgrade to the latest PyPI release by doing a pip install. If I fixed a problem or completed a feature while working on your problem and you downloaded a PySimpleGUI.py file from GitHub as a fix, you should delete the previously downloaded PySimpleGUI.py file and upgrade via pip to pick up your changes in the released version.
pip install --upgrade --no-cache-dir PySimpleGUI
MikeTheWatchGuy 2018-12-07T16:26:36Z
Filtered Listbox (Search)
import PySimpleGUI as sg
names = ['Roberta', 'Kylie', 'Jenny', 'Helen',
'Andrea', 'Meredith','Deborah','Pauline',
'Belinda', 'Wendy']
layout = [ [sg.Text('Listbox with search')],
[sg.Input(do_not_clear=True, size=(20,1),enable_events=True, key='_INPUT_')],
[sg.Listbox(names, size=(20,4), enable_events=True, key='_LIST_')],
[sg.Button('Chrome'), sg.Button('Exit')]]
window = sg.Window('Window Title').Layout(layout)
while True: # Event Loop
event, values = window.Read()
if event is None or event == 'Exit':
break
print(event, values)
if values['_INPUT_'] != '':
search = values['_INPUT_']
new_values = [x for x in names if search in x]
window.Element('_LIST_').Update(new_values)
else:
window.Element('_LIST_').Update(names)
if event == '_LIST_' and len(values['_LIST_']):
sg.Popup('Selected ', values['_LIST_'])
window.Close()
Just coded up this little gem for someone on Discord.
It will get a search term from an input field and use it to search and display a listbox. It's simple, easy, and elegant to do in PySimpleGUI.
Since it's only 28 lines of code it seemed worthy of being posted. I have no clue what it would take to do this same program in Qt, but I can tell you it's a lot more than 28 lines of code.
MikeTheWatchGuy 2018-12-08T01:56:02Z
DrawImage
for Graph Element
You can now add images to your Graph Element.
While creating a card game I encountered a problem. I wanted to show overlapping cards, but I was unable to do that using PySimpleGUI.
Here is a screenshot of the effect I was trying to achieve.
I could find no way to do this other than to add a new primitive to the Graph Element.
This capability means you can now show an image and collect clicks on that image, a potentially fantastic feature for the right application.
MikeTheWatchGuy 2018-12-08T02:03:30Z
Base64 Image Encoder
This is one for you perfectionists out there that want the cool buttons that can be embedded in your Python script.
This utility / demo program will take a folder full of PNGs and turn them into a single Python source file, output.py
. In that file you will find variables that are the same as the filename. All you have to do is call the PySimpleGUI image related functions using the parameter data
. The data
parameter can be found in the Image Element, Button Element and now in the Graph.DrawImage primitive. In Qt you'll find it identified with a 64 in the variable name.
Here is how I drew the 2 card you see in the prior post:
Elem('_GRAPH_').DrawImage(data=b2, location=(0,0))
Elem('_GRAPH_').DrawImage(data=r2, location=(100,40))
The variable r2 is the red 2 card and b2 is the blue 2 card, both in base 64.
The call to Elem is a new technique I'm using that utilizes a lambda to shorten things. It is simply defined as:
Elem = lambda key: window.Element(key)
Think of it as a simple copy and paste. Instead of Elem
, paste in window.Element
. That is all it's doing, replacing a bunch of text.
MikeTheWatchGuy 2018-12-08T02:19:39Z
Shortcuts using Lambda
I've really been getting into making the code more compact by using lambda expressions. I know, scary stuff.... but not the way I'm using them.
Think of Lambda as "function" or "def" because it's just like a def in many ways.
For programs that Update a lot of elements, there's a lot of copying or typing involved. Every time you must call:
window.FindElement('key)
before you adding .Update(values)
Even if you use the new shorter version it's still a lot of text:
window.Element('key')
Check out the magic of this:
Elem = lambda key: window.Element(key)
After that assignment, I can use Elem
like this:
Elem('key').Update(values)
Nice, right?
Look at that lambda for a moment. Everything before the : are parameters. After the : are the statements in the "Function". It's just like writing:
The same trick can be used for creating Elements that have long, complex parameter values. Maybe all of your buttons need to be the same size (12,1) and use Helvetica size 14 font and the color is white on blue.
You can write that as this:
sg.Button('text', size=(12,1), font='Helvetica 14', button_color=('white', 'blue'))
If you have 10 of those to do, then for sure use this technique. You can create a MyButton type:
MyButton = lambda text: sg.Button(text, size=(12,1), font='Helvetica 14', button_color=('white', 'blue'))
Then in the layout all you have to specify is:
MyButton('Custom text')
You can get fancier and allow more fields to be specified, with default values, etc.
I learned this technique by reading one of the users' code. You can learn a lot by reading code. I highly recommend doing it.
MikeTheWatchGuy 2018-12-08T18:14:19Z
Window element_padding
on PySimpleGUI and CurrentLocation()
on PySimpleGUIQt
Just completed forward and back-porting features between PySimpleGUI and PySimpleGUIQt. Maintaining the features across 2 platforms is proving to be challenging.
One way I'm forcing the issue is to try my best to get Demo programs to run on both PySimpleGUI and PySimpleGUIQt by only changing the import
statement.
Today I ported the pop-up touch keyboard back and forth. I had 2 versions, one for tk, the other Qt. Now there's a single version that works equally well. To do this, each platform needed some functionality available only on the other platform.
I can't imagine the headaches that are coming when I add Kivy and Wx. Oy!
Here is the touch keyboard running on tkinter and Qt. Only 1 line change to move between the 2 frameworks.
The element_padding
parameter is a particularly good one to have. Now instead of calling SetOptions
to change the padding, you can do it when you create the window. It also keeps the scope at the window level. Using SetOptions
changes the padding for all windows, including things like Popups.
MikeTheWatchGuy 2018-12-09T22:24:49Z
Qt Window.Move, Window.Minimize, Window.Disable
, ProgressMeters
Just finished up the Window implementation, except for the disable_close
parameter. I added the Move, Minimize, Disable.
There was also work done on Progress Meters. You can set custom colors now! The vertical orientation works now too.
As you can see, there are still feature implementations that are not yet completed on PySimpleGUIQt. I'm adding them as quickly as I can and am trying to update the docs with the changes too. Plus I'm adding new features if needed by a user and the feature fits with PySimpleGUI.
How to research problems
When you get to something that you're not able to guess parameter names, look in the documentation. Here's the order I recommend people research parameters or function names:
-
The main user documentation (he Readme) - http://www.PySimpleGUI.org
-
If running Qt, also check the Qt docs - https://github.com/MikeTheWatchGuy/PySimpleGUI/tree/master/PySimpleGUIQt
-
The code itself - PyCharm users control click on the function name and check the function definition.
-
SDK Quick Ref - There is a demo program that shows the function definitions. Warning that it can get a little out of date.
If you check those 3 locations and don't find the answer, by all means post an Issue and it'll get addressed quickly. I may or may not be able to do something to fix the problem, but I'll look into whatever is happening.
This package is on a fast-track. I apologize if the docs are lagging or if a feature is not yet complete. Doing my best to keep the features coming.
MikeTheWatchGuy 2018-12-10T00:30:37Z
Qt 0.21.0
0.21.0 - 9-Dec-2018
-
Removed use of global variabels - using static class variabels instead
-
Listbox.Get() will return current listbox value
-
Progressbar now has color support
-
Progressbar can be vertical now
-
Can change bar or back and background color
-
(barcolor, background color - None if use default)
-
Table num_rows parameter implemented
-
Table.Update - can change number of visible rows
-
Window resizable parm - implemented, default changed from False to True
-
Window.Move - implemented
-
Window.Minimize - implemented
-
Window.Disable - implemented
-
Window.Enable - implemented
-
Window.CurrentLocation - implemented
-
Fixed too small scrollbar in Combobox
-
Fixed too small scrollbar in Listbox
-
Changed "text" window to a complex one for quick regression testing (try running PySimpleGUIQt.py by itself)
MikeTheWatchGuy 2018-12-10T00:36:40Z
Qt 0.22.0
- Spin.Get method - get the current value of the spinner
Forgot to add that one in.
MikeTheWatchGuy 2018-12-11T18:24:39Z
3.18.0 & 1.18.0
If you are running a custom PySimpleGUI.py file, delete it and upgrade to the latest release
pip install --upgrade --no-cache-dir PySimpleGUI
It feels like a risky-ish release. There is a lot in this release. Please report issues. Hopefully your feature made it into the release
Noteworthy items
-
Visibility touched every element and every element's Update method.
-
I changed some internal architecture, moved globals into class variables.
-
Completely replaced the OneLineProgressMeter code. Started from scratch. The code condensed nicely and is much more elegant. Also provides a reason code if you want to know why the meter gave an "end" return code (cancelled, closed with X, reached max count).
-
Menus are broken in version 2.7. You really shouldn't be on legacy Python anyway.
-
Visibility - can be used to create "dynamic" windows. Elements can come and go. On this tkinter release they only seem to grow. Once you show a widget that space is reserved for it.
-
Graphs can have images! Great for games.
-
Clickable images
-
Debug window pops back up after you close it if you call sg.Print again. Previously it defaulted back to the console.
-
Can set the padding at the Window level using new Window parameter
-
NOTE - Menus are broken on version 2.7. Don't know how long they've been this way.
-
Default progress bar length changed to shorter
-
Master window and tracking of num open windows moved from global to Window class variable
-
Element visibility setting (when created and when Updating element)
-
Input text visiblity
-
Combo visiblity
-
Combo replaces InputCombo as the primary class name
-
Option menu visibility
-
Listbox visiblity
-
Listbox new SetFocus method
-
Radio visibility
-
Checkbox visibility
-
Spin visiblity
-
Spin new Get method returns current value
-
Multiline visiblity
-
Text visibility
-
StatusBar visiblity
-
Output visibility
-
Button visibility
-
Button SetFocus
-
ProgressBar - New Update method (used only for visibility)
-
Image - clickable images! enable_events parameter
-
Image visibility
-
Canvas visibility
-
Graph visibility
-
Graph - new DrawImage capability (finally)
-
Frame visibility
-
Tab visibility (may not be fully functional)
-
TabGroup visibility
-
Slider visibility
-
Slider - new disable_number_display parameter
-
Column visibilty
-
Menu visibility - Not functional
-
Table visibility
-
Table - new num_rows parm for Update - changes number of visible rows
-
Tree visiblity
-
Window - New element_padding parameter will set padding for entire window
-
OneLineProgressMeter - Completely REPLACED the implementation
-
OneLineProgressMeter - can get reason for the cancellation (cancel button versus X)
-
EasyProgressMeter - completely removed. Use OneLineProgressMeter instead
-
Debug window, EasyPrint, Print - debug window will re-open if printed to after being closed
-
SetOptions - can change the error button color
-
Much bigger window created when running PySimpleGUI.py by itself. Meant to help with regression testing
MikeTheWatchGuy 2018-12-13T02:20:17Z
Uno On PySimpleGUI
Instead of working dutifully on the outstanding Qt issues, I spent that past couple of days coding up this Uno game. I borrowed the game engine from a text based version of the game.
What I wanted to demonstrate were these 2 things.
-
PySimpleGUI can be used to make games
-
You can store graphic files, a good number of them, inside your code.
I mentioned earlier that I wrote a base64 image converter that will encode a folder full of PNGs into a single .py source file. The reason I wrote that utility was for this game. I needed to convert 100 PNG files to base64 so doing it by hand was not an option.
I still need to finish up some polishing and I want to properly cite where I got the code as well as where the image files originated. Once I get those together, I'll release it officially.
My hope is to release this on ActiveState, the place I found the text based version.
Feedback is most welcomed!
MikeTheWatchGuy 2018-12-13T02:47:00Z
Lambda Update
GUIs of all types can be wordy. While creating the Uno card game I ended up making a number of lambda expressions to cut down, significantly, the amount of code I had to write.
For programs that do a lot of updating of elements on the screen, I'm going to likely be showing more and more of these lambda expressions in the demo programs.
This one in particular is handy:
This allows you to write:
Update(key, value)
and it will do the same thing as if you called:
window.Element(key).Update(value)
When you have a dozen or more of these to do in your window then it makes sense do use a lambda instead of copying and pasting. For one thing it allows you to change a single line of code instead of dozens of lines of code.
I also created one for Text elements:
Then I can write:
T('My text')
and my text will be Helvetica 16 sized automatically. I was using it with keys a lot too which is why you see the key argument. To make a text element with a key value:
T('Player', '_P3_')
The **kwargs makes it possible to add on as many of the Text parameters as I want such as visibility:
T('Cards', '_C3_', visible=False)
Here's a chunk of the layout definition so you can see it in action:
col_players = [
[OvalButton('Quit', greenbutton, key='_QUIT_', visible=False)],
[T('Player', '_P1_', text_color=yellow_color)],
[T('Cards', '_C1_', text_color=yellow_color)],
[T(' ' * 15)],
[T('Player', '_P2_', text_color=red_color)],
[T('Cards', '_C2_', text_color=red_color)],
[T(' ' * 15,'_S3_', visible=False,)],
[T('Player', '_P3_', visible=False)],
[T('Cards', '_C3_', visible=False)],
[T(' ' * 15, '_S4_', visible=False,)],
[T('Player', '_P4_', visible=False)],
[T('Cards', '_C4_', visible=False)],]
Note that you don't need to add sg.
to the front of these too.
I realize that the code looks a bit foreign compared to other PySimpleGUI code, but I think it's worth the time savings and ease of modifying things in a centralized way.
MikeTheWatchGuy 2018-12-13T14:37:39Z
Uno game "complete"
I am close enough to being "done" to call it "done". Is a program ever truly done?
I posted about it here on Reddit (should you want to upvote for example ;-)
https://www.reddit.com/r/Python/comments/a5tzhq/uno_card_game_using_a_gui_pysimplegui/
Here is what the final version looks like:
MikeTheWatchGuy 2018-12-13T16:11:52Z
3.19.2 13-Dec-2018
-
Warning for Mac's when trying to change button color
-
New parms for Button.Update - image_size and image_subsample
-
Buttons - remove highlight when border depth == 0
-
OneLineProgressMeter - better layout implementation
I completely forgot when I released Uno today that I needed new features from PySimpleGUI. So, I dashed out this release... actually 3 released today. Solved a problem with outlines around buttons in Linux. Gives me an idea of what may be wrong with checkboxes.
MikeTheWatchGuy 2018-12-14T20:57:17Z
Pane Element
It's been a while since a new element was implemented. Just when I think I've got them all.
I didn't know what the tkinter "Paned Window" was until recently. I don't know quite how to integrate them into a GUI. I haven't seen one in any other applications that I can think of. It feels like a mobile app widget.
If you want to try yourself, you'll find the changes in the Master Branch on GitHub.
Here is one in action.
One of the input elements is updating the other. Each are in a different “pane”. One is nested inside of the other.
The rule is:
A Pane Element takes a list of panes. A pain is defined as a Column element. So, the Pane Element takes a list of Column Elements as the input.
import PySimpleGUI as sg
col1 = sg.Column([[sg.Text('in pane1')],
[sg.T('Pane1')],
[sg.T('Pane1')],
])
col2 = sg.Column([[sg.Text('in pane2')],
[sg.T('Pane2')],
[sg.Input(key='_IN2_', do_not_clear=True)],
[sg.T('Pane2')],
[sg.T('Pane2')],
])
col3 = sg.Column([[sg.Text('test')],
[sg.In(key='_IN3_', enable_events=True, do_not_clear=True)],
])
layout = [ [sg.Text('Click'), sg.Text('', key='_OUTPUT_')],
[sg.Button('Go')],
[sg.Pane([sg.Column([[sg.Pane([col1, col2], orientation='v', background_color=None, show_handle=True, visible=True, key='_PANE_', relief=sg.RELIEF_SUNKEN),]]),col3 ], orientation='h', background_color=None, size=(160,120), relief=sg.RELIEF_RIDGE)]
]
window = sg.Window('Window Title', default_element_size=(15,1)).Layout(layout)
while True: # Event Loop
event, values = window.Read()
print(event, values)
if event is None or event == 'Exit':
break
if event == 'Go':
window.Element('_PANE_').Update(visible=True)
window.Element('_IN2_').Update(values['_IN3_'])
window.Close()
MikeTheWatchGuy 2018-12-18T18:17:00Z
John Conway's Game of Life
If you're a fan of 1970's computing, then you know Conway's "Game of Life". This implementation wraps the engine in a PySimpleGUI GUI. You setup the initial board, click "Go" and watch the fun.
You can change the speed and number of generations parameters on the fly. There are some pretty wild patterns that have been "Discovered" and documented.
You place blocks by clicking. To delete a block, click it.
You will need a new PySimpleGUI.py file to run this as the new DeleteFigure is needed (to delete the blocks). This is exactly why I write these demo programs, to move forward the SDK. DeleteFigure is needed for a variety of programs so it's good to get it done and available for people to use.
This runs on tkinter at the moment.
Will push the PySimpleGUI.py file up to PyPI quickly so that only a pip install is required.
MikeTheWatchGuy 2018-12-18T22:20:44Z
3.20.0 & 1.20.0 18-Dec-2018
-
New Pane Element
-
Graph.DeleteFigure method
-
disable_minimize - New parameter for Window
-
Fix for 2.7 menus
-
Debug Window no longer re-routes stdout by default
-
Can re-route by specifying in Print / EasyPrint call
-
New non-blocking for PopupScrolled
-
Can set title for PopupScrolled window
The big features for this release are the new Pane Element, menu fix for 2.7, and delete figure needed for game of life.
MikeTheWatchGuy 2018-12-18T22:38:23Z
http://www.conwaylife.com/wiki/Conway%27s_Game_of_Life
MikeTheWatchGuy 2018-12-21T01:07:35Z
Mixing tkinter and Qt
It just dawned on me that it's possible to mix tkinter and Qt windows in the same application. Of course you cannot put Qt widgets into a tkinter window and vice versa, but you can have windows from both frameworks up on the screen at the same time, interacting.
Maybe there's a feature only available in Qt that you need for one of your screen, but are fine with tkinter for rest of your application.
import PySimpleGUI as sg
import PySimpleGUIQt as sgqt
layout = [ [sg.Text('Type here for display in Qt window:')],
[sg.Input(do_not_clear=True, enable_events=True, key='_IN_')],
[sg.Button('Show'), sg.Button('Exit')]]
window = sg.Window('tkinter Window').Layout(layout)
layout2 = [ [sgqt.Text('This is a Qt Window')],
[sgqt.Text(' ', key='_OUTPUT_')],
[sgqt.Button('Show'), sgqt.Button('Exit'), sgqt.Stretch()]]
window2 = sgqt.Window('Qt Window').Layout(layout2).Finalize()
while True: # Event Loop
event, values = window.Read()
if event is None or event == 'Exit':
break
window2.FindElement('_OUTPUT_').Update(values['_IN_'])
window2.Refresh()
window.Close()
MikeTheWatchGuy 2018-12-21T16:14:27Z
ButtonMenus for PySimpleGUI (tkinter version)
I finally got off my ass and completed the ButtonMenu Element for tkinter. It's been around for Qt for some time now.
I did this reacting to the Issue posted here #961 .
It enables you to have menus that match the background. You should be able to put an image on these buttons.
What is NOT yet completed is the ability to update the colors of the button. You can update the menu definition however, just like in Qt. In Qt I don't believe it's possible to change the button text and colors either. Of course, if that's a problem in your application, post an issue.
If you haven't noticed, it's the users of PySimpleGUI that often dictate the priorities of features. If something is impossible and should be possible, I'm likely to do something about it.
I am quite aware of the number of outstanding issues at the moment. The Qt port is still in Alpha condition, awaiting the completion of all of the Elements' features and configurations. Every day it's a little bit closer however, so have faith that it'll get done.
MikeTheWatchGuy 2018-12-21T20:00:12Z
Bar Charts
Ever wanted to graph some data but don't have the time to learn Matplotlib?
How about a simple bar chart using PySimpleGUI instead.
I wrote this little program in response to a Reddit question:
import PySimpleGUI as sg
import random
BAR_WIDTH = 50
BAR_SPACING = 75
EDGE_OFFSET = 3
GRAPH_SIZE = (500,500)
DATA_SIZE = (500,500)
graph = sg.Graph(GRAPH_SIZE, (0, 0), DATA_SIZE)
layout = [[sg.Text('Bar graphs using PySimpleGUI')],
[graph],
[sg.Button('OK')]]
window = sg.Window('Window Title').Layout(layout)
while True:
event, values = window.Read()
graph.Erase()
if event is None:
break
for i in range(7):
graph_value = random.randint(0, 400)
graph.DrawRectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, graph_value),
bottom_right=(i * BAR_SPACING + EDGE_OFFSET + BAR_WIDTH, 0), fill_color='blue')
graph.DrawText(text=graph_value, location=(i*BAR_SPACING+EDGE_OFFSET+25, graph_value+10))
Every time you click OK, you get a new random chart.
The entire program can be boiled down to a single statement:
graph.DrawRectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, graph_value),
bottom_right=(i * BAR_SPACING + EDGE_OFFSET + BAR_WIDTH, 0), fill_color='blue')
A "bar" in a bar chart is nothing more than a rectangle. This statement draws a bar chart. The size of the bar is same as the value being graphed (graph_value
)
The beauty of the Graph Element is that when you define it, you define the coordinate system you'll be using. This make graphing stuff super simple. Tell the DrawRectangle primitive the value of your data and it'll take care of translating it into the pixel sizes to be plotted on the screen. You get to live in your data's coordinate system, not the tkinter canvas pixel dimensions.
MikeTheWatchGuy 2018-12-22T20:13:23Z
Right Click Menus! NEW for PySimpleGUI-tk
While working on the new ButtonMenu feature I discovered that tkinter has "popup" menus that I can assign to widgets.
You won't be able to modify the menu after you've assigned it to an element, but at least you'll one menu. I'll look at doing Updates to these menus later when someone has a real use for them and needs to be able to modify the menu.
You can set it on these elements:
text, image, canvas, graph, column, frame, table, tree
If you set it for the window when calling Window
, it will automatically assign that menu to all occurrences of elements that support menu. It's as close to a global menu setting as I can get.
Note this is for the tkinter version of PySimpleGUI. I'll look into what it'll take to port to Qt.
Here's a trick for you.... if you want your entire window's background to have a right click menu, then place your layout into a Column element that has the right click menu enabled.
I'm open to expanding this feature if someone has a solid use case for it. So far no one has asked for this feature, but it was somewhat easy to implement so I went ahead and added it.
MikeTheWatchGuy 2018-12-22T21:30:07Z
PySimpleGUIWx version 0.0.1
It's official.... I started on the WxPython port.
This test window demonstrates what's operational. The buttons aren't hooked up yet, but the rest of the window functions as it should. Even managed to set the icon correctly.
While it's checked into GitHub, it won't do you a lot of good since the only thing it does at the moment is display windows like this one. No return values are sent back because buttons are not yet operational.
I have to say that programming using Wx is pretty awesome. They have a debug tool that's AMAZING. It runs in parallel with your application window. I am able to "browse" the widgets I've created, highlight them on my window and examine all of its settings. It's invaluable as 1/2 the battle is understanding what setting can be changed.
I can see why people enjoy working with it. Wx has a lot of well-written documentation and there are tons of sample programs. It would be awesome if Python could adopt Wx on a permanent basis and make it available automatically.
MikeTheWatchGuy 2018-12-22T22:01:07Z
Sample Application Using Custom Graphics
I wanted to share this application I wrote this afternoon. It's a betting application that I'm using in another project. PySimpleGUI made making this application downright trivial. It would have taken me quite a while to do it in C# and I'm guessing the amount of code would have been significantly more.
There is a lesson to be learned here for people that want to make their tkinter PySimpleGUI programs look better.
This application uses custom graphics for the check mark where you choose the bet and the up/down arrows. I could have used a "spinner" to input the amount to bet, but it would have looked like one of those GUIs from the 90's.
It was super easy to make these custom spinner. I simply put the PNG files into a folder, ran the Base64 converter program, copied and pasted the resulting code into my code and then referenced the buttons as base64 variables when I created the up/down buttons.
MikeTheWatchGuy 2018-12-24T16:26:28Z
System Tray Icon (from Wx)
The System Tray Icon feature from Qt is awesome. If you've not played with it, I highly suggest you give it a try. There are demo programs that make it super easy to use.
Here is how I use it:
I scrape the GitHub site for Issues and show the current count, most recently updated issue in the menu. I also provide a "quick launch" capability to do things like make a pull request, or launch Discord.
It's a fantastic way to quickly get to your most frequent tasks without launching a browser first and then choosing a destination.
However, if you're a tkinter user you do not have this option available. BUT, soon you'll be able to run the WxPython version.
So why does this matter? Why would you want to use WxPython version of something over Qt.
The reason is around the size of the EXE file created by PyInstaller and the overall memory usage. Qt is rather HUGE by comparison. When I compile a PySimpleGUI program using tkinter it's about 9 MB in size, with WxPython it's 11 MB and with Qt it's 240 MB. Clearly Qt is an issue.
What I'm suggesting is that if you want to use a system tray icon and you're not a Qt user, then use the soon to be released Wx version. I'm hoping to get it written today.
I really like the idea of being able to mix and match these different GUI frameworks! It's my hope that an application can launch windows using any of the 3 GUI frameworks. I'm particularly excited about mixing Wx and tkinter in the same application as I've outlined here.
Watch for the announcement today for System Tray icons. PySimpleGUIWx may be usable starting today! Wow, that would be exciting.
MikeTheWatchGuy 2018-12-26T22:07:59Z
0.2.0 PySimpleGUIWx
This release is a pretty much feature complete SystemTray implementation! It's source code compatible with the Qt System Tray implementation, the only choice up until now.
I've switched my GitHub Issues Watcher system tray application over from Qt To Wx and it's working beautifully.
This 0.2.0 release has all the features expected, the ability to hide the icon, detect message clicks, etc.
You'll find 3 demo programs that show how to use the SystemTray object.
MikeTheWatchGuy 2018-12-27T23:36:24Z
0.3.0 PySimpleGUIWx
I didn't think I was going to do much more, but ended up hooking up buttons, read with timeout, etc, so that pop-ups are functioning!
Windows are already useful and can be combined with the SystemTray.
0.3.0 - 27-Dec-2018
-
Hooked up buttons!
-
Browse file button is only file/folder button that works
-
Text, Input and Button elements are the only working elements
-
SystemTray can take any kind of image as icon
-
Read with Timeout (non-zero) works
-
Popups
MikeTheWatchGuy 2018-12-29T02:16:11Z
3.21.0 28-Dec-2018
-
ButtonMenu Element
-
Embedded base64 default icon
-
Input Text Right click menu
-
Disabled Input Text are now 'readonly' instead of disabled
-
Listbox right click menu
-
Multiline right click menu
-
Text right click menu
-
Output right click menu
-
Image right click menu
-
Canvas right click menu
-
Graph right click menu
-
Frame right click menu
-
Tab, tabgroup right click menu (unsure if works correctly)
-
Column right click menu
-
Table right click menu
-
Tree right click menu
-
Window level right click menu
-
Window icon can be filename or bytes (Base64 string)
-
Window.Maximize method
-
Attempted to use Styles better with Combobox
-
Fixed bug blocking setting bar colors in OneLineProgressMeter
MikeTheWatchGuy 2018-12-30T17:58:13Z
PySimpleGUI(Tk) New features on GitHub
There has been some nice stuff tossed into the tkinter PySimpleGUI that you may be interested in. Not yet on PyPI.
-
Ability to set the size of a Column - should really help with making lined up layouts easy
-
Tables now have optional horizontal scrollbar. It's turned off by default.
MikeTheWatchGuy 2018-12-30T18:16:57Z
0.4.0 PySimpleGUIWx
-
Text Element - colors, font work
-
Text Update method works
-
Button - Close button implemented
-
Button - Implemented basic button, correctly presented Values on Read
-
Button - Can now set font
-
Changed overall "App" variable usage for better mainloop control
-
Windows - Timeouts and non-blocking Reads work
-
Windows - Autoclose works
-
Windows - Non-blocking calls supported (timeout=0)
-
Windows - Grab anywhere works
-
Windows - No title-bar works
-
Windows - Location and Size working correctly
-
Correctly adding element padding to Text, Input, Buttons
-
Popups - most Popups work (except for the input type that involve folders)
This is a sizable update to PySimpleGUIWx. You can do most all of the Popup calls, including the ones without title bars or are non-blocking or auto-closing.
MikeTheWatchGuy 2018-12-30T18:37:04Z
PySimpleGUIWx Development Strategy
While it may look like chaotic development, there is method to the madness.
First, if you haven't noticed, I'm attentive to the Issue list and what users are doing that may need assistance. The package has been extended, often, with the help of programmers building their applications. When PySimpleGUI is lacking in an area simply because it hasn't been fully developed, I'm more likely to work on that if someone is using it. So, be vocal with your requests.
Second, there's a Wx port in the mix. Yea, I know, Qt isn't "done" so why Wx? The reason is that I am not seeing a lot of problems reported by Qt users. It's "good enough" at this point. I'm an 80% person. But will finish the other 20% if there's an active need. The reason for adding Wx is that it is the "happy middle" between tkinter and Qt.
Wx brings with it features that tkinter doesn't have but could use. The System Tray is the obvious one. Further down the road the more complex Elements are likely going to be coming from Wx. There are some nice ones I'm eyeing such as speedometers.
I'm bringing up Wx in chunks that are usable immediately. The system tray is "done" but I'm sure people will want icons on the menus, etc. It's a solid working, basic system tray icon.
The cool thing about Wx and tkinter is that they can run side-by-side. There is no restriction on running a WxPython system tray with tkinter windows.
But, I am trying to get the WxPython windows operational too, starting with the Popups. The idea here is to provide the high-level APIs so that users an begin to use them right away. Some people don't need fully-custom windows so why not build something that's useful right away?
While creating the Popup windows, I'm also developing the core Window features like changing location, sizing, etc These features are represented by the parameters to popup. Get Popup fully operational and I'll have a good number of Window features completed because you can set things like no titlebar in a popup call.
I think it's a useful strategy to be working from. There have been over 1,100 installs of PySimpleGUIWx already. That's pretty amazing considering the tiny amount of features that have been completed.
I also try to push features out the door quickly and often. There have been 4 released of PySimpleGUIWx in the past 5 days, each pretty beefy.
Frequent releases get the cool new things into the hands of users quickly and also gets run-time on the package. I'm finding it difficult to get enough traffic pulling releases from GitHub that I really have to release to PyPI if I want any testing done at all on the releases.
It's crazy but the results speak for themselves. I see a good number of happy users.
MikeTheWatchGuy 2018-12-30T18:43:40Z
GitHub Migration
I'm planning on migrating the PySimpleGUI project over to another GitHub account. I want it to live in a standalone location. The new account is called... wait for it....
PySimpleGUI
That will make the location of the software:
https://github.com/PySimpleGUI/PySimpleGUI
I'm targeting Jan 1 to make the change.
Evidently GitHub will provide forwarding links, for people period of time.
I recommend people use http://www.PySimpleGUI.com when wanting to get to the PySimpleGUI GitHub page as that URL will always point to the current GitHub repository. http://www.PySimpleGUI.org will get you the latest documentation.
MikeTheWatchGuy 2018-12-31T20:33:55Z
PySimpleGUI Feature Matrix
This is what I'm working from while developing PySimpleGUIWx and finishing PySimpleGUIQt.
MikeTheWatchGuy 2019-01-02T00:05:13Z
New Year's news
Migration to new GitHub
We're now live at:
https://github.com/PySimpleGUI/PySimpleGUI
GitHub will automatically forward people that try to use the old addresses.
I recommend using http://www.PySimpleGUI.com as it'll point to the right place.
By the numbers....100,000
There have been 100,000 (ok, 99,000 but it'll be 100K by tomorrow) pip installs of PySimpleGUI, when you add together the 4 packages representing 3 ports, PySimpleGUI, PySimpleGUI27, PySimpleGUIQt, PySimpleGUIWx
I have no clue how that number translates into anything real. How many installs happen daily that are automated and how many are brand new users? Who knows.
Also recently passed the 1,000 stars mark. This one has some meaning behind it as no robots are at work, only people, when it comes to stars. 1,000 people indicating this is a good package does have some statistical value.
6 months.... the amount of time PySimpleGUI has been released.
deajan 2019-01-02T20:08:40Z Wow... a paper feature matrix... Long time no see :)
Happy new year and happy 100k downloads of PysimpleGUI.
MikeTheWatchGuy 2019-01-03T15:18:04Z
100,000 Installs
Yesterday the total number of Pip installs for PySimpleGUI, all versions, reached 100,052.
It's a milestone of sorts, reaching the "first" 100K. It's not very useful on its own, but is good if you're comparing other packages that also have this stat as well as comparing the PySimpleGUI versions.
The rate of installs, per week:
PySimpleGUI 2,000
PySimpleGUIQt 3,000
PySimpleGUI27 1,400
PySimpleGUIWx 1,300
MikeTheWatchGuy 2019-01-05T16:32:34Z
Wx - Visibility
Working through the feature matrix. Working to get Input, Button, and Text done, solidly. This way the features that are available to users should work. A good number won't work until I get around to fixing whatever is causing the issue.
It takes Voodoo to get these Frameworks to autosize windows. Each are different and some are weird, but eventually the job does get done.
This demo shows a window that starts with several Elements invisible.
If you want you element to be invisible from the start, you will not be able to do that using the Visible parameter. You will instead Finalize
your window and then make Update
calls to set the ones you want to be invisible.
If you do not use this 2-step method, then you will get a messed up background when the window expands. Here's an example of setting the visible flag to False.
MikeTheWatchGuy 2019-01-06T21:30:59Z
0.5.0 PySimpleGUIWx 6-Jan-2019
-
New element - Multiline input
-
New element - Multiline output
-
Borderless Windows
-
Grab anywhere windows
-
Alpha channel for windows
-
Finishing up the Text and Input Text Elements
-
Visibilty for all Elements
-
Input Get / Set focus
-
Output element - unable to get stdout to re-route
-
Debug window works
Uploaded this latest release to PyPI today.
It's getting there!
MikeTheWatchGuy 2019-01-06T22:28:30Z
Feature matrix cont...
The problem is that there are actually 3 answers per square, not just 1.
MikeTheWatchGuy 2019-01-07T00:08:06Z
Measuring speed of packages & ease of porting.
https://youtu.be/kn-vqgLPR_E
It's getting even more fun with Wx coming onto the scene.
Check out the Color_Names demo program!
Qt and Wx both loaded in 2 or 3 seconds. Tkinter took 4 or 5 seconds. It's a noticeable difference.
Three different frameworks available by simply changing the import statement. Ease of changing between the packages == how long it takes to change two letters. This super-quick time to move between frameworks is a benefit/feature that had never dawned on me before.
All 3 performed great at this program, popping up multiple windows, tooltips, spacing of buttons.
MikeTheWatchGuy 2019-01-09T01:02:11Z
One Line Progress Meter - Wx
Almost all of the high level interfaces into PySimpleGUIWx are done (Popups, Debug Print, Progress Meter). So if Wx is your favorite and all you need are simple popups, then you should perhaps consider trying it out.
In order to implement the progress meter, I needed to complete the Text, Column and Progress Bar elements.
I recommend grabbing a version from the Master Branch as the changes take a little while to get to PyPI.
MikeTheWatchGuy 2019-01-09T16:11:34Z
PySimpleGUIWx 0.6.0 - The "it's coming together" release
Wx is coming together fairly quickly.
I'm following a strategy of bringing up features and functions an element at a time, but, in an order that enables certain applications. For Example, the HowDoI application is one of the first to bring up. It requires a Multiline Input, Output, Buttons, No titlebar Grab Anywhere.
The System Tray application that scrapes GitHub Issues and launches some applications Also works.
Next up will be the Launcher button-bar that I run that runs programs and scripts at the push of a button.
I also focused on the high-level features set.... the Popups, Debug Window and the Progress Meter. Those too required certain features - autoclose, Output element, multi-windows, progress meter, async windows, in addition to features already listed.
If you have an application that you would like to run on PySimpleGUIWx but the port has not supplied you with all of the required features, open an Issue. It helps me guide the effort
0.6.0 9-Jan-2019
-
Column Element
-
Checkbox Element with events
-
Output Element
-
Background Image (I think works)
-
Debug Print
-
One Line Progress Meter
-
All Popups works
------------ complete and ready to use ------------
Elements:
-
Text
-
Input Text
-
Buttons including file/folder browse
-
Input multiline
-
Outputmultiline
-
Output
-
Columns
-
Progress Meters
Features
-
Windows & System Tray
-
Debug Print
-
All Popups
-
Check box
-
Keyboard key events
-
Mouse wheel events
-
Multiple windows
-
Async windows
-
Read with timeout
-
Background images
-
One Line Progress Meter (tm)
-
Autoclosing windows
-
No titlebar windows
-
Grab anywhere windows
-
Default Icon
-
Base64 Icons
MikeTheWatchGuy 2019-01-09T21:31:47Z
The PySimpleGUI Logo
Now that the PySimpleGUI logo is included with the source file you're more likely to have seen it. The code isn't on PyPI yet for the main PySimpleGUI.py file, but it's been on GitHub for a while now.
Here's a reminder of how it looks:
I'm curious how many people have not noticed that it's the Python logo turned on it's head. Prior to using it I looked on the net and I wasn't able to find any images like it. None. No posts where someone has used the Python logo in this way. Doing an "image search" on Google and Bing brought up no matches. I'm surprised no one at least did it once and posted it.
I like it because it resembles the letters "SG" (as in Simple GUI).... at least that was the idea.
Hey, can't be a 'thing'without a name and a logo, right?
MikeTheWatchGuy 2019-01-11T13:57:10Z
Docs stored only on GitHub
I'm now storing the docs only on the GitHub site. Previously I had local copies that I would work from and check in. This will enable everyone to access the most up to date documents.
MikeTheWatchGuy 2019-01-11T15:46:02Z
Trees with Icons
Finally there's a match between how trees on PySimpleGUI and PySimpleGUIQt behave.... sorta....
Checked in a new Tree Element Demo program that displays a directory structure with a little folder icon for each folder.
Using PySimpleGUI the code produces this window:
PySimpleGUIQt produces this window:
It would appear that the Qt implementation does not yet have "values" that you can set on each entry. On the tkinter version I've added the file size for each entry.
If you are developing a program using PySimpleGUIQt that uses trees and you need to store values, just post an Issue and it'll get implemented.
What continues to amaze me is that the exact same source code produced those 2 windows. PySimpleGUI code continues to be source code compatible between the GUI frameworks. I fully expect and so far have seen PySimpleGUIWx code be compatible. It's an exciting time to be working with PySimpleGUI.
MikeTheWatchGuy 2019-01-12T17:36:23Z
PySimpleGUIWx Get Comboboxes and Radio Buttons
Nailed two more elements last night.... complete with colors, sizes, events and updates.
Here's a summary window of the Elements that are up and running.
Not visible is the Column Element which enables just about any layout.
MikeTheWatchGuy 2019-01-12T17:38:50Z
WxPython thoughts....
I'm liking WxPython!
It's very consistent in how the widgets are configured and how you interact with them. The result is that I'm able to properly get the colors and styles right without weird side effects. With tkinter the combobox element still isn't able to be correctly styled and sometimes looks pretty dated. Not so with the PySimpleGUIWx combobox. It looks great.
The only downside I've experienced with WxPython so far has been the Linux installation. It was hell and feel like it's going to be a barrier to entry.
It may be that the PySimpleGUIWx users are pretty much limited to windows but that's still a large number of users.
My hope is that I'm going to be able to do a better job with tables and trees using WxPython and that I also am going to be able to use the exciting advanced widgets like Speedometers!! It would be cool to be able to use custom widgets that are available on the net.
While WxPython is the most comfortable of the GUI frameworks I've used so far, it's far far away from being beginner "friendly". It's barely "intermediate friendly". While I wish it could become the standard for Python, there's still an enormous gap for beginners.
If only these GUI frameworks offered a parallel SDK to their primary SDK that is more like PySimpleGUI.
It's clearly possible to offer an alternate interface to the same underlying objects in a way that's more user friendly. I'm surprised it's not been done or isn't being done now.
Given how approachable Python bills itself as, why isn't the GUI programming also approachable?
MikeTheWatchGuy 2019-01-12T19:12:26Z
Black
Trying the latest coding fad by running PySimpleGUIWx through the black code reformatting tool. The only option I turned off was "normalizing quotes". I like single quotes and it would have converted everything to double quotes.
It's "interesting". It will make documenting the element objects easier as it formats init calls by putting each parameter on a separate line.
For example, it reformatted the Window class definition to this:
def __init__(
self,
title,
default_element_size=DEFAULT_ELEMENT_SIZE,
default_button_element_size=(None, None),
auto_size_text=None,
auto_size_buttons=None,
location=(None, None),
size=(None, None),
element_padding=None,
button_color=None,
font=None,
progress_bar_color=(None, None),
background_color=None,
border_depth=None,
auto_close=False,
auto_close_duration=None,
icon=DEFAULT_BASE64_ICON,
force_toplevel=False,
alpha_channel=1,
return_keyboard_events=False,
use_default_focus=True,
text_justification=None,
no_titlebar=False,
grab_anywhere=False,
keep_on_top=False,
resizable=True,
disable_close=False,
disable_minimize=False,
background_image=None,
):
It's a lot easier to read, but it means scrolling through a LOT more pages of code. It pushed the number of lines of code from 6,985 to 9,368! YIKES!
It also modified the window layout code in an unexpected way:
BEFORE
def main():
# ChangeLookAndFeel('Black')
layout = [[Text('TEXT1',tooltip='Tooltip'), Text('TEXT2', )],
[Text('You should be importing it rather than running it', justification='l', size=(50, 1))],
[Text('Here is your sample input window....')],
[Text('Source Folder', size=(15, 1), justification='right'), InputText('Source', focus=True),
FileBrowse()],
[Text('Destination Folder', size=(15, 1), justification='right'), InputText('Dest'), FolderBrowse()],
[Button('Ok')]]
window = Window('Demo window..',
default_element_size=(35,1),
auto_size_text=True,
auto_size_buttons=True,
no_titlebar=False,
disable_close=False,
disable_minimize=True,
grab_anywhere=True,
).Layout(layout)
event, values = window.Read()
print(event, values)
window.Close()
AFTER
def main():
# ChangeLookAndFeel('Black')
layout = [
[Text('TEXT1', tooltip='Tooltip'), Text('TEXT2')],
[
Text(
'You should be importing it rather than running it',
justification='l',
size=(50, 1),
)
],
[Text('Here is your sample input window....')],
[
Text('Source Folder', size=(15, 1), justification='right'),
InputText('Source', focus=True),
FileBrowse(),
],
[
Text('Destination Folder', size=(15, 1), justification='right'),
InputText('Dest'),
FolderBrowse(),
],
[Button('Ok')],
]
window = Window(
'Demo window..',
default_element_size=(35, 1),
auto_size_text=True,
auto_size_buttons=True,
no_titlebar=False,
disable_close=False,
disable_minimize=True,
grab_anywhere=True,
).Layout(layout)
event, values = window.Read()
print(event, values)
window.Close()
The verdict is that it's great for Class definitions, but completely and totally f's up thePySimpleGUI window layouts. What was readable and matched the screen became nothing more than code and lines of parameter (yuck).
Not sure where that leaves the PySimpleGUIWx.py code itself.
MikeTheWatchGuy 2019-01-13T17:41:01Z
3.22.0 PySimpleGUI 1.22.0 PySimpleGUI27
-
Added type hints to some portions of the code
-
Output element can be made invisible
-
Image sizing and subsample for Button images
-
Invisibility for ButtonMenus
-
Attempt at specifying size of Column elements (limited success)
-
Table Element
-
New row_colors parameter
-
New vertical_scroll_only parameter - NOTE - will have to disable to get horizontal scrollbars
-
Tree Element
-
New row_height parameter
-
New feature - Icons for tree entries using filename or Base64 images
-
Fix for bug sending back continuous mouse events
-
New parameter silence_on_error for FindElement / Element calls
-
Slider returns float now
-
Fix for Menus when using Python 2.7
-
Combobox Styling (again)
MikeTheWatchGuy 2019-01-15T15:06:04Z
GitHub Private Repositories Are Now Free
I heard this news on the Python Bytes podcast (has fantastic, practical, stuff you can use). Previously if you wanted a private project, you had to pay a monthly fee. Now private projects are free up to a certain number of developers (I think 3).
Not surprisingly, GitHub didn't send me anything about the change.
MikeTheWatchGuy 2019-01-16T22:09:51Z
3.23.0 1.23.0 16-Jan-2019
A surprise release of animated GIFs!
No one has asked for this one in a while. I want to be able to offer an indeterminate progress bar, essentially a "loading" indicator. Spinners, donuts, progress bars,... There are some real fun ones that I'm finding that I'll also be posting.
-
Animated GIFs!
-
Calendar Chooser stays on top of other windows
-
Fixed bug of no column headings for Tables
-
Tables now use the font parameter
MikeTheWatchGuy 2019-01-16T22:10:30Z
A GIFt to you....
import PySimpleGUI as sg
gif103 = b'R0lGODlhoAAYAKEAALy+vOTm5P7+/gAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCQACACwAAAAAoAAYAAAC55SPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvHMgzU9u3cOpDvdu/jNYI1oM+4Q+pygaazKWQAns/oYkqFMrMBqwKb9SbAVDGCXN2G1WV2esjtup3mA5o+18K5dcNdLxXXJ/Ant7d22Jb4FsiXZ9iIGKk4yXgl+DhYqIm5iOcJeOkICikqaUqJavnVWfnpGso6Clsqe2qbirs61qr66hvLOwtcK3xrnIu8e9ar++sczDwMXSx9bJ2MvWzXrPzsHW1HpIQzNG4eRP6DfsSe5L40Iz9PX29/j5+vv8/f7/8PMKDAgf4KAAAh+QQJCQAHACwAAAAAoAAYAIKsqqzU1tTk4uS8urzc3tzk5uS8vrz+/v4D/ni63P4wykmrvTjrzbv/YCiOZGliQKqurHq+cEwBRG3fOAHIfB/TAkJwSBQGd76kEgSsDZ1QIXJJrVpowoF2y7VNF4aweCwZmw3lszitRkfaYbZafnY0B4G8Pj8Q6hwGBYKDgm4QgYSDhg+IiQWLgI6FZZKPlJKQDY2JmVgEeHt6AENfCpuEmQynipeOqWCVr6axrZy1qHZ+oKEBfUeRmLesb7TEwcauwpPItg1YArsGe301pQery4fF2sfcycy44MPezQx3vHmjv5rbjO3A3+Th8uPu3fbxC567odQC1tgsicuGr1zBeQfrwTO4EKGCc+j8AXzH7l5DhRXzXSS4c1EgPY4HIOqR1stLR1nXKKpSCctiRoYvHcbE+GwAAC03u1QDFCaAtJ4D0vj0+RPlT6JEjQ7tuebN0qJKiyYt83SqsyBR/GD1Y82K168htfoZ++QP2LNfn9nAytZJV7RwebSYyyKu3bt48+rdy7ev378NEgAAIfkECQkABQAsAAAAAKAAGACCVFZUtLK05ObkvL68xMLE/v7+AAAAAAAAA/5Yutz+MMpJq7046827/2AojmRpYkCqrqx6vnBMAcRA1LeN74Ds/zGabYgjDnvApBIkLDqNyKV0amkGrtjswBZdDL+1gSRM3hIk5vQQXf6O1WQ0OM2Gbx3CQUC/3ev3NV0KBAKFhoVnEQOHh4kQi4yIaJGSipQCjg+QkZkOm4ydBVZbpKSAA4IFn42TlKEMhK5jl69etLOyEbGceGF+pX1HDruguLyWuY+3usvKyZrNC6PAwYHD0dfP2ccQxKzM2g3ehrWD2KK+v6YBOKmr5MbF4NwP45Xd57D5C/aYvTbqSp1K1a9cgYLxvuELp48hv33mwuUJaEqHO4gHMSKcJ2BvIb1tHeudG8UO2ECQCkU6jPhRnMaXKzNKTJdFC5dhN3LqZKNzp6KePh8BzclzaFGgR3v+C0ONlDUqUKMu1cG0yE2pWKM2AfPkadavS1qIZQG2rNmzaNOqXcu2rdsGCQAAIfkECQkACgAsAAAAAKAAGACDVFZUpKKk1NbUvLq85OLkxMLErKqs3N7cvL685Obk/v7+AAAAAAAAAAAAAAAAAAAABP5QyUmrvTjrzbv/YCiOZGmeaKqubOuCQCzPtCwZeK7v+ev/KkABURgWicYk4HZoOp/QgwFIrYaEgax2ux0sFYYDQUweE8zkqXXNvgAQgYF8TpcHEN/wuEzmE9RtgWxYdYUDd3lNBIZzToATRAiRkxpDk5YFGpKYmwianJQZoJial50Wb3GMc4hMYwMCsbKxA2kWCAm5urmZGbi7ur0Yv8AJwhfEwMe3xbyazcaoBaqrh3iuB7CzsrVijxLJu8sV4cGV0OMUBejPzekT6+6ocNV212BOsAWy+wLdUhbiFXsnQaCydgMRHhTFzldDCoTqtcL3ahs3AWO+KSjnjKE8j9sJQS7EYFDcuY8Q6clBMIClS3uJxGiz2O1PwIcXSpoTaZLnTpI4b6KcgMWAJEMsJ+rJZpGWI2ZDhYYEGrWCzo5Up+YMqiDV0ZZgWcJk0mRmv301NV6N5hPr1qrquMaFC49rREZJ7y2due2fWrl16RYEPFiwgrUED9tV+fLlWHxlBxgwZMtqkcuYP2HO7Gsz52GeL2sOPdqzNGpIrSXa0ydKE42CYr9IxaV2Fr2KWvvxJrv3DyGSggsfjhsNnz4ZfStvUaM5jRs5AvDYIX259evYs2vfzr279+8iIgAAIfkECQkACgAsAAAAAKAAGACDVFZUrKqszMrMvL683N7c5ObklJaUtLK0xMLE5OLk/v7+AAAAAAAAAAAAAAAAAAAABP5QyUmrvTjrzbv/YCiOZGmeaKqubOuCQSzPtCwBeK7v+ev/qgBhSCwaCYEbYoBYNpnOKABIrYaEhqx2u00kFQCm2DkWD6bWtPqCFbjfcLcBqSyT7wj0eq8OJAxxgQIGXjdiBwGIiokBTnoTZktmGpKVA0wal5ZimZuSlJqhmBmilhZtgnBzXwBOAZewsAdijxIIBbi5uAiZurq8pL65wBgDwru9x8QXxsqnBICpb6t1CLOxsrQWzcLL28cF3hW3zhnk3cno5uDiqNKDdGBir9iXs0u1Cue+4hT7v+n4BQS4rlwxds+iCUDghuFCOfFaMblW794ZC/+GUUJYUB2GjMrIOgoUSZCCH4XSqMlbQhFbIyb5uI38yJGmwQsgw228ibHmBHcpI7qqZ89RT57jfB71iFNpUqT+nAJNpTIMS6IDXub5BnVCzn5enUbtaktsWKSoHAqq6kqSyyf5vu5kunRmU7L6zJZFC+0dRFaHGDFSZHRck8MLm3Q6zPDwYsSOSTFurFgy48RgJUCBXNlkX79V7Ry2c5GP6SpYuKjOEpH0nTH5TsteISTBkdtCXZOOPbu3iRrAadzgQVyH7+PIkytfzry58+fQRUQAACH5BAkJAAwALAAAAACgABgAg1RWVKSipMzOzNze3Ly6vNTW1OTm5MTCxKyqrOTi5Ly+vNza3P7+/gAAAAAAAAAAAAT+kMlJq7046827/2AojmRpnmiqrmzrvhUgz3Q9S0iu77wO/8AT4KA4EI3FoxKAGzif0OgAEaz+eljqZBjoer9fApOBGCTM6LM6rbW6V2VptM0AKAKEvH6fDyjGZWdpg2t0b4clZQKLjI0JdFx8kgR+gE4Jk3pPhgxFCp6gGkSgowcan6WoCqepoRmtpRiKC7S1tAJTFHZ4mXqVTWcEAgUFw8YEaJwKBszNzKYZy87N0BjS0wbVF9fT2hbczt4TCAkCtrYCj7p3vb5/TU4ExPPzyGbK2M+n+dmi/OIUDvzblw8gmQHmFhQYoJAhLkjs2lF6dzAYsWH0kCVYwElgQX/+H6MNFBkSg0dsBmfVWngr15YDvNr9qjhA2DyMAuypqwCOGkiUP7sFDTfU54VZLGkVWPBwHS8FBKBKjTrRkhl59OoJ6jjSZNcLJ4W++mohLNGjCFcyvLVTwi6JVeHVLJa1AIEFZ/CVBEu2glmjXveW7YujnFKGC4u5dBtxquO4NLFepHs372DBfglP+KtvLOaAmlUebgkJJtyZcTBhJMZ0QeXFE3p2DgzUc23aYnGftaCoke+2dRpTfYwaTTu8sCUYWc7coIQkzY2wii49GvXq1q6nREMomdPTFOM82Xhu4z1E6BNl4aELJpj3XcITwrsxQX0nnNLrb2Hnk///AMoplwZe9CGnRn77JYiCDQzWgMMOAegQIQ8RKmjhhRhmqOGGHHbo4YcZRAAAIfkECQkADQAsAAAAAKAAGACDVFZUrKqs1NbUvL685ObkxMbE3N7clJaUtLK0xMLE7O7szMrM5OLk/v7+AAAAAAAABP6wyUmrvTjrzbv/YCiOZGmeaKqubOu+VSDPdD1LQK7vvA7/wFPAQCwaj4YALjFIMJ3NpxQQrP4E2KxWSxkevuBwmKFsAJroZxo9oFrfLIFiTq/PBV3DYcHv+/kHSUtraoUJbnCJJ3J8CY2PCngTAQx7f5cHZDhoCAGdn54BT4gTbExsGqeqA00arKtorrCnqa+2rRdyCQy8vbwFkXmWBQvExsULgWUATwGsz88IaKQSCQTX2NcJrtnZ2xkD3djfGOHiBOQX5uLpFIy9BrzxC8GTepeYgmZP0tDR0xbMKbg2EB23ggUNZrCGcFwqghAVliPQUBuGd/HkEWAATJIESv57iOEDpO8ME2f+WEljQq2BtXPtKrzMNjAmhXXYanKD+bCbzlwKdmns1VHYSD/KBiXol3JlGwsvBypgMNVmKYhTLS7EykArhqgUqTKwKkFgWK8VMG5kkLGovWFHk+5r4uwUNFFNWq6bmpWsS4Jd++4MKxgc4LN+owbuavXdULb0PDYAeekYMbkmBzD1h2AUVMCL/ZoTy1d0WNJje4oVa3ojX6qNFSzISMDARgJuP94TORJzs5Ss8B4KeA21xAuKXadeuFi56deFvx5mfVE2W1/z6umGi0zk5ZKcgA8QxfLza+qGCXc9Tlw9Wqjrxb6vIFA++wlyChjTv1/75EpHFXQgQAG+0YVAJ6F84plM0EDBRCqrSCGLLQ7KAkUUDy4UYRTV2eGhZF4g04d3JC1DiBOFAKTIiiRs4WIWwogh4xclpagGIS2xqGMLQ1xnRG1AFmGijVGskeOOSKJgw5I14NDDkzskKeWUVFZp5ZVYZqnllhlEAAAh+QQJCQAMACwAAAAAoAAYAINUVlSkoqTMzszc3ty8urzU1tTk5uTEwsSsqqzk4uS8vrzc2tz+/v4AAAAAAAAAAAAE/pDJSau9OOvNu/9gKI5kaZ5oqq5s674pIM90PUtIru+8Dv/AE+CgOBCNxaMSgBs4n9DoABGs/npY6mQY6Hq/XwKTgRgkzOdEem3WWt+rsjTqZgAUAYJ+z9cHFGNlZ2ZOg4ZOdXCKE0UKjY8YZQKTlJUJdVx9mgR/gYWbe4WJDI9EkBmmqY4HGquuja2qpxgKBra3tqwXkgu9vr0CUxR3eaB7nU1nBAIFzc4FBISjtbi3urTV1q3Zudvc1xcH3AbgFLy/vgKXw3jGx4BNTgTNzPXQT6Pi397Z5RX6/TQArOaPArWAuxII6FVgQIEFD4NhaueOEzwyhOY9cxbtzLRx/gUnDMQVUsJBgvxQogIZacDCXwOACdtyoJg7ZBiV2StQr+NMCiO1rdw3FCGGoN0ynCTZcmHDhhBdrttCkYACq1ivWvRkRuNGaAkWTDXIsqjKo2XRElVrtAICheigSmRnc9NVnHIGzGO2kcACRBaQkhOYNlzhwIcrLBVq4RzUdD/t1NxztTIfvBmf2fPr0cLipGzPGl47ui1i0uZc9nIYledYO1X7WMbclW+zBQs5R5YguCSD3oRR/0sM1Ijx400rKY9MjDLWPpiVGRO7m9Tx67GuG8+u3XeS7izeEkqDps2wybKzbo1XCJ2vNKMWyf+QJUcAH1TB6PdyUdB4NWKpNBFWZ/MVCMQdjiSo4IL9FfJEgGJRB5iBFLpgw4U14IDFfTpwmEOFIIYo4ogklmjiiShSGAEAIfkECQkADQAsAAAAAKAAGACDVFZUrKqs1NbUvL685ObkxMbE3N7clJaUtLK0xMLE7O7szMrM5OLk/v7+AAAAAAAABP6wyUmrvTjrzbv/YCiOZGmeaKqubOu+aSDPdD1LQK7vvA7/wFPAQCwaj4YALjFIMJ3NpxQQrP4E2KxWSxkevuBwmKFsAJroZxo9oFrfLIFiTq/PBV3DYcHv+/kHSUtraoUJbnCJFWxMbBhyfAmRkwp4EwEMe3+bB2Q4aAgBoaOiAU+IE4wDjhmNrqsJGrCzaLKvrBgDBLu8u7EXcgkMw8TDBZV5mgULy83MC4FlAE8Bq9bWCGioEgm9vb+53rzgF7riBOQW5uLpFd0Ku/C+jwoLxAbD+AvIl3qbnILMPMl2DZs2dfESopNFQJ68ha0aKoSIoZvEi+0orOMFL2MDSP4M8OUjwOCYJQmY9iz7ByjgGSbVCq7KxmRbA4vsNODkSLGcuI4Mz3nkllABg3nAFAgbScxkMpZ+og1KQFAmzTYWLMIzanRoA3Nbj/bMWlSsV60NGXQNmtbo2AkgDZAMaYwfSn/PWEoV2KRao2ummthcx/Xo2XhH3XolrNZwULeKdSJurBTDPntMQ+472SDlH2cr974cULUgglNk0yZmsHgXZbWtjb4+TFL22gxgG5P0CElkSJIEnPZTyXKZaGoyVwU+hLC2btpuG59d7Tz267cULF7nXY/uXH12O+Nd+Yy8aFDJB5iqSbaw9Me6sadC7FY+N7HxFzv5C4WepAIAAnjIjHAoZQLVMwcQIM1ApZCCwFU2/RVFLa28IoUts0ChHxRRMBGHHSCG50Ve5QlQgInnubKfKk7YpMiLH2whYxbJiGHjFy5JYY2OargI448sDEGXEQQg4RIjOhLiI5BMCmHDkzTg0MOUOzRp5ZVYZqnlllx26SWTEQAAIfkECQkADAAsAAAAAKAAGACDVFZUpKKkzM7M3N7cvLq81NbU5ObkxMLErKqs5OLkvL683Nrc/v7+AAAAAAAAAAAABP6QyUmrvTjrzbv/YCiOZGmeaKqubOu+cAfMdG3TEqLvfL/HwCAJcFAcikcjcgnIDZ7QqHSAEFpfvmx1Qgx4v2AwoclADBLnNHqt3l7fKfNU6mYAFAGCfs/XBxRkZmhqhGx1cCZGCoqMGkWMjwcYZgKVlpcJdV19nAR/gU8JnXtQhwyQi4+OqaxGGq2RCq8GtLW0khkKtra4FpQLwMHAAlQUd3mje59OaAQCBQXP0gRpprq7t7PYBr0X19jdFgfb3NrgkwMCwsICmcZ4ycqATk8E0Pf31GfW5OEV37v8URi3TeAEgLwc9ZuUQN2CAgMeRiSmCV48T/PKpLEnDdozav4JFpgieC4DyYDmUJpcuLIgOocRIT5sp+kAsnjLNDbDh4/AAjT8XLYsieFkwlwsiyat8KsAsIjDinGxqIBA1atWMYI644xnNAIhpQ5cKo5sBaO1DEpAm22oSl8NgUF0CpHiu5vJcsoZYO/eM2g+gVpAmFahUKWHvZkdm5jCr3XD3E1FhrWyVmZ8o+H7+FPsBLbl3B5FTPQCaLUMTr+UOHdANM+bLuoN1dXjAnWBPUsg3Jb0W9OLPx8ZTvwV8eMvLymXLOGYHstYZ4eM13nk8eK5rg83rh31FQRswoetiHfU7Cgh1yUYZAqR+w9adAT4MTmMfS8ZBan5uX79gmrvBS4YBBGLFGjggfmFckZnITUIoIAQunDDhDbkwMN88mkR4YYcdujhhyCGKOKIKkQAACH5BAkJAA0ALAAAAACgABgAg1RWVKyqrNTW1Ly+vOTm5MTGxNze3JSWlLSytMTCxOzu7MzKzOTi5P7+/gAAAAAAAAT+sMlJq7046827/2AojmRpnmiqrmzrvnAXzHRt0xKg73y/x8AgKWAoGo9IQyCXGCSaTyd0ChBaX4KsdrulEA/gsFjMWDYAzjRUnR5Ur3CVQEGv2+kCr+Gw6Pv/fQdKTGxrhglvcShtTW0ajZADThhzfQmWmAp5EwEMfICgB2U5aQgBpqinAVCJE4ySjY+ws5MZtJEaAwS7vLsJub29vxdzCQzHyMcFmnqfCwV90NELgmYAUAGS2toIaa0SCcG8wxi64gTkF+bi6RbhCrvwvsDy8uiUCgvHBvvHC8yc9kwDFWjUmVLbtnVr8q2BuXrzbBGAGBHDu3jjgAWD165CuI3+94gpMIbMAAEGBv5tktDJGcFAg85ga6PQm7tzIS2K46ixF88MH+EpYFBRXTwGQ4tSqIQymTKALAVKI1igGqEE3RJKWujm5sSJSBl0pPAQrFKPGJPmNHo06dgJxsy6xUfSpF0Gy1Y2+DLwmV+Y1tJk0zpglZOG64bOBXrU7FsJicOu9To07MieipG+/aePqNO8Xjy9/GtVppOsWhGwonwM7GOHuyxrpncs8+uHksU+OhpWt0h9/OyeBB2Qz9S/fkpfczJY6yqG7jxnnozWbNjXcZNe331y+u3YSYe+Zdp6HwGVzfpOg6YcIWHDiCzoyrxdIli13+8TpU72SSMpAzx9EgUj4ylQwIEIQnMgVHuJ9sdxgF11SiqpRNHQGgA2IeAsU+QSSRSvXTHHHSTqxReECgpQVUxoHKKGf4cpImMJXNSoRTNj5AgGi4a8wmFDMwbZQifBHUGAXUUcGViPIBoCpJBQonDDlDbk4MOVPESp5ZZcdunll2CGKaYKEQAAIfkECQkADAAsAAAAAKAAGACDVFZUpKKkzM7M3N7cvLq81NbU5ObkxMLErKqs5OLkvL683Nrc/v7+AAAAAAAAAAAABP6QyUmrvTjrzbv/YCiOZGmeaKqubOu+cAzMdG3TEqLvfL/HwCAJcFAcikcjcgnIDZ7QqHSAEFpfvmx1Qgx4v2AwoclADBLnNHqt3l7fKfNU6mYAFAGCfs/XBxRkZmxsaml1cBJGCoqMGkWMjwcai5GUChhmApqbmwVUFF19ogR/gU8Jo3tQhwyQlpcZlZCTBrW2tZIZCre3uRi7vLiYAwILxsfGAgl1d3mpe6VOaAQCBQXV1wUEhhbAwb4X3rzgFgfBwrrnBuQV5ufsTsXIxwKfXHjP0IBOTwTW//+2nWElrhetdwe/OVIHb0JBWw0RJJC3wFPFBfWYHXCWL1qZNP7+sInclmABK3cKYzFciFBlSwwoxw0rZrHiAIzLQOHLR2rfx2kArRUTaI/CQ3QwV6Z7eSGmQZcpLWQ6VhNjUTs7CSjQynVrT1NnqGX7J4DAmpNKkzItl7ZpW7ZrJ0ikedOmVY0cR231KGeAv6DWCCxAQ/BtO8NGEU9wCpFl1ApTjdW8lvMex62Y+fAFOXaswMqJ41JgjNSt6MWKJZBeN3OexYw68/LJvDkstqCCCcN9vFtmrCPAg08KTnw4ceAzOSkHbWfjnsx9NpfMN/hqouPIdWE/gmiFxDMLCpW82kxU5r0++4IvOa8k8+7wP2jxETuMfS/pxQ92n8C99fgAsipAxCIEFmhgfmmAd4Z71f0X4IMn3CChDTloEYAWEGao4YYcdujhhyB2GAEAIfkECQkADQAsAAAAAKAAGACDVFZUrKqs1NbUvL685ObkxMbE3N7clJaUtLK0xMLE7O7szMrM5OLk/v7+AAAAAAAABP6wyUmrvTjrzbv/YCiOZGmeaKqubOu+cBzMdG3TEqDvfL/HwCApYCgaj0hDIJcYJJpPJ3QKEFpfgqx2u6UQD+CwWMxYNgDONFSdHlSvcJVAQa/b6QKv4bDo+/99B0pMbGuGCW9xFG1NbRqNkANOGpKRaRhzfQmanAp5EwEMfICkB2U5aQgBqqyrAVCJE4yVko+0jJQEuru6Cbm8u74ZA8DBmAoJDMrLygWeeqMFC9LT1QuCZgBQAZLd3QhpsRIJxb2/xcIY5Aq67ObDBO7uBOkX6+3GF5nLBsr9C89A7SEFqICpbKm8eQPXRFwDYvHw0cslLx8GiLzY1bNADpjGc/67PupTsIBBP38EGDj7JCEUH2oErw06s63NwnAcy03M0DHjTnX4FDB4d7EdA6FE7QUd+rPCnGQol62EFvMPNkIJwCmUxNBNzohChW6sAJEd0qYWMIYdOpZCsnhDkbaVFfIo22MlDaQ02Sxgy4HW+sCUibAJt60DXjlxqNYu2godkcp9ZNQusnNrL8MTapnB3Kf89hoAyLKBy4J+qF2l6UTrVgSwvnKGO1cCxM6ai8JF6pkyXLu9ecYdavczyah6Vfo1PXCwNWmrtTk5vPVVQ47E1z52azSlWN+dt9P1Prz2Q6NnjUNdtneqwGipBcA8QKDwANcKFSNKu1vZd3j9JYOV1hONSDHAI1EwYl6CU0xyAUDTFCDhhNIsdxpq08gX3TYItNJKFA6tYWATCNIyhSIrzHHHiqV9EZhg8kE3ExqHqEHgYijmOAIXPGoBzRhAgjGjIbOY6JCOSK5ABF9IEFCEk0XYV2MUsSVpJQs3ZGlDDj50ycOVYIYp5phklmnmmWRGAAAh+QQJCQAMACwAAAAAoAAYAINUVlSkoqTMzszc3ty8urzU1tTk5uTEwsSsqqzk4uS8vrzc2tz+/v4AAAAAAAAAAAAE/pDJSau9OOvNu/9gKI5kaZ5oqq5s675wTAJ0bd+1hOx87/OyoDAEOCgORuQxyQToBtCodDpADK+tn9Y6KQa+4HCY4GQgBgl0OrFuo7nY+OlMncIZAEWAwO/7+QEKZWdpaFCFiFB3JkcKjY8aRo+SBxqOlJcKlpiQF2cCoKGiCXdef6cEgYOHqH2HiwyTmZoZCga3uLeVtbm5uxi2vbqWwsOeAwILysvKAlUUeXutfao6hQQF2drZBIawwcK/FwfFBuIW4L3nFeTF6xTt4RifzMwCpNB609SCT2nYAgoEHNhNkYV46oi5i1Tu3YR0vhTK85QgmbICAxZgdFbqgLR9/tXMRMG2TVu3NN8aMlyYAWHEliphsrRAD+PFjPdK6duXqp/IfwKDZhNAIMECfBUg4nIoQakxDC6XrpwINSZNZMtsNnvWZacCAl/Dgu25Cg3JkgUIHOUKz+o4twfhspPbdmYFBBVvasTJFo9HnmT9DSAQUFthtSjR0X24WELUp2/txpU8gd6CjFlz5pMmtnNgkVDOBlwQEHFfx40ZPDY3NaFMqpFhU6i51ybHzYBDEhosVCDpokdTUoaHpLjxTcaP10quHBjz4vOQiZqOVIKpsZ6/6mY1bS2s59DliJ+9xhAbNJd1fpy2Pc1lo/XYpB9PP4SWAD82i9n/xScdQ2qwMiGfN/UV+EIRjiSo4IL+AVjIURCWB4uBFJaAw4U36LDFDvj5UOGHIIYo4ogklmgiChEAACH5BAkJAA0ALAAAAACgABgAg1RWVKyqrNTW1Ly+vOTm5MTGxNze3JSWlLSytMTCxOzu7MzKzOTi5P7+/gAAAAAAAAT+sMlJq7046827/2AojmRpnmiqrmzrvnBMBnRt37UE7Hzv87KgMBQwGI/IpCGgSwwSTugzSgUMry2BdsvlUoqHsHg8ZjAbgKc6ulYPrNg4SqCo2+91wddwWPj/gH4HS01tbIcJcChuTm4ajZADTxqSkWqUlo0YdH4JnZ8KehMBDH2BpwdmOmoIAa2vrgFRihOMlZKUBLq7ugm5vLu+GQPAwb/FwhZ0CQzNzs0FoXumBQvV13+DZwBRAZLf3whqtBIJxb2PBAq66+jD6uzGGebt7QTJF+bw+/gUnM4GmgVcIG0Un1OBCqTaxgocOHFOyDUgtq9dvwoUea27SEGfxnv+x3ZtDMmLY4N/AQUSYBBNlARSfaohFEQITTc3D8dZ8AjMZLl4Chi4w0AxaNCh+YAKBTlPaVCTywCuhFbw5cGZ2WpyeyLOoSSIb3Y6ZeBzokgGR8syUyc07TGjQssWbRt3k4IFDAxMTdlymh+ZgGRqW+XEm9cBsp5IzAiXKQZ9QdGilXvWKOXIcNXqkiwZqgJmKgUSdNkA5inANLdF6eoVwSyxbOlSZnuUbLrYkdXSXfk0F1y3F/7lXamXZdXSB1FbW75gsM0nhr3KirhTqGTgjzc3ni2Z7ezGjvMt7R7e3+dn1o2TBvO3/Z9qztM4Ye0wcSILxOB2xiSlkpNH/UF7olYkUsgFhYD/BXdXAQw2yOBoX5SCUAECUKiQVt0gAAssUkjExhSXyCGieXiUuF5ygS0Hn1aGIFKgRCPGuEEXNG4xDRk4hoGhIbfccp+MQLpQRF55HUGAXkgawdAhIBaoWJBQroDDlDfo8MOVPUSp5ZZcdunll2CGiUIEACH5BAkJAAwALAAAAACgABgAg1RWVKSipMzOzNze3Ly6vNTW1OTm5MTCxKyqrOTi5Ly+vNza3P7+/gAAAAAAAAAAAAT+kMlJq7046827/2AojmRpnmiqrmzrvnAsW0Bt37gtIXzv/72ZcOgBHBSHYxKpbAJ2g6h0Sh0giNgVcHudGAPgsFhMeDIQg0R6nVC30+pudl5CV6lyBkARIPj/gH4BCmZoamxRh4p5EkgKjpAaR5CTBxqPlZgKl5mRGZ2VGGgCpKWmCXlfgasEg4WJrH9SjAwKBre4t5YZtrm4uxi9vgbAF8K+xRbHuckTowvQ0dACVhR7fbF/rlBqBAUCBd/hAgRrtAfDupfpxJLszRTo6fATy7+iAwLS0gKo1nzZtBGCEsVbuIPhysVR9s7dvHUPeTX8NNHCM2gFBiwosIBaKoD+AVsNPLPGGzhx4MqlOVfxgrxh9CS8ROYQZk2aFxAk0JcRo0aP1g5gC7iNZLeDPBOmWUDLnjqKETHMZHaTKlSbOfNF6znNnxeQBBSEHStW5Ks0BE6K+6bSa7yWFqbeu4pTKtwKcp9a1LpRY0+gX4eyElvUzgCTCBMmWFCtgtN2dK3ajery7lvKFHTq27cRsARVfsSKBlS4ZOKDBBYsxGt5Ql7Ik7HGrlsZszOtPbn2+ygY0OjSaNWCS6m6cbwkyJNzSq6cF/PmwZ4jXy4dn6nrnvWAHR2o9OKAxWnRGd/BUHE3iYzrEbpqNOGRhqPsW3xePPn7orj8+Demfxj4bLQwIeBibYSH34Et7PHIggw2COAaUxBYXBT2IWhhCDlkiMMO+nFx4YcghijiiCSWGGIEACH5BAkJAA0ALAAAAACgABgAg1RWVKyqrNTW1Ly+vOTm5MTGxNze3JSWlLSytMTCxOzu7MzKzOTi5P7+/gAAAAAAAAT+sMlJq7046827/2AojmRpnmiqrmzrvnAsW0Ft37gtAXzv/72ZcOgJGI7IpNIQ2CUGiWcUKq0CiNiVYMvtdinGg3hMJjOaDQB0LWWvB9es3CRQ2O94uwBsOCz+gIF/B0xObm2ICXEUb09vGo6RA1Aak5JrlZeOkJadlBd1fwmipAp7EwEMfoKsB2c7awgBsrSzAVKLEwMEvL28CZW+vsAZu8K/wccExBjGx8wVdQkM1NXUBaZ8qwsFf93cg4VpUgGT5uYIa7kSCQQKvO/Ixe7wvdAW7fHxy5D19Pzz9NnDEIqaAYPUFmRD1ccbK0CE0ACQku4cOnUWnPV6d69CO2H+HJP5CjlPWUcKH0cCtCDNmgECDAwoPCUh1baH4SSuKWdxUron6xp8fKeAgbxm8BgUPXphqDujK5vWK1r0pK6pUK0qXBDT2rWFNRt+wxnRUIKKPX/CybhRqVGr7IwuXQq3gTOqb5PNzZthqFy+LBVwjUng5UFsNBuEcQio27ey46CUc3TuFpSgft0qqHtXM+enmhnU/ejW7WeYeDcTFPzSKwPEYFThDARZzRO0FhHgYvt0qeh+oIv+7vsX9XCkqQFLfWrcakHChgnM1AbOoeOcZnn2tKwIH6/QUXm7fXoaL1N8UMeHr2DM/HoJLV3LBKu44exutWP1nHQLaMYolE1+AckUjYwmyRScAWiJgH0dSAUGWxUg4YSO0WdTdeCMtUBt5CAgiy207DbHiCLUkceJiS2GUwECFHAAATolgqAbQZFoYwZe5MiFNmX0KIY4Ex3SCBs13mikCUbEpERhhiERo5Az+nfklCjkYCUOOwChpQ9Udunll2CGKeaYX0YAACH5BAkJAAsALAAAAACgABgAg1RWVKSipMzOzLy6vNze3MTCxOTm5KyqrNza3Ly+vOTi5P7+/gAAAAAAAAAAAAAAAAT+cMlJq7046827/2AojmRpnmiqrmzrvnAsq0Bt37g977wMFIkCUBgcGgG9pPJyaDqfT8ovQK1arQPkcqs8EL7g8PcgTQQG6LQaHUhoKcFEfK4Bzu0FjRy/T+j5dBmAeHp3fRheAoqLjApkE1NrkgNtbxMJBpmamXkZmJuanRifoAaiF6Sgpxapm6sVraGIBAIItre2AgSPEgBmk2uVFgWlnHrFpnXIrxTExcyXy8rPs7W4twKOZWfAacKw0oLho+Oo5cPn4NRMCtbXCLq8C5HdbG7o6xjOpdAS+6rT+AUEKC5fhUTvcu3aVs+eJQmxjBUUOJGgvnTNME7456paQninCyH9GpCApMmSJb9lNIiP4kWWFTjKqtiR5kwLB9p9jCelALd6KqPBXOnygkyJL4u2tGhUI8KEPEVyQ3nSZFB/GrEO3Zh1wdFkNpE23fr0XdReI4Heiymkrds/bt96iit3FN22cO/mpVuNkd+QaKdWpXqVi2EYXhSIESOPntqHhyOzgELZybYrmKmslcz5sC85oEOL3ty5tJIcqHGYXs26tevXsGMfjgAAIfkECQkACgAsAAAAAKAAGACDlJaUxMbE3N7c7O7svL681NbU5ObkrKqszMrM5OLk/v7+AAAAAAAAAAAAAAAAAAAABP5QyUmrvTjrzbv/YCiOZGmeaKqubOu+cCyrR23fuD3vvHwIwKBwKDj0jshLYclsNik/gHRKpSaMySyyMOh6v90CVABAmM9oM6BoIbjfcA18TpDT3/Z7PaN35+8YXGYBg4UDYhMHCWVpjQBXFgEGBgOTlQZ7GJKUlpOZF5uXl5+RnZyYGqGmpBWqp6wSXAEJtLW0AYdjjAiEvbxqbBUEk8SWsBPDxcZyyst8zZTHEsnKA9IK1MXWgQMItQK04Ai5iWS/jWdrWBTDlQMJ76h87vCUCdcE9PT4+vb89vvk9Ht3TJatBOAS4EIkQdEudMDWTZhlKYE/gRbfxeOXEZ5Fjv4AP2IMKQ9Dvo4buXlDeHChrkIQ1bWx55Egs3ceo92kFW/bM5w98dEMujOnTwsGw7FUSK6hOYi/ZAqrSHSeUZEZZl0tCYpnR66RvNoD20psSiXdDhoQYGAcQwUOz/0ilC4Yu7E58dX0ylGjx757AfsV/JebVnBsbzWF+5TuGV9SKVD0azOrxb1HL5wcem8k0M5WOYP8XDCtrYQuyz2EWVfiNDcB4MSWEzs2bD98CNjejU/3bd92eAPPLXw22gC9kPMitDiu48cFCEXWQl0GFzDY30aBSRey3ergXTgZz0RXlfNSvodfr+UHSyFr47NVz75+jxz4cdjfz7+///8ABgNYXQQAIfkECQkABQAsAAAAAKAAGACCfH58vL685ObkzM7M1NLU/v7+AAAAAAAAA/5Yutz+MMpJq7046827/2AojmRpnmiqrmzrvnAsw0Bt3/es7xZA/MDgDwAJGI9ICXIZUDKPzmczIjVGn1cmxDfoer8E4iMgKJvL0+L5nB6vzW0H+S2IN+ZvOwO/1i/4bFsEA4M/hIUDYnJ0dRIDjH4Kj3SRBZN5jpCZlJuYD1yDX4RdineaVKdqnKirqp6ufUqpDT6hiF2DpXuMA7J0vaxvwLBnw26/vsLJa8YMXLjQuLp/s4utx6/YscHbxHDLgZ+3tl7TCoBmzabI3MXg6e9l6rvs3vJboqOjYfaN7d//0MTz168SOoEBCdJCFMpLrn7zqNXT5i5hxHO8Bl4scE5QQEQADvfZMsdxQACTXU4aVInS5EqUJ106gZnyJUuZVFjGtJKTJk4HoKLpI8mj6I5nDPcRNcqUBo6nNZpKnUq1qtWrWLNq3cq1q1cKCQAAO2ZvZlpFYkliUkxFdG9ZdlpHWWpMU3d6N0VKTDNnVk01aWxQaXBDSXJ2SDMxK3lHMGxMVHJVY0lUU0xvTGdvemw='
layout = [ [sg.Text('Loading....', font='ANY 15')],
[sg.Image(data=gif103, key='_IMAGE_')],
[sg.Button('Cancel')]
]
window = sg.Window('My new window').Layout(layout)
while True: # Event Loop
event, values = window.Read(timeout=0)
if event in (None, 'Exit', 'Cancel'):
break
window.Element('_IMAGE_').UpdateAnimation(gif103, time_between_frames=50)
MikeTheWatchGuy 2019-01-17T06:09:36Z
3.24.0 PySimpleGUI, 1.24.0 PySimpleGUI27 17-Jan-2018
- PopupAnimated - A popup call for showing "loading" type of windows
PopupAnimated
I couldn't resist jamming out one "final" feature for animated GIFs, the PopupAnimated
function. This call enables you to show a "loading" window / animation without the need to create and show the window yourself.
To use it, simply call PopupAnimated over and over. It will automatically keep track of which frame to show and when. Add the call to your work loop just like you would a OneLineProgressMeter
. It's like having a OneLineAnimatedGIF call.
Also, there is a built-in, default, animated GIF that you can use if you don't have one. The variable is named:
DEFAULT_BASE64_LOADING_GIF
Here's an example use:
for i in range(100000):
sg.PopupAnimated(sg.DEFAULT_BASE64_LOADING_GIF, background_color='white', time_between_frames=100)
sg.PopupAnimated(None) # close all Animated Popups
The result is a spinning animation lasting a few seconds.
The result looks like this:
Not bad for a couple of lines of code, right?
Demo_Animated_GIFs.py
A new demo program was released at the same time. It shows you how to use the PopupAnimated
call as well as how to run your own animation in your custom window. The file also contains 10 Base64 encoded GIF files, ready to copy and paste into your code!
Runs on legacy Python
For those of you stuck in the 2.7 world, shockingly this code also runs on legacy Python. I wouldn't have though all these graphic formats and operations wouldn't be supported, but I'll be damned if it doesn't work. Hats off to the tkinter team for this feature.
MikeTheWatchGuy 2019-01-17T22:06:39Z
Animated GIF Checkin
I have posted 20 animated GIFs that I have been using to test the animated GIF features. You'll find them here:
https://github.com/PySimpleGUI/PySimpleGUI/tree/master/GIFs
In that folder you'll also find a file output.py
which contains the Base64 versions of all of the GIF files. You can copy these variables into your code and use them directly with the new calls.
Simple and easy to use!
Animated GIF Design Philosophy
If not apparent, my goal is to typically boil down PySimpleGUI interfaces into a single line of code if possible, assuming that a single line of code is the most simple, straightforward way of doing things.
For Animated GIFs there are 2 single-lines of code. One is the PopupAnimated
and the other is the UpdateAnimation
. Both of these single calls cause a GIF file or Base64 variable to be animated.
If these actions were performed by the user code then it would be significantly more complex and more code than a single line. The caller would need to worry about how many frames are in the GIF, how often to show a new frame, etc.
MikeTheWatchGuy 2019-01-20T01:19:48Z
PySimpleGUIWx - Spinner
The Wx port just got a new element! The Spinner is done! It took longer than expected because I had to combine 2 WxPython widgets to get the implementation right. It's a combination of a text entry box and a "spin button". The reason is that a normal Spinbox Widget in WxPython controls an integer counter. It does not display strings.
In tkinter strings are displayed. In Qt there was also some tricks that had to be played in order to get strings to show up in a Spin Element. Because tkinter went first I've made the other frameworks, Qt and WxPython, look and behave like tkinter. It's a superior interface in my opinion as you can still show an up/down integer counter.
Up next.... Listbox.... and soon.... TABLES! (oh joy... how I hate tables but maybe this time it'll be easy)
MikeTheWatchGuy 2019-01-21T15:55:06Z
0.7.0 PySimpleGUIWx 21-Jan-2019
-
Element.Update support for disabled and tooltip
-
Combo Element
-
Newest Combo paramters
-
Radio Element
-
Newest Radio paramters (size_px, visible, enable_events)
-
Type hints on Wx widgets
-
Spinner Element
-
Newest Spinner paramters
-
Text Element visibility
-
Column Element size_px parameter (unclear if works... likely does not)
-
Column visibility
-
Column Update method added
-
System Tray - support for any kind of image format for icons
-
Window.Move
-
Window.Minimize
-
Window.Maximize
-
Window.Disable
-
Window.Enable
-
Window.Hide
-
Window.UnHide
-
Window.BringToFront
-
Popup non_blocking - returns window and button not just button
-
More comprehensive test harness when running PySimpleGUIWx.py
These are currently the working Elements
-
Text
-
Input Text
-
Buttons including file/folder browse
-
Input multiline
-
Output multiline
-
Output
-
Columns
-
Progress Meters
-
Checkbox
-
Radio Button
-
Combobox
-
Spinner
MikeTheWatchGuy 2019-01-21T16:03:36Z
Wx Release
Didn't realize how long it's been since the last PySimpleGUIWx release.... was something like 10 days. There were 3 new elements in this release, so it's not like development stood still. New are the Radio, Combobox and Spinner elements.
The Radio Buttons were weird to code. I had to group the creation of the Wx Radio Button widgets in a specific order. This made it impossible to use the tk or Qt methods. The problem comes when you have a group of radio buttons in your window with other radio buttons in between the group, then the buttons in the middle would be included in the group. It required multiple "passes" over the window layout to create the Radio Buttons in groups. It was somewhat painful.
The "logical" choice for the next Element to implement is the Listbox.
I would like to skip it or get it done quickly so I can get to...... TABLES!!
I'm hoping that WxPython can represent "the" port to use for tables. I guess I'm hoping even more that the port will go smoothly.
Then Trees... and finally the FUN part, custom Widgets like gauges and speedometers!! I'll take suggestions for these cool new styles of widgets. Would like to show everyone what WxPython is capable of by exposing as many of the interfaces as possible.
"New package, same great taste".
MikeTheWatchGuy 2019-01-21T21:29:59Z
r/PySimpleGUI - The PSG Subreddit
https://www.reddit.com/r/PySimpleGUI/
I got this idea from the Remi project... the newest target for a porting effort.
I have no idea if it'll help people discover PySimpleGUI or get support or if it'll be a complete waste of everyone's time.
MikeTheWatchGuy 2019-01-22T16:56:56Z
PySimpleGUIWeb !
Wow!
I'm blown away by a new port that's started.... yes, yet another platform.... this one is DIFFERENT however. This time your program runs in a Web page! You got that right, in a web page.
import PySimpleGUIWeb as sg
def main():
layout = [
[sg.Text('This is a text element')],
[sg.Text('Here is another' ), sg.Text(' and another on the same line')],
[sg.Text('If you close the browser tab, the app will exit gracefully')],
[sg.InputText('Source'), sg.FolderBrowse()],
[sg.InputText('Dest'), sg.FolderBrowse()],
[sg.Ok(), sg.Cancel()]
]
window = sg.Window('Demo window..').Layout(layout)
while True:
event, values = window.Read()
print(event, values)
if event is None:
break
window.Close()
main()
print('Program terminating normally')
The port has barely begun (as in today was the first day of coding) and already the Text, Input Text, and Button Elements are running (at a basic level).
The version that was just checked in, 0.1.1, is a "proof of concept" release meant to show it's "possible".
MikeTheWatchGuy 2019-01-22T17:20:04Z https://youtu.be/m4YqMMEnauw
Not sure why YouTube has decided to crunch my video down so badly!
MikeTheWatchGuy 2019-01-23T15:56:07Z
Web Progress & Development Strategy
Last night I got the Timer demo app up and running. I use the demo apps as a way to step through features and implement them. It's like laying train tracks out in front of a train of demo programs.
The advantage to this kind of development is that I can release groups of features that fit together to form "typical" applications. As long as your app only needs Text, Input Text and Buttons, then you could in theory be using PySimpleGUIWeb. It would be quite limited as there is no 'styling' currently available. The point is features are released in "sets" and the ports tend to follow similar paths in the order Elements are brought online.
I also make multiple passes at the elements. The Text Element at the moment has no font, size or color controls. You can only create the text and Update the text. Buttons you can change the text but not the colors.
The current feature set matches these Timer Demo required features:
-
Create a window with Text and Buttons
-
Update the Text fields
-
Update the Button text
-
Close the window when finished
The next chunk to be done is the fonts, colors, sizes and padding along with some Window features like setting the title. That will enable the window to look more like the ones created using tkinter, Qt, WxPython:
I'm thinking of doing something interesting with Popup
. Instead of creating a window using normal user Elements, the window will be a "Notification Window" that slides out in the bottom right of the Window desktop. I don't know how they work on Linux. I'm going to try it and see if it works well or is a bust.
Here's the code that produced the timer window
#!/usr/bin/env python
import sys
import PySimpleGUIWeb as sg
import time
# ---------------- Create Form ----------------
layout = [
[sg.Text('')],
[sg.Text('test', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
[sg.Button('Pause', key='button', button_color=('white', '#001480')),
sg.Button('Reset', button_color=('white', '#007339'), key='Reset'),
sg.Exit(button_color=('white', '#8B1A1A'), key='Exit')]
]
window = sg.Window('Running Timer').Layout(layout)
# ---------------- main loop ----------------
current_time = 0
paused = False
start_time = int(round(time.time() * 100))
while (True):
# --------- Read and update window --------
if not paused:
event, values = window.Read(timeout=10)
current_time = int(round(time.time() * 100)) - start_time
else:
event, values = window.Read()
if event == 'button':
event = window.FindElement(event).GetText()
# --------- Do Button Operations --------
if event is None or event == 'Exit': # ALWAYS give a way out of program
break
if event is 'Reset':
start_time = int(round(time.time() * 100))
current_time = 0
paused_time = start_time
elif event == 'Pause':
paused = True
paused_time = int(round(time.time() * 100))
element = window.FindElement('button')
element.Update(text='Run')
elif event == 'Run':
paused = False
start_time = start_time + int(round(time.time() * 100)) - paused_time
element = window.FindElement('button')
element.Update(text='Pause')
# --------- Display timer in window --------
window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
(current_time // 100) % 60,
current_time % 100))
# --------- After loop --------
window.Close()
MikeTheWatchGuy 2019-01-23T22:20:28Z
0.2.0 PySimpleGUIWeb
Dropped another release tonight. This release adds fonts, colors, sizes. In other words, the things that make a GUI interesting.
Enough functionality was added to complete the Timer program so that it appears the same as the Timer when run using tkinter.
I can't stress how weird, freaky, strange it feels to be running this PySimpleGUI code in a browser window.
The exact same code is running on PySimpleGUI (tkinter) and PySimpleGUIWeb.
The differences are in things like the size of the text fields. Minor things you normally tweak a little when moving from one platform to another.
#!/usr/bin/env python
import PySimpleGUI as sg
import time
# ---------------- Create Form ----------------
layout = [
[sg.Text('', background_color='black')],
[sg.Text('test', size=(20, 1), font=('Helvetica', 30), justification='center', text_color='white', key='text', background_color='black')],
[sg.Text('', background_color='black')],
[sg.Button('Pause', key='button', button_color=('white', '#001480')),
sg.Button('Reset', button_color=('white', '#007339'), key='Reset'),
sg.Exit(button_color=('white', '#8B1A1A'), key='Exit')]
]
window = sg.Window('Running Timer', background_color='black', font='Helvetica 18').Layout(layout)
# ---------------- main loop ----------------
current_time = 0
paused = False
start_time = int(round(time.time() * 100))
while (True):
# --------- Read and update window --------
if not paused:
event, values = window.Read(timeout=0)
current_time = int(round(time.time() * 100)) - start_time
else:
event, values = window.Read()
if event == 'button':
event = window.FindElement(event).GetText()
# --------- Do Button Operations --------
if event is None or event == 'Exit': # ALWAYS give a way out of program
break
if event is 'Reset':
start_time = int(round(time.time() * 100))
current_time = 0
paused_time = start_time
elif event == 'Pause':
paused = True
paused_time = int(round(time.time() * 100))
element = window.FindElement('button')
element.Update(text='Run')
elif event == 'Run':
paused = False
start_time = start_time + int(round(time.time() * 100)) - paused_time
element = window.FindElement('button')
element.Update(text='Pause')
# --------- Display timer in window --------
window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
(current_time // 100) % 60,
current_time % 100))
# --------- After loop --------
window.Close()
MikeTheWatchGuy 2019-01-24T00:04:16Z
0.2.1 PySimpleGUIWeb
If you upgraded to 0.2.0 then please get 0.2.1. If you don't set a background color it will crash without telling you why.
I'm struggling a little on getting exceptions turned on in my code again while executing in the Remi environment.
MikeTheWatchGuy 2019-01-24T07:48:37Z
0.3.0 PySimpleGUIWeb 24-Jan-2019
-
Checkbox Element
-
Combobox Element
-
Listbox Element
-
Element padding for all elements
I couldn't resist releasing the Checkbox, Combobox, Listbox elements that were just completed. Making loads of progress very quickly. Will be implementing Tables and Tree before long and then it'll be on to the fun, unique and interesting unique to PySimpleGUIWeb features. Looking forward to the new notification-style popups.
Correct padding of Elements enabled the Color demo to run. Surely you recall seeing this demo program previously. I've posted a screenshot of this program using every port as the ports are brought up using these demo programs. Despite seeing this program so many times in the past, it's always exciting when the demo programs start to run, one by one. Each new demo represents some new subset of functional features.
MikeTheWatchGuy 2019-01-25T18:06:03Z
Android support....
PySimpleGUI on Windows, Mac and Linux desktop GUI provided through:
- tkinter, WxPython, Qt
PySimpleGUIWeb Browser support provided through:
- Remi
Here's something I had not at all expected from the PySimpleGUIWeb effort:
- Ability to run PySimpleGUI programs on Android
I just read that it's possible to run Remi on Android
This has been possible for a couple of years evidently. QPython is used as the Android Python port of choice for this operation.
I'm trying to run PySimpleGUIWeb on Android ASAP!
Remi may be the technology that enables PySimpleGUI to offer a complete solution that includes both desktop and mobile.
I had previously been eyeing Kivy for the Android port, but I ran into difficulty with the Kivy port. Maybe someday I'll pick it up and make another pass at it. But for now it's on hold with PySimpleGUIWeb being the primary vehicle for Android applications.
It would be ideal to be able to show Remi applications on Android in a way that removes all of the web browser graphics where you're left with only the PySimpleGUI elements on the screen.
It keeps getting better and better for this PySimpleGUIWeb port!
MikeTheWatchGuy 2019-01-26T19:48:41Z
0.4.0 PySimpleGUIWeb
pip will now also install Remi when installing PySimpleGUIWeb
Functioning Elements
-
Text
-
Single line text input
-
Multiline Input
-
Multiline Output
-
Listbox
-
Combobox
-
Checkbox
-
Slider
-
Spinner (numbers only...hardcoded to 0 to 100)
New features
-
Tooltips for all elements (so cool this works)
-
Input Text events
-
Text clicked event
-
Listbox selected event
-
Combobox selected event
-
Checkbox Update
-
Disable parameter for all elements
-
Window.Close shuts down the server
-
Enabled exceptions during packing operation
-
New test harness exercises all element types
MikeTheWatchGuy 2019-01-27T00:27:32Z
PySimpleGUIWeb RUNNING online
If you're ever on the road and in the mood for some PySimpleGUI programming but don't have access to your Python machine then this will be of interest to you!
https://repl.it/@PySimpleGUI/PySimpleGUIWeb-Demos
Thanks to the hard work of the Remi project and the repl.it folks it's possible to run your PySimpleGUI code directly in your browser, no Python installation required.
It's trippy to see actual PySimpleGUI code in the online editor with the resulting window shown in a window in the browser based debugger.
MikeTheWatchGuy 2019-02-02T03:35:06Z
0.5.0 PySimpleGUIWeb 1-Feb-2019
Time for another release! Columns! Now you can get just about any layout. Really wanted to get this out so can begin to work with repl.it more. repl.it is the future for the PySimpleGUI Cookbook. Tutorials as well should be using the embedded iframe feature of repl.it.
-
New default font size. Was Helvetica 10, now Helvetica 15
-
InputText Element single character events working! (Finally)
-
Listbox simple Update (values only)
-
Column Element! New!
-
Column element experimental justification setting doesn't work yet
-
Element background colors now picked up from container, not top level window
-
Autosize Text
-
Autosize Button Text
MikeTheWatchGuy 2019-02-07T17:31:33Z
Python Developers' Survey...
https://www.jetbrains.com/research/python-developers-survey-2018/
I'm stunned by this data:
That tells me that PySimpleGUIWeb is absolutely the right priority at this time. Or that more Web Developers answered the survey than other developers.
This data is based on 20,000 people that filled out the survey.
MikeTheWatchGuy 2019-02-07T17:40:34Z
PySimpleGUIWeb Installations
The number of pip installs of PySimpleGUIWeb continue to take the top spot of the PySimpleGUI ports. It's also interesting to see how the Remi installs track the PySimpleGUI installs, especially after I indicated that Remi is a required package that is automatically installed with PySimpleGUIWeb installs.
PySimpleGUIWeb has triggered a shuffling of the priorities.... especially after enabling it to run on repl.it. There is SO much that can be done using PySimpleGUIWeb now that PySimpleGUI can't do. The port has a long long ways to go, but it's moving along briskly. PySimpleGUIWeb on repl.it has the potential to be an excellent educational resource for learning both Python and GUI programming.
Never did I think that PySimpleGUI would be running in a browser. It wasn't on the roadmap of planned ports.
Check out these install stats. Remi is on the left, PySimpleGUIWeb on the right.
pamoroso 2019-02-07T18:22:48Z PySimpleGUIWeb is in a sweet spot combining ease of use, versatility, and wide deployability.
MikeTheWatchGuy 2019-02-08T23:30:26Z
0.8.1 Multiple windows!!
This is an officially cool release!!
Really excited this is working, however brittle it may be.
You can now have Popups! Multiple windows are working, even running on Repl.it.
Here's one that shows a popup.
https://repl.it/@PySimpleGUI/Popup-Demonstration
8.1 is the newest version. It removed the bad code in the Hide and UnHide methods. Sorry about that code being in there.
You can run the design pattern 1 using 0.8.1! (It will crash on 0.8.0)
This is exciting stuff. I'm not sure yet how it'll all come together, but I do know this is a significant capability to add. The range of potential applications just increased by a big factor.
MikeTheWatchGuy 2019-02-13T17:42:19Z
PySimpleGUIWeb -Window.Hide
, Window.UnHide
Snuck in Window.Hide and Window.UnHide. These calls weren't all that useful in Windows, Qt, Wx, but, for Remi they are a powerful tool. They allow you to manage the display of your multiple windows.
At the moment, only one PSG Window can be displayed on a Web page at a time. A Popup will replace the window that called the popup. When the popup exits, the calling window is restored.
If you want run multiple windows then you need a way to indicate which of your windows should be shown. This is where Hide
and UnHide
come in. To "switch" to another window, Hide the current window and UnHide the one you want to show. To switch back, UnHide the original window, and Hide the current one.
In the PySimpleGUI code, you simply run the normal Multiple Windows Design Pattern, but need to add code to manage specifically which window is visible.
This could really open up an application that has setup screens, enter detailed information screens, etc.
MikeTheWatchGuy 2019-02-15T15:42:55Z
0.9.0 PySimpleGUIWeb is out
I slipped out a new version the other evening. It was to get the Hide and UnHide features available since multiple windows is now "a thing".
This port paired with repl.it has turned out to be one of the best things to happen to PySimpleGUI.
Here is why.... By simply going to a webpage, a user will not just see the PySimpleGUI code, but they will watch it execute. There is no pip install. Nothing at all to do except WATCH. It's like forcing them to look at the running code, correctly solving a problem.
Here is an example where this really came in handy:
https://www.reddit.com/r/learnpython/comments/aqwqy0/gui_random_number_of_buttons_depending_on/
A Reddit poster wanted to know if it's possible to have 1 window create another window with a large amount of buttons,. based on input from the first window.
Pfffffftttt... such a simple thing to do in PySimpleGUI. In fact, it was easy enough that it can run using PySimpleGUIWeb! And that means a user gets to SEE the prototype solution to their problem and can copy and paste it right into their project.
Then change from import PySimpleGUIWeb
to import PySimpleGUI
and poof you're up and running on tkinter.
It really is like magic!
MikeTheWatchGuy 2019-02-16T03:18:06Z
Reddit PySimpleGUIWeb Announcement
https://www.reddit.com/r/Python/comments/ar3x3b/embedding_entire_python_guis_in_webpages_with/
I took another chance and posted about PySimpleGUIWeb. I'm excited about repl.it and the potential it holds. It's not one of my better posts, but it at least lets everyone know there's a PySimpleGUI web GUI solution available, ready to use.
Seeing how there was a recent request in r/Python for a ban of all GUI posts on r/Python for some period of time, I don't expect this announcement to get the warmest of receptions. But that's OK, as long as the people that ARE interested in PySimpleGUI get the message.
I'm not above directly asking for your support. If you happen to be on Reddit, reading this post, feel free to up-vote the topic 😏
MikeTheWatchGuy 2019-02-17T04:10:57Z
0.10.0 PySimpleGUIWeb 16-Feb-2019
Pushing out another release, enabling a little bit more. It's available immediately on repl.it.
-
Completed Text.Update method. Can now change:
-
Text
-
Font family & size
-
Background color
-
Text Color
-
Visibility
-
-
Completed Button.Update with exception of images
-
Completed Spin.Update with except of range. This element still pretty crippled
-
Completed Slider.Update - Can update value, visibility, disabled, but not the range
-
Image Element!
-
Events for Image Element
-
Image.Update to change image
MikeTheWatchGuy 2019-02-20T14:06:47Z
Releases for PySimpleGUI, PySimpleGUI27 and PySimpleGUIWx
There have been some changes that hit EVERY release of PySimpleGUI. One is the addition to change your display information on the call to OneLineProgressMeter. Previously changing the display arguments had no effect.
Other changes were bug fixes or adding new capabilities (the Update method for Text on Wx).
PySimpleGUI & PySimpleGUI27 .25 & 1.25 20-Feb-2019
-
Comments :-)
-
Convert Text to string right away
-
Caught exceptions when main program shut down with X
-
Caught exceptions in all of the graphics primitives
-
Added parameter exportselection=False to Listbox so can use multiple listboxes
-
OneLineProgressMeter - Can now change the text on every call if desired
PySimpleGUIWx 0.8.0 20-Feb-2019
-
Big Try/Except block around Update method for multiline in case window closed
-
Text - convert incoming text to string right away
-
Text.Update - convert incoming value to string
-
Completed Button.Update method. Can now change text, color, etc.
-
Added Try around reading multiline input value - not sure why needed
-
OneLineProgressMeter - can update text on every call now
MikeTheWatchGuy 2019-02-25T20:00:10Z
0.11.0 PySimpleGUIWeb
A great release for those of you wanting to control the Remi settings such as the IP address and Port! All can be set in the call to Window now.
-
Slider - Can update range using .Update method
-
NEW Window parameters that allow control over all Remi startup settings
-
New Window parameters and default values:
-
web_debug=False
-
web_ip='0.0.0.0'
-
web_port=0
-
web_start_broswer=True
-
web_update_interval=.00001
-
Can set the Window backaground image (sorta works sometimes)
-
Struggling to get the "resources" settings understood so can work with files
-
I have a ways to go
-
deajan 2019-02-26T09:51:25Z Nice that PySimpleGUIWeb is going on forwards with big steps :)
Also some new releases of PySimpleGUI and PySimpleGUIWx, good to know those projets are still being given love :p
MikeTheWatchGuy 2019-02-27T00:21:42Z I'm REALLY need a new Qt release to go out immediately because it's breaking with the new pyside 2
MikeTheWatchGuy 2019-02-27T00:23:35Z
How Do I - Web-style
https://repl.it/@PySimpleGUI/howdoipy
My favorite PySimpleGUI utility, HowDoI, has finally ported to the Web. However, it gets better than that. It runs on repl.it too!
I had to shrink down the window to make it fit better with repl.it. I want to fix that up so it's better. I can change fonts, etc.
Anyway, the point is that it WORKS !!! I'm stunned!
MikeTheWatchGuy 2019-02-28T16:55:01Z
0.10.0 PySimpleGUIWeb Release
- A single-purpose release.... get the Combo.Update call fully operational.
I did this for 2 reasons.... one is that it needed to be done. All of the elements need their Update methods complete if not already completed.
Reason two is that I wanted to be able to demonstrate the solution to this Issue:
https://github.com/PySimpleGUI/PySimpleGUI/issues/1184
Because of the PySimpleGUIWeb update I just did, I was able to run the code on repl.it.
https://repl.it/@PySimpleGUI/Combox-How-To-Updatepy
This enables me to share code with people in a way they can IMMEDIATELY interact with. You don't need to download the code, open it in PyCharm, and try it out. Just follow the link and click "Run".
MikeTheWatchGuy 2019-03-01T00:24:31Z
Issues template
Now when you fill out an Issue on GitHub, there is a little template to follow. I need some basic information that is often missing and thus I make an assumption (Iike WHICH PySimpleGUI is being discussed).
The format is simple:
Issue Title Prefixes - [Bug], [Question], [Enhancement]
What is the import statement in your program that imports the PySimpleGUI package?
Your PySimpleGUI version if known:
Operating System and version:
What's up?
MikeTheWatchGuy 2019-03-02T18:59:38Z
New Demo Program - multithreaded design pattern
There was a Reddit post asking for help with async PySimpleGUI programming.
https://www.reddit.com/r/learnpython/comments/awbsft/async_design_patterns/
Made me realize I didn't have a demo program written that shows how to do multi-threading with PySimpleGUI, or at least one way of doing it.
You'll find the new demo program here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Multithreaded_Queued.py
But, what's really impressive is that you'll find a running version of it here:
https://repl.it/@PySimpleGUI/Async-With-Queue-Communicationspy
PySimpleGUIWeb is so powerful when it comes to being a teaching aid for PySimpleGUI. It is why PySimpleGUIWeb continues to soak up the dev cycles. This specific Demo is a great example showing that not only are PySimpleGUIWeb calls being taught, but deeper Python concepts are ALSO being demonstrated, live, in a web page.
[In this repl.it](https://repl.it/@PySimpleGUI/Async-With-Queue-Communicationspy
) you're able to experiment with not just the GUI elements, timing values, loops, etc, but you're also being exposed to the Queue and Thread objects. You can immediately begin modifying the program and observing the behavioral changes, all without doing a damned thing with your local machine
MikeTheWatchGuy 2019-03-05T13:16:20Z
Slow going...
I'm really sorry that bugs are starting to pile up. This is a bit of a first for the project as I've been able stay on top of critical bugs that are affecting people.
I'm behind on getting a critical release of Qt out the door since the new pyside2 doesn't work with current release. The Web port continues to take up time, but I'm spending not much on it these days.
The reasons for the slowdown are that I'm helping someone on their GUI for a fairly large project. System tray, multiple windows, etc. It's taking much longer than expected. Another project with higher priority than PySimpleGUI has also been eating lots of cycles.
So, I feel bad that some of you are stuck with bugs blocking you. I'll at least answer the new bugs and determine how difficult to work on. I hate bugs!!!
MikeTheWatchGuy 2019-03-05T15:56:46Z
0.13.0 PySimpleGUIWeb 5-Mar-2019
-
Added new parameter to Window - web_multiple_instance
-
Like other Window web parameters, this value is passsed Remi upon start
-
The default value is TRUE (Previously I think default was False by Remi)
-
Was made as a result of comment on repl.it.
Hopefully the repl.it's will run better now!
MikeTheWatchGuy 2019-03-05T16:19:25Z
0.15.0 PySimpleGUIWeb 5-Mar-2019
- Made the multiple_instance parameter FALSE by default (was messing up badly with True)
Well, things didn't go well at ALL when I released 13 and ran it in repl.it. It kept starting over, etc.
2 releases later and perhaps it's back to "normal" with this multiple instance thing turned off. Feel free to turn it on if you want.
MikeTheWatchGuy 2019-03-08T15:59:58Z
0.23.0 PySimpleGUIQt 8-Mar-2019
Here, enjoy this truck-load of Qt changes :-)
I'm sorry it's been a while since a release of Qt. The latest pyside2 causes PySimpleGUI to crash so I HAD to do something. I don't normally sit on releases this long because in my opinion it's a lot better to release them as quickly as possible.
There were changes that may affect window layouts. I changed the pixel scaling in particular. There are ways for you to get your old scaling back if you really want it.
If you're waiting on an Issue to get fixed, try and be patient. I DO get around to them as you can see.
-
Fixed crash that was happening with latest pyside2 release!!!!
-
Huge update to OneLineProgressMeter
-
Debug window got title and do-not-reroute-std-out option
-
Popups get a title option
-
PopupScrolled gets non-blocking option
-
Default logo included in Base64 Format
-
Changed Chars to pixels scaling. Went from (10,25) to (10,35)
-
Changed pixel to chars cutoff from 10 to 12
-
Change progress bar default size to 200 from 250
-
Reworked the _my_windows global variable / class to use Window class variables
-
Change in how Elements / Widgets are updated. Need to use {} correctly
-
InputText supports drag and drop
-
Support for Checkbox.Get()
-
Support for strings in spinbox
-
Added Update method to Output element
-
Changed Button default file_types from . to *
-
Support for Tab enable_events so they now generate events
-
Table.Update can change the number of rows of table
-
Window class now manages the list of active popups, user defined icon, QTApplication, num open windows
-
Window resizable parameter default changed from False to True
-
Window new parameter - disable_minimize
-
Window.GetScreenDimensions added
-
Window.Move added
-
Window.Minimize added
-
Window.Maximize added
-
Window.Disable added
-
Window.Enable added
-
Window.BringToFront added
-
Window.CurrentLocation added
-
TabGroup now returns which tab is selected in the return values
-
Completely new Style generation class and functions (I hope it works!!!!)
-
Style reworked for Column, Text, Button, Input, Combobox, Listbox, Input Multiline, Output Multiline, Progress Bar, Spinbox, Output,
-
Progress Bar colors are now correct
-
Events generated when tabs are changed
-
"Better" Table support. Uses num_rows now and styles the scrollbar
-
Tree element can support multiple types of icons including base64
-
Fixed tree element scroll bar
-
Icon ccan be set using SetOptions
-
main for PySimpleGUIQt.py gets a nice test harness that shows lots of Elements
MikeTheWatchGuy 2019-03-09T17:43:19Z
Updated Demo_Multi_Threaded_Queued.py
Lately there's been more talk about multi-threading (as well as a few projects that I'm working on that are actively using these kinds of techniques.
Today the code was:
-
Extensively commented
-
Added using itertools
-
Made the imports less specific so that the code is more specific
-
Uses 3 threads now instead of 2
A few things to point out in that list. I modified the threading import to go from
from threading import Thread
to
import threading
The reason I've done this is that I want to the calls to Thread in the main code to reflect exactly where that call to Thread is going to:
Another of the changes was using itertools.
I'm normally not a fan of "exotics" in the code, but itertools is part of the standard library going back to legacy Python, so it's not a new technology... it's just new to me.
I specifically wanted to solve a long-standing construct issue with me.
Here's a bit of code that I KNEW could be written better in Python:
That code was replaced by this code:
for i in itertools.count(): # loop forever, keeping count in i as it loops
time.sleep(run_freq/1000) # sleep for a while
gui_queue.put('{} - {}'.format(thread_name, i)) # put a message into queue for GUI
There are times that I want to run an infinite loop, but with a COUNTER. Unfortunately there is no:
for i in range(Infinity):
However I was able to essentially get the exact same result using this line of code:
` for i in itertools.count(): # loop forever, keeping count in i as it loops
`
It saved me 2 lines of code that looked clunky to me.
You can expect this kind of thing in the future for my code. However, I think that it's super-critical to comment a loop like this one HEAVILY, explaining exactly what's happening. In this case, what's happening is an infinite loop with a counter variable i
being available for use in the loop as if it were a normal for
loop.
MikeTheWatchGuy 2019-03-13T21:09:08Z
Repl.it with TKINTER
https://repl.it/@PySimpleGUI/PySimpleGUI-using-tkinter
I found that I can run the real PySimpleGUI rather than the Web one on repl.it. It seems to have some bugs. I sometimes have to rename the project and that will cause some kind of "re-install" of stuff that's required. You'll see these messages down in the lower right of the screen.
I make a little "launcher" app so that I can show several programs in this one project.
I had to include the entire PySimpleGUI.py file as part of the project. Thankfully that one file is all that's ever needed to get PySimpleGUI to work!
There are some quirks like the title bar being missing sometimes so you are unable to move the windows.
Other time, it doesn't reliably work. It's getting there! It's amazing that I can now provide sample and demo programs using plain PySimpleGUI and they can be run in a web page.. unchanged.
MikeTheWatchGuy 2019-03-14T00:51:35Z
PySimpleGUIWeb Tables
I read on Reddit that someone was considering PySimpleGUI but needed to use Tables and it says in the PySimpleGUI docs that the Table stuff sucks (paraphrase).
Doh!
I either need to be less honest or write better software. I'm leaning towards less honest now 😒
I appreciate the person who replied to the post, defending the PySimpleGUI Tables. Thank you whoever that was. I'll take any Reddit support I can get. It's not easy starting a movement ya know. (Nearing the 200,000th Pip install).
ANYWAY, it's motivated me to get my ass going on implementing Tables for.... PySimpleGUIWeb. Of course, sorry Wx, again.
Here's the progress so far:
I can't select rows yet nor do anything fancy like get events back from them. But you'll at least be able to feed PySimpleGUIWeb a table and it'll be shown.
I will post to GitHub tonight, probably PyPI too so I can repl.it. It's better to have something 1/2 way working than no way working
Next up... selecting rows. Oh joy.
MikeTheWatchGuy 2019-03-15T02:39:20Z
0.17.0 14-Mar-2019 PySimpleGUIWeb
-
More Table features supported
-
Option to display row numbers
-
New parameter
row_header_text
-
Can turn on / off displaying row numbers
-
enable_events
-
text_color
-
Font
-
Can get the value of the item clicked using Table.SelectedItem. Can be coded as window.Element('table').SelectedItem
While not many of the options are available (such as alternating row colors or number of rows), there are still enough awesome features to let this one ship. Better to have something that's "pretty good" than nothing at all.
You can see the Web version of the Table Element in use here:
https://repl.it/@PySimpleGUI/Table-Element
MikeTheWatchGuy 2019-03-15T14:05:36Z
0.18.0 15-Mar-2019
-
Hotfix for bug that causes Popups / secondary windows to crash
-
Table gets
starting_row_num
parameter
Yet another PySimpleGUIWeb release. This one added more capabilities for the Table Element and fixed a bug that broke the Popups / secondary windows.... not good!
MikeTheWatchGuy 2019-03-18T18:49:38Z
201,000 Installs
It's 200K day!
The pip odometer clicked over another 100,000 today.
It's a stat that likely means next to nothing by itself, but I find it interesting to compare it to other packages. Some packages are just plain monsters, getting millions of installs. These are the more general purpose packages.
Pyside2, for example, only has 158,000 installs. I find this one weirdly low.
Kivy 664,000
WxPython 846,000
PyQt5 2,324,228
Then there are the other "simplified" GUIs
easygui 430,000
gooey 188,000
appjar 84,000
toga 98,000
guizero 108,000
I think the 'takeaway', at least for me, is that in the few months (less than 1 year) that PySimpleGUI has been around it has managed to attract as many users and more than projects that have been around for several years.
I like this trend!!
PySimpleGUI has the kind of legs and impact that I knew it would have.
None of this would have been possible, however, without the user community that has stepped forward to help get the word out to other people, to make suggestions that are awesome and make the package much better. So, it's a congratulations that goes out to the user community for hitting this milestone. I'm the not the person that's racking up the install stats, it's all of you out there building awesome applications.
Thank you for your support and encouragement. I hear from a good number of users that thank me for building this. Often in the Issues I see positive comments despite a bug being reported. Those little comments matter. They do have an impact, a very positive one. Sometimes one short phrase is what gets me through the day, that keeps me motivated to keep pushing forward.
sidbmw 2019-03-19T23:03:03Z Congrats!!! :clap: :clap: :clap:
Keep up the impressive work, thanks for your effort in making PySimpleGUI....I believe this will hit the 1 MILLION mark soon (and billion soon after):1st_place_medal:
One day PySimpleGUI will be the "go to" GUI tool for all Python projects :)
MikeTheWatchGuy 2019-03-23T21:16:27Z
do_not_clear
defaults to True now!!!
Mark your calendar, it's finally happened...
No more having to add the annoying do_not_clear=True
to your input and multiline input/output elements!
You can simply write:
sg.Input()
and your input field will not be cleared when you "Read" the window.
I still must change all the docs, but for now, I'm happy just having jammed it out the door on these ports:
-
tkinter
-
Qt
-
WxPython
-
Web/Remi
Enjoy! I do apologize for not changing it much sooner.
Now I'm going to have to start explaining "how to clear the input fields after clicking a button". I know the questions will start pouring in. LOL
MikeTheWatchGuy 2019-03-31T16:32:33Z
3.27.0 PySimpleGUI 31-Mar-2019
Mixup.... 3.26 changes don't appear to have been correctly released so releasing in 3.27 now
-
do_not_clear now defaults to TRUE!!!
-
Input Element
-
Multiline Element
-
Enable Radio Buttons to be in different containers
-
Ability to modify Autoscroll setting in Multiline.Update call
-
PopupGetFolder, PopupGetFile, PopupGetText - title defaults to message if none provided
-
PopupAnimated - image_source can be a filename or bytes (base64)
-
Option Menu can now have values updated
MikeTheWatchGuy 2019-03-31T16:34:32Z I really screwed up the 3.26 release last week before surgery.
The changes were simply not there when I pip installed.
I rarely run the installed version of course, so I completely missed that the new animation feature wasn't working.
I'm really sorry if anyone lost time on this f-up.
The new stuff is there now and should be working fine.
MikeTheWatchGuy 2019-03-31T21:06:35Z
PySimpleGUI (tkinter) repl.it Template
Here is a template. The PySimpleGUI release that's used is 3.27.
https://repl.it/@PySimpleGUI/PySimpleGUI-on-tkinter-TEMPLATE
The cool thing about this template is that you can "fork it" on replit, paste your code into the main program window and run your plain PySimpleGUI code, in a browser.
I'm starting to use this more and more when answering Issues. It allows me to have control over which version of PySimpleGUI is being used. And it demonstrates, live, to the Issue reader, the fix that I'm proposing. No download and running in PyCharm on their system needed. Just follow the link.
I used it today to answer this question about replacing a window's contents:
https://github.com/PySimpleGUI/PySimpleGUI/issues/1270
And #1271 too.
I think it's super helpful to be able to answer this way.
If not, just tell me to knock it off :-)
MikeTheWatchGuy 2019-04-02T15:29:12Z
Some Things I Learned This Week
I've said it a number of times... this package grows as a direct result of how users use PySimpleGUI. Feature implementation often follows the requests by users rather than a firm, detailed roadmap. "Just enough, just in time" programming is how I think of it.
I learn from looking at how people use PySimpleGUI and am able sometimes to incorporate what I learn directly back into the code code or I learn a new technique from a user and am able to distribute it back to the community through this GitHub or through documentation / demo programs.
And, I learn from writing PySimpleGUI code to help people. I find myself duplicating GUIs that others have written so that I can compare the code required to duplicate the same GUI window. It's usually 1/2 the amount of code or less and pretty much always more clear to read (all subjective I realize). I learn where it's difficult or even impossible to duplicate other GUIs. It's all good stuff.
Using "special characters" as images on buttons
Check out this site for symbols to copy.
There is a restriction that I ran into for some characters if they are above some threshold. I don't recall all the particulars. You'll know when you hit a problem.
Here's an example of them in use:
import PySimpleGUI as sg
layout = [[sg.Text('Up and down buttons for free!')],
[sg.Button('▲'), sg.Button('▼')]]
e,v = sg.Window('Window Title').Layout(layout).Read()
print(e,v)
tkinter window:
Qt window:
Wx Window:
Web (Remi)
"Building" Layouts
I've struggled to come up with good demo programs, cookbook entries that show how to programmatically build a window. In the past I did things like use the '*' operator to unpack a list directly into a layout. This required Python 3.4 (I think) in order for it to work.
This new technique relies on concatenation of lists using the '+' operator. Should have tried this one long ago.
Like the above example, most layouts are these static lists of lists:
How do you easily add onto the end, or more importantly, how can you add something in the middle?
The way to do it is to always keep your layout pieces as these double lists [ [ ] ] and add them together.
To "add" the buttons then it would look something like this:
or, more than likely, you already have a variable layout
going and want to add to the end:
You can expect to see something more written about this in the future in the docs and in demo programs. It's been a thorn for beginners that I think this technique will solve.
MikeTheWatchGuy 2019-04-02T15:41:47Z
More Shortcuts
New shortcuts were added to all 4 ports of PySimpleGUI. These enable you to use very short names for Elements. The new ones include:
InputText:
I
Button:
B
Btn
Butt
I've noticed more people don't use shortcuts, and that's all well and good. I'm impatient, especially when it comes to cranking out simple GUIs that have Text, InputText, and Button elements. It makes a lot of sense to me to have available shorthand versions of these for people that want them.
The problem with having these is that I'm tempted to use them all the time, even in "teaching" situations, but that's not a good idea. It's easy to guess that Text('This is text')
is something that's going to display text in some way. It's not quite so clear when it's written: T('This is text')
. It gets worse with B
for Button
and I
for InputText
. Who knows, maybe it won't be an issue.
MikeTheWatchGuy 2019-04-04T18:46:35Z
Base64 Window Icon support added to Qt (so now in ALL ports)
I'm elated to have just checked in a change that allows you to specify the icon
parameter in a call to Window
to be a Base64 Byte String in addition to a filename.
All of the other PySimpleGUI ports (tkinter, WxPython, Remi) supported Base64 window icons, so it's nice that Qt supports them now too!!
This has not yet been released to PyPI. It's only on GitHub at this point.
I will try and get this up on PyPI this evening as I also want to get the super-short shortcuts uploaded too (B = Button, I = Input).
MikeTheWatchGuy 2019-04-05T15:34:21Z
Training the masses on Buttons.....
There is a new round of users arriving to the PySimpleGUI party!! How exciting.
This wave seems to be struggling with getting the news that PySimpleGUI does not at all follow the other GUI frameworks' OO model.
One of the more recent batches of questions has been around "How to hook a button up to a function". I've seen people guess by adding a command=
parameter to the Button
call, but that clearly didn't get them far.
And to make matters a little more difficult, the posts for help are spreading away from the GitHub issues list and onto sites like StackOverflow where I recently answered this one:
https://stackoverflow.com/questions/55515627/pysimplegui-call-a-function-when-pressing-button/55517255#55517255
This triggered me to take a couple of actions in addition to answering the specific StackOverflow post.
-
I created a new Demo program that specifically addresses connecting buttons to functions.
-
To go with that, I've created a repl.it sample program so it can be immediately examined and EXECUTED. https://repl.it/@PySimpleGUI/Call-Func-When-Button-Pressed
I am wondering what else to do on top of this. I'm tempted to add a BIG NOTICE right at the top of the Readme, urging people to read a very short introduction (perhaps also new) that quickly educates the reader that this GUI SDK is unlike the others and introduces them quickly to the concepts like Event Loops.
This notice and section is meant not for the complete beginner as much as the intermediate or advanced programmer that has had GUI exposure before and needs to be told "this time it's different".
I'm open to suggestions.... or perhaps this isn't a huge program that I need to worry about.
MikeTheWatchGuy 2019-04-05T15:44:32Z
Repl.it PySimpleGUI tkinter-style....
More on this incredible repli.it capability.
I continue, daily, to be blown away by repl.it and what it is enabling PySimpleGUI to do.
My latest obsession is the ability to run actual PySimpleGUI code in a web browser...not the PySimpleGUIWeb version,. but the real PySimpleGUI (tkinter) version.
I'm tempted to turn as many of the existing Demo Programs into repl.it versions and then adding the link to the repl.it to the top of the Demo Program.py file's source code.
For example, someone asked about a Chat program on Reddit, so I thought it was a great opportunity to move it over to replit for display.
I've now added this repl.it link to the comments of the demo code here on GitHub:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Chat.py
One down, potentially lots to go....
MikeTheWatchGuy 2019-04-05T18:10:23Z
0.25.0 PySimpleGUIQt 5-Apr-2019
Really wanted to get this Base64 icon released to PyPI as well as the new shortcuts. This means all the ports finally have the real PySimpleGUI icon built into the code so that it will always display, by default. It's a cool logo, and it's great to be able to look at a window and know if it's a PySimpleGUI window (most likely people won't change the logo).
Don't feel like I can really begin to use the shortcuts until all of the ports have them released to PyPI. So, not sg.Butts in my layouts yet.
-
Uses built-in Default Base64 Logo! (no more .ico file needed)
-
New shortcuts for Elements
-
I = InputText
-
B = Butt = Btn = Button
-
-
Convert user supplied button text to string just in case not a string
-
Parameter
icon
inWindow
call can be Base64 byte string in addition to filename
MikeTheWatchGuy 2019-04-05T19:57:23Z
import PySimpleGUI as g
Tossed this out for comments and wasn't well received, so leaving everything as sg
. I'm likely to use g
from time to time in stuff I post in Issues, and other places where I want to be brief or have the layout a little less cluttered.
This is likely to be the new import statement I'm going to use going forward.
PySimpleGUI
As you might have noticed in the prior announcement post, of more shortcuts for Elements, it is the layouts that I'm most interested in simplifying at the moment.
I don't think there's going to be a huge objection to this other than mixing and matching code is going to be a problem.
(Start lament)..... THIS is the kind of change I would like to be able to assign to my dev team and have them change all of the Demo Programs, docs, cookbooks and repl.it's for the project. But, alas, there is no PSG Dev Team just yet. Need a few more months for that one.
(End lament)
I'm unsure just how global I should MAKE a change for this import versus simply using it going forward.
MikeTheWatchGuy 2019-04-05T22:28:31Z
ANDROID!!!!
It's finally happened.... PySimpleGUI is running on Android!
This "screen shot" is of my FirePad running the widget summary (minus the image)
There is an ongoing issue providing instructions on how to do this.
1288
The method is based on using termux. Use it to install Python, natively on Android. You're not running PySimpleGUI code on one of those Python Apps from the app store. No, you're running Python 3.7.3 on Android's Linux. Then you do a pip install of PySimpleGUIWeb
... Run pip to install it?? Damn, it doesn't get any better than this!
You do not need to "root" your device in any way.
How many "This changes everything" moments can PySimpleGUI have??
Wow.... huge thank you to the Remi team and to @MisterY for pulling it all together and showing us the path!
MikeTheWatchGuy 2019-04-07T23:26:14Z
0.20.0 07-Apr-2019 PySimpleGUIWeb
Main purpose is to get the Output Element released so that Prints will go to window!
-
Output Element WORKS!! Can re-route stdout to window
-
Added Idle function to Remi MyApp for stdout re-route (thanks Davide!!)
-
New Shortcuts:
-
I = InputText
-
B = Btn = Butt = Button
-
-
Removed temp size in Multiline setup
-
Button - convert button text passed in into a string
-
Added support for base64 Images in Image.Update but it's not working! Don't use!
-
Changed web_update_interval=.0000001 from 0 (YIKES I HOPE SOMETHING DIDN'T BREAK!)
MikeTheWatchGuy 2019-04-09T17:49:01Z
Tic tac toe....and Reddit Observations
This sure got a lot of attention in the past few hours on Reddit.
https://www.reddit.com/r/learnpython/comments/bb598q/way_to_get_graphics_in_my_tic_tac_toe_game/
As usual, I was drawn in to comment. No one was recommending PySimpleGUI after all :-) And damn, THIS is what the package was written and meant to be. "My First GUI"(tm)
I'm starting to see a pattern in "uptake" of people supporting PySimpleGUI. The more established programmers are the most "resistant" or skeptical or whatever label may fit as it's difficult to not be super-biased when pigeonholing people.
It's the newbies that gravitate towards PySimpleGUI. It's those actively looking for a solution to a problem they've not solved before.
Not saying these are the only people using PySimpleGUI, but does seem to be who are most apt to give it a try.
I'm sure people are tired of me recommending this package, but damn, I honestly and really do believe what I post. If PySimpleGUI is a great fit, I say so. If it's not, I'm not going to push it.
Anyway, the lesson I think I'm learning is that there is no converting those that are skeptics. Evidence is not part of the equation.
Sorry to be making noise about Reddit again.... oy... but it is where I learn the most. It's where I get exposed to new users, often one user at a time.
And it's the users that help make this package what it is. It's the USERS that bring in the new ideas. I wouldn't be working on getting PySimpleGUI running on Android had it not been for a user. SO many features and architectural directions were proposed by people using the package. The more of you there are out there, the more good ideas that are brought to this project.
MikeTheWatchGuy 2019-04-10T23:13:07Z
0.21.0 10-Apr-2019 PySimpleGUIWeb
This was a needed addition. By setting the disable_close
parameter in your call to Window, it will allow you to close your browser and to reconnect with your application as if your browser never closed. You will not be notified in fact that it's closed.
If you want the user to be able to exit, you'll need to supply and Exit button of some kind that will in turn call Window.Close
.
This seemed like a must Android programs
- If
disable_close
parameter set in Window call, then Remi will not disconnect when browser closed. Great for reconnecting.
MikeTheWatchGuy 2019-04-11T22:39:56Z
ALL Ports Updated - PySimpleGUI, Qt, WxPython, Web
And the laziness continues.
Windows just got easier to create!
The SECOND parameter to a Window call is now...... layout.
You can now specify the layout as part of the call to Window itself. You no longer need to add .Layout to the end of your window calls, unless you want to.
This
Becomes this
If you want to play it safe for a while so that it catches an attempt at running with an older version, you can specify the parameter name in the call....
Of course, make SURE you've installed the latest update from PyPI or GitHub prior to doing this change or self you won't be setting the layout parameter, you'll instead be passing your layout in as the default_element_size, what was the second parameter.
This should make things look much easier for beginners! No "chaining" required to create a window.
Since this is a somewhat important API change, I made it across the board and did a PyPI push of all 4 ports. Whew! Everyone better be damned grateful 😃
MikeTheWatchGuy 2019-04-21T18:47:57Z
0.23.0 21-Apr-2019 PySimpleGUIWeb
Getting this Graph Element up and running is going to really propel a looking GUIs along. You can make bar charts, line charts, do math stuff, draw images, make games, animate stuff, etc.
I'm building up stuff to be able to make a simple game for Android.
-
GRAPH ELEMENT almost done!
* DrawLine
-
DrawRectangle
-
DrawPoint
-
DrawCicle
-
DrawText
-
Erase
-
Move
-
MoveFigure (by a delta amount)
-
RelocateFigure (draw to a new spot)
-
Update - for background color change
-
Enable events works for single clicks (no drags yet)
-
-
Changed Image element to use SuperImage class
-
Image element works better?
-
Base64 not yet working
-
MikeTheWatchGuy 2019-04-22T22:53:11Z
3.29 22-Apr-2019 PySimpleGUI
Added the new RelocateFigure to PySimpleGUI so that the Web and Tkinter version can both run the same code.
-
New method for
Graph
-RelocateFigure
-
Output Element no longer accepts focus
MikeTheWatchGuy 2019-04-23T19:50:36Z
New pymunk
based demo
Check out the new demo that integrates pymunk into both PySimpleGUI and PySimpleGUIWeb.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Graph_pymunk_2D_Graphics.py
I want to try and use it to create a simple 2 player game to be played between 2 phones.
I'm terrible at thinking of game stuff.
Maybe it can be used to make Pong?
Here is what the ball test looks like on tkinter and in a browser with Remi.
This is the browser version. Only changed the import statement.
Or start the balls in a random location and speed up the time....
MikeTheWatchGuy 2019-04-23T23:31:53Z
0.24.0 PySimpleGUIWeb 23-Apr-2019
-
Enabled SuperImage class to accept base64 imagees
-
Now use an SvgGroup to hold all of the drawing items
-
Circle can now set outline color
-
DrawImage still isn't working
-
Move isn't working
-
Added Relocate for group
-
Lazy buttons - Up, Down, Left, Right(()
- Creates buttons with arrows on them as text
-
Base64 support for Image Element
MikeTheWatchGuy 2019-04-26T18:00:14Z
0.25.0 PySimpleGUIWeb 25-Apr-19
-
DrawImage method for Graph now takes BOTH filenames and base64 variables
-
Fix for DrawRectangle
MikeTheWatchGuy 2019-04-26T18:04:16Z
New Demo Program Added - Demo_Script_Launcher_Realtime_Output.py
I've been using this technique to output shell / subprocess output in realtime for things like the EXE maker. But, I had not officially released this streamed output model anywhere in the demo code programs so it seemed like the right time.
Here is the "Run Command" function that makes it all possible:
def runCommand(cmd, timeout=None, window=None):
""" run shell command
@param cmd: command to execute
@param timeout: timeout for command execution
@param window: the PySimpleGUI window that the output is going to (needed to do refresh on)
@return: (return code from command, command output)
"""
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = ''
for line in p.stdout:
line = line.decode(errors='replace' if (sys.version_info) < (3, 5) else 'backslashreplace').rstrip()
output += line
print(line)
window.Refresh() if window else None # yes, a 1-line if, so shoot me
retval = p.wait(timeout)
return (retval, output)
MikeTheWatchGuy 2019-04-28T19:12:29Z
PyGame Integration
Lately I've been playing around with game related stuff because I want to build a demo application that runs on Android and allows 2 people to interact at the same time, looking at the same screen. It's a perfect setup for a game.
The problem, however, is that some of these packages do not support ARM. The pymunk 2D engine is a good example. Runs great on Windows, Linux, but wouldn't pip install correctly on Android using Termux.
I doubt there will be a way to integrate PyGame to PySimpleGUIWeb, but perhaps there is a way. I've asked the fine folks at Remi (@dddomodossola) to see if there's a way of hooking in (Issue here)
In the meantime, I've posted 2 Demo programs for use with the tkinter version of PySimpleGUI. The 2 Demos are:
-
Super minimal. Sets things up for you to begin. It will take a button click and draw a circle.
-
Snake Game - it's a game I lifted from the net. It runs inside of a PySimpleGUI window (tkinter)!!
MikeTheWatchGuy 2019-04-28T20:23:19Z
Super Mario PyGame integration example
Just located this Mario Brothers source code and wanted to see if I could run it inside of a PySimpleGUI window. It took a while to figure out the Mario code. I found the 3 places I needed to make a change. 1. Initial setup of the screen
-
Passing the window variable to main program
-
Added window.Read() call and event loop contents to the "Main Loop" in the game
MikeTheWatchGuy 2019-04-28T22:16:17Z
Android Games On the Way! PySimpleGUI and pymunk running on Android....
This is a "game" that is running on my Android tablet. It's a proof of concept kind of thing. I managed to work with the pymunk team to get pymunk up and running on Android. I'll add the commands you need to enter into Termux with the code.
I connected to it from my PC. Both screens show the same thing and both react to input. It should make for a good gaming experience between you and your friends. You write and run your code on your device (phone, etc), and tell your friends your IP address so they can connect.
That makes a couple of different game engines that I managed to integrate with today.
MikeTheWatchGuy 2019-04-30T19:40:15Z
PyGame running inside PySimpleGUIWeb
Check this out!! I've been getting a LOT of help from the Remi project. Without Davide's help I wouldn't be able to do any of this.
I need to solve a sound problem as I'm not hearing any sound when using PySimpleGUIWeb. I do have sound when using the tkinter PySimpleGUI so I'm pretty sure it's going to be possible, at least when played on a local machine.
I wonder if sound could be routed to go out the browser such that anyone connected to the device will hear the sound.....
MikeTheWatchGuy 2019-05-01T22:19:23Z
0.26.0 PySimpleGUIWeb 1-May-2019
-
Combo - converts values into a list of strings
-
Image.Update is working with both filename and base64 (but no size controls yet)
-
Window - new parameter - return_key_down_events. Normally it's key up events that are returned from Read calls
-
Returning keyboard input works!
-
Turned off Remi Logging completely (may be a bad idea. can change it back)
-
Rearranged code so that same code is used for first window and following windows
-
Window disable_close parameter controls wether or not server keeps running after user disconnects
MikeTheWatchGuy 2019-05-01T22:24:14Z
Window(title, layout, ...)
changed in docs
The Readme and Cookbook have been updated to use the "new-style" window call. The layout is specified as the second parameter to Window.
All of the statements that looked like this:
were changed to look like this:
It will help out the folks with very little Python experience. Now making a Window is a single function call instead of a chained object.
Truth is that I'm lazy and was tired of typing layout twice for no good reason.
MikeTheWatchGuy 2019-05-02T20:11:33Z
Window.FindElement('_KEY_')
changed in docs to Window.Element('_KEY_')
Continuing with the updates to Readme and Cookbook (which have not been updating on the read the docs site since MARCH!)
I went through those 2 docs and changed all of the calls to FindElement
to Element
.
I have been using the short-form (Element
) in all of the code I've written in the past 3+ months. If you've followed this project, you know just how lazy I am. And I don't think that dropping the "Find" from the call is going to confuse people.
Now I just need to make all these changes to the demo files too!
MikeTheWatchGuy 2019-05-03T14:01:54Z
Overseas Users
In order to learn more about how people use PySimpleGUI, I go on the hunt for stuff people make or write about the package.
There's a vibrant overseas community of users, Russia, China, ...
I ran into this interesting list today.
http://bubuko.com/infodetail-3038936.html
It claims to be a list of the Python standard library packages that you may find useful:
I scrolled down and saw the GUI section which read:
GUI
Tkinter: can be replaced by pysimplegui, super easy to use
Python Software Foundation, are you listening? 😉
MikeTheWatchGuy 2019-05-03T16:43:52Z
Drawing with PySimpleGUIWeb
I've been adding the drag code for the Graph Element. This code returns the mouse position when inside of a graph element. It's what is required for doing things like this:
It doesn't have mouse down/up detection yet which means I get events if the mouse is down or not. Have to get the code working so that events are only returned when the mouse button is down. SOON!
MikeTheWatchGuy 2019-05-03T18:28:34Z
More Drawing
I've got the mouse up/down working now so that drag events are only returned when a mouse button is down.
The result....a better "drawing app", complete with ability to pick colors:
And it came to less than 30 lines of code.
import PySimpleGUIWeb as sg
layout = [ [sg.Text('Drawing App')],
[sg.Graph((400,400), (0,0), (400,400), enable_events=True, key='_GRAPH_',background_color='lightblue', drag_submits=True)],
[sg.B('OR', button_color=('orange', 'orange')), # Pen color orange
sg.B('BL', button_color=('black', 'black')), # Pen color black
sg.B('RD', button_color=('red', 'red')),], # Pen color red
[sg.Button('Exit'), sg.B('Erase')]]
window = sg.Window('Window Title', layout)
prev_point = None
line_color = 'black'
while True: # Event Loop
event, values = window.Read()
if event in (None, 'Exit'):
break
if event == 'Erase':
window.Element('_GRAPH_').Erase()
elif event == '_GRAPH_':
if values['_GRAPH_'] == (None, None):
prev_point = None
if prev_point is not None:
window.Element('_GRAPH_').DrawLine(prev_point, values['_GRAPH_'],line_color, 2)
prev_point = values['_GRAPH_']
else:
line_color = {'OR':'orange', 'BL':'black', 'RD':'red'}[event]
window.Close()
MikeTheWatchGuy 2019-05-03T21:55:53Z
PySimpleGUIWeb - A Progress Meter
It's not the ProgressMeter Element....yet.. but it may turn out to be at some point soon.
I've been working hard on the Graph element and the drawing primitives. After reading an Issue on the Remi site where Davide pointed out that a Progress Meter could be drawn manually quite easily I decided to give it a shot using PySimpleGUIWeb.
Here's a meter that went from 0 to 1000
And this is the entire program that does it. If I in-lined everything and didn't have the constants at the top, it would have been
import PySimpleGUIWeb as sg
BAR_SIZE = (200,20)
MAX = 1000
BACKGROUND_COLOR = 'gray'
BAR_COLOR = 'red'
def draw_bar(graph:sg.Graph, current, max, color):
graph.Erase()
graph.DrawRectangle((0,BAR_SIZE[1]), (int(BAR_SIZE[0]* current/max),0), fill_color=color)
def main():
layout = [ [sg.Text('Progress Bar Simulation')],
[sg.Graph(BAR_SIZE, (0,0), BAR_SIZE, background_color=BACKGROUND_COLOR, key='_GRAPH_' )],
[sg.Button('Exit')]]
window = sg.Window('Simulating a Progress Meter', layout)
graph = window.Element('_GRAPH_')
for count in range(MAX): # Event Loop
event, values = window.Read(timeout=1)
if event in (None, 'Exit'):
break
draw_bar(graph, count, MAX, BAR_COLOR)
sg.Popup('Maximum amount reached... exiting application')
window.Close()
main()
or if you want to in-line everything, then it's only 15 lines of code in total, for everything. Wow, PSG rocks...
import PySimpleGUIWeb as sg
layout = [ [sg.Text('Progress Bar Simulation')],
[sg.Graph((200,20), (0,0), (200,20), background_color='gray', key='_GRAPH_' )],
[sg.Button('Exit')]]
window = sg.Window('Simulating a Progress Meter', layout)
graph = window.Element('_GRAPH_')
for count in range(1000): # Event Loop
event, values = window.Read(timeout=1)
if event in (None, 'Exit'):
break
graph.Erase()
graph.DrawRectangle((0, 20), (int(200 * count / 1000), 0), fill_color='red')
window.Close()
Oh, and it works with tkinter too!! Just change the import statement and you get this nice window:
MikeTheWatchGuy 2019-05-04T22:49:59Z
Repl.it Jam Starting NOW..... Ends tomorrow at 6:00 PM EST
I hesitate to post this because I don't want any competition, but at the same time, if they see a flood of people using PySimpleGUI for this Jam, then it'll get written about.
So... why not share it?!
Here is the full text of the annoucement:
Hello jammers! This jam is going to be a bit different. In the past you've always had a theme your project you needed to follow. This time, you have a task. In this scenario, you've been hired by Lottery Royal, the world's first lottery based battle royal game. The LR team wants to analyze previous lottery winnings, so they can replicate those events in game. Your job is to create a program, that will display all the information in a readable way. The team doesn't care what you use, as long as they can use it without much trouble. The program must read the data from a file, you cannot hard code the data. You can find your data here below.
Being a member of the LR team myself, feel free to ask me any questions in the appropriate channel. judging will also be done a bit differently. Due to the huge amounts of submissions, it has become very cumbersome to give in depth feedback. For this jam, participating admins, mods, and guardians will rate their favorite submissions. The submission that is most consistently picked highly will win!
The prize is the same as always. If you win, you'll get the super special and awesome Jam Champion role. In addition, you'll be allowed an emoji of your choice to the guild.
Now get started. Here's your data, and go make those GUIs!
https://catalog.data.gov/dataset/lottery-mega-millions-winning-numbers-beginning-2002
Your judges are @Mosrod, @kpasta, @timchen, @katya, @Edwin (Lightning Fast / EanKeen), and Mwah.
When the jam ends, this form will close shortly after. When you're finished, post your project here: https://forms.gle/EPn3rJqffMSTWXJL9
Google Docs
Code Jam Submissions!
Put your working repl here! This will close after the jam is over.
MikeTheWatchGuy 2019-05-08T12:23:09Z
PySimpleGUI Wins Repl.it Code Jam
Used PySimpleGUI to enter this code jam:
This was the entry:
https://repl.it/@PySimpleGUI/Lottery
Have to say it was a satisfying victory on a number of levels. One was that while I've been using repl.it for these awesome PySimpleGUI examples, it's actually a much bigger tool than that. Python is but one of many languages that it can run. There must be 20 or 30 languages / environments on the available environments list.
Python's tkinter was the indirect winner. It IS possible to create an attractive GUI using the plain tkinter version of PySimpleGUI. Thankfully it's the furthest along development wise. I was able to throw quite a bit of code from Demo Programs that were already written like integrating with Matplotlib to make bar graphs.
In total I spent maybe 3 hours on the entry.
My favorite feature is the "Search" tab and the sliders that are used to search and show the results in realtime. That feature was likely the thing that got it across the line.
It was coded quite inefficiently. I should go back and combine the create figure calls that are all identical except for the labels. But, was in a hurry as it was a 24 hour thing and neatness didn't count quite so much.
So, was a good day for Python and PySimpleGUI.
MikeTheWatchGuy 2019-05-08T19:44:01Z
0.27.0 PySimpleGUIWeb 8-May-2019
These changes enabled some of the demos to run, like the Game of life which you can find running here:
https://repl.it/@PySimpleGUI/Conways-Game-of-Life-Web
-
Changed default icon from string to bytes
-
New Text Update to match newer call parameters
-
Added image_subsample, image_size parms to be backward compat. Note - not enabled
-
SuperImage changes - load both base64 images and files
-
Fix for DrawRectangle
-
Added data parm to DrawImage
-
Added DeleteFigure
-
Tab Support
-
Just barely beginning
-
May or may not work
-
-
Window new class variable - AllKeysDict
-
Contains dictionary of all elements and keys
-
Now used by FindElement / Element calls for quick lookup
-
-
Fix for Column elements and rows that didn't line up. Changed tk_row_frame style
-
Graph Element
-
enable_events works
-
drag events works
-
click events works
-
MikeTheWatchGuy 2019-05-08T21:03:07Z
PySimpleGUI Designer!
You asked for it... now you've got it.
Check out the work by this amazing PySimpleGUI teacher....
https://youtu.be/dN7gXwnNoBA
What an amazing accomplishment! Wow....
MikeTheWatchGuy 2019-05-10T15:50:13Z
Drawing Primitives Used for Line Graphs
PySimpleGUI is awesome for making dashboards. The reason is that drawing your own custom bar and line graphs is much easier to do using PySimpleGUI than it is to do it in Matplotlib.
In this example code, a "Graph" is created with 0,0 being at the bottom left and (500,500) at the upper right. Think of it like the + portion of a normal math graph. This means to make a line graph over time you vary X from 0 to 500 and your Y value is 0 to 500 depending on what your value to be graphed is.
Check out this amazing screen shot of a tkinter, Qt, and Web based port of PySimpleGUI produced with the exact same source code:
Here is the code that was run:
import PySimpleGUIWeb as sg
from random import randint
layout = [[sg.Text('Line Graph Simplicity')],
[sg.Graph((500,500), (0,0), (500,500), key='_GRAPH_')],
[sg.OK()]]
window = sg.Window('Example of Line Graphing In PySimpleGUI', layout)
while True: # Event Loop
event, values = window.Read()
if event is None:
break
# This portion draws the graph
window.Element('_GRAPH_').Erase()
prev_point = (0, 0) # start drawing in bottom left corner (0,0)
for x in range(500): # loop through X values
y = randint(0, 500) # make up a Y value
window.Element('_GRAPH_').DrawLine(prev_point, (x, y)) # do the actual drawing of the line
prev_point = x, y # remember where to begin drawing next time
MikeTheWatchGuy 2019-05-11T19:22:31Z
Menus for the web!
The PySimpleGUIWeb port is nearing an Alpha / feature semi-complete level. I think the only major thing left is Trees. All of the other Elements are pretty much done.
They may not have all of their options exposed (changing the fonts, etc), but the basics are all there which means the remainder I can fill in as features are requested.
I hope to get the Wx Port up to this level too soon.
MikeTheWatchGuy 2019-05-14T00:20:27Z
The magic of Type Hints and PyCharm
The code-completion feature of PyCharm goes PERFECTLY with PySimpleGUI. So does its clear display of a functions named parameters. This is super important when you have calls with many named parameters, like PySimpleGUI has. PySimpleGUI relies on named parameters EVERYWHERE.
MANY TIMES you will learn more about a feature's possibilities by looking at the parameters than looking at the docs. Sorry, but the docs lag the code.
Advice you can't go wrong with....
USE PyCharm WITH PySimpleGUI
Back to type hints.
You will see this kind of code in the PySimpleGUIWeb code:
Then anytime I write
self.Widget.
in one of the other class functions, it will show me all the cool things that a Remi Button has!
I use this trick sometimes by settings a variable to itself just so I can set the comment. A variable by itself didn't seem to be enough. You'll see this in ALL of the ports:
It's a way of "check pointing" the variable. Saying, at this point, the variable element should be a class variable Graph. Then when I type element.
it will show me all the things that a Graph.
has to offer.
I can't tell you what a lifesaver it has been to use this. It's safe because it's all done in the comments and yet with PyCharm it magically works.
MikeTheWatchGuy 2019-05-14T17:17:40Z
PySimpleGUI on Git gets new Transparent Window feature
There is a new parameter to the Window call....
transparent_color
Any place in your window this color is encountered will be made see-through. Often other GUI SDKs will use a green color for this as it lessens the likelihood that you have this color occurring naturally in your window.
You can also modify this value at runtime by calling:
The best use of this is for the loading animations where you want just the animation to show on top of the other windows
The function PopupAnimated
now takes advantage of this new capability and the results look fantastic.
When applied to a window in general, the results are a little confusing.
The standard test window looks like this:
Calling window.SetTransparentColor
passing in green as the color has this effect:
MikeTheWatchGuy 2019-05-14T18:55:09Z
New Demo - Long Running Operations
OK, I've finally had enough of these questions:
**_
What do I do when my function takes so long to complete that it freezes my GUI?
_**
My standard reply of "you spin it out into a task" isn't good enough. To be a PySimpleGUI solution, you need to be able to deploy it right away. The 5 minute rule. One of the best ways for that is to supply a Demo Program.
This demo program shows one method of performing long-running operations with PySimpleGUI. You'll find the demo here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Threaded_Work.py
See what you think. Maybe there's a better way to architect it for use. I tried to keep it simple enough to understand and good enough to deploy in a project.
MikeTheWatchGuy 2019-05-15T19:47:41Z
0.28.0 PySimpleGUIWeb 15-May-2019
-
Menus
-
Yes, the full Menu Bar across the top of the window!
-
PLUS, you get more controls to set the colors and fonts
-
Works with menu keys too
-
Disabled items are not working however
-
Correctly returns menu events
-
-
Listbox
-
Correctly handling Update calls that change the list
-
Correctly returns a LIST of items (even if only 1)
-
-
Button Graphics!
-
Can specify either a filename or image data as the source
-
Update parameters image_data and image_filename work!
-
-
Fix in DrawLine. Wasn't returning the id
-
DrawRectangle fixes - transparent fill color is default. Correctly draws coordinates now
-
DrawImage seems to work with both data and files
-
enable_events parameter for TabGroups
-
Frame Element
- Behaves like a Column element for now since no official Remi Frame
-
Fix for popups that get data - New dictionary return values messed up popups. Needed to use keys internally
MikeTheWatchGuy 2019-05-16T17:15:05Z
New Issue Reporting Process Change
Some time ago I created a template to be used with Issue reporting. I spent time creating this template because it's needed. If I didn't need the information being requested, I wouldn't take the time to ask for it.
I've been letting it slide when people don't fill it out and instead continue to be free-form.
Issues that are filled out without the template will no longer be accepted. They will be REJECTED.
I'm spending way too much time ASKING for the information that I asked for up front. If you can't take a moment to fill in the fields, then I can't take the many moments more to ask you each of the questions one by one.
Sorry if this feels draconian, but it's simply how it has to be. There is ONE person fielding all of the Issues, creating releases for FOUR different ports, and documenting everything. I don't know how to support the growing user base without this kind of cooperation.
MikeTheWatchGuy 2019-05-25T18:55:32Z
The BEST User Community Ever!
I looked to the pip install stats today for the new Debugger. I expected a couple hundred people, at MOST, would give it a try. After all, the only place I mentioned it was on the GitHub site. It was only today that I made a Reddit post.
I was stunned to see that yesterday over 1,000 pip installed took place!
Here are the stats from pepy. What's funny about pip installs is that the package names are not case sensitive. I just now realized what PySimpleGUIdebugger looks like in all lower case!
pysimpleguidebugger
Yes, I've created a "Py Simple Guide Bugger". I bet there's some British translation of that phrase that isn't so nice. It sounds like I've created a "Guide to Screwing Things Up Really Easily".
These are ONE DAY numbers remember because it's only been out officially for 1 day:
MikeTheWatchGuy 2019-05-25T19:21:12Z
PySimpleGUI Version 3.30
It's been a LONG time evidently. I don't like dumping this much in at one time.
3.30.0 PySimpleGUI 24-May-2019
-
Rework of ALLL Tooltips. Was always displaying at uttuper left part of element. Not displays closer to where mouse entered or edited
-
New Element.Widget base class variable. Brings tkinter into the newer architecture of user accessibility to underlying GUI Frameworks' widgets
-
New SetTooltip Element method. Means all Elements gain this method. Can set the tooltip on the fly now for all elements
-
Include scroll bar when making visible / invisible Listbox Elements
-
New Radio Element method -
Radio.ResetGroup()
sets all elements in the Radio Group to False -
Added borderwidth to Multiline Element
-
Button.Click()
- new method - Generates a button click even as if a user clicked a button (at the tkinter level) -
Made a Graph.Images dictionary to keep track of images being used in a graph. When graph is deleted, all of the accociated images should be deleted too.'
-
Added
Graph.SetFocus()
to give a Graph Element the focus just as you can input elements -
Table new parameter -
hide_vertical_scroll
if True will hide the table's vertical bars -
Window - new parameter -
transparent_color
. Causes a single color to become completely transparent such that you see through the window, you can click through the window. Its like tineows never was there. -
The new
Window.AllKeysDict = {}
has been adopted by all PySimpleGUI ports. It's a new method of automatically creating missing keys, storing and retrieving keys in general for a window. -
Changed how
window.Maximize
is implemented previously used the '-fullscreen' attribute. Now uses the 'zoomed' state -
Window gets a new
Normal()
method to return from Maximize state. Sets root.state('normal') -
Window.Close() now closes the special
Window.hidden_master_root
window when the "last" window is closed -
Window.SetTransparentColor
method added. Same effect as if window was created with parameter set -
An Element's Widget stored in
.Widget
attribute -
Making ComboBox's ID unique by using it's Key
-
Changed Multiline to be sunken and have a border depth setting now
-
Removed a second canvas that was being used for Graph element.
-
Changed how no titlebar is implemented running on Linux versus Windows. -type splash now used for Linux
-
PopupScrolled - Added back using CloseButton to close the window
-
Fixed PopupGetFolder to use correct PySimpleGUI program constructs (keys)
-
PopupGetText populated values carrectly using the value variable, used keys
-
PopupAnimated finally gets a completely transparent background
MikeTheWatchGuy 2019-05-26T20:07:26Z
Happy 100,000 PySimpleGUI Users!
We've finally officially reached the 100,000 pip installs of the tkinter 3.0 port of PySimpleGUI. In other works, PySimpleGUI.py.
Here are the stats. Something pushed it up to 1,000 installs yesterday. It must have been the Debugger!
MikeTheWatchGuy 2019-05-26T20:18:43Z
PySimpleGUIdebugger
has been renamed to imwatchingyou
I did this name quickly to try and nip it before it becomes wildly popular and runs away with itself.
I did it for a couple of reasons. Having PySimpleGUI in the name itself made no sense. It uses PySimpleGUI but that's all. It can debug anything including tkinter programs or Qt programs.
PySimpleGUI has a number of trolls following it around at the moment. Go figure. I got some insight the other day when someone complained about my package versus another package that had been around for a very long time, but failed to get traction.
Jealousy is not a fun emotion to experience nor be the target of. I feel kinda bad for these guys., It's a really shitty emotion, jealousy, to feel.
So, I'm renaming and escaping, to some extent, the PySimpleGUI brand.
MikeTheWatchGuy 2019-05-28T17:14:38Z
imwatchingyou
has consumed me, just as the web port has... sorry if you're waiting on an Issue
I just want to complete THREE more "features" on the project and I'll be done. :
-
Simply get better GUI layout overall.
-
Create a small, floating on top, thin/no border watcher window. Think tiny but powerful
-
Internal integration into PySimpleGUI itself
Full-Internal Integration
The last one I'm particularly excited about. It would be so cool if PySimpleGUI programs simply had a built-in debugger that's at your fingertips while you're experiencing a problem, not after!
My hope is to make one that can be launched anytime you want, particularly when things aren't going so well.
At the rate I'm moving it could be a day or two to get through these things so give me just a liitlte more time and it'll be wrapped up and done.
MikeTheWatchGuy 2019-06-10T04:04:16Z
imwatchingyou
Version 2.2.2 Released!
Finally got that monkey off my back.
Before diving back into the built-in version of the debugger, I'm going to be doing some work on the documentation. Working on having part of the docs auto-generated from the source code. So, lots of re-factoring to do so that only the user callable functions / methods are shown.
MikeTheWatchGuy 2019-06-10T14:04:29Z
3.38 PySimpleGUI, 1.38 PySimpleGUI27 10-June-2019 Released
Some changes that helped with the imwatchingyou project as well as user requests.
-
Multiline - now has a "read only" state if created as "Disabled"
-
Multiline - If window is created as resizable, then Multiline Elements will now expand when the window is enlarged, a feature long asked for.
-
Output Element expands in the Y Direction
-
"Expandable Rows" option added to PackFormIntoFrame allowing future elements to also expand
-
Error Element - silence_on_error option
-
Text Element wrapping - FINALLY got it right? No more "Fudge factor" added
-
PopupScrolled - Windows are now resizable
-
Option to "launch built-in debugger" from the test harness
-
Remember that the Debugger is still in this code! It may or may not be operational as it's one version back from the latest release of the
imwatchingyou
debugger code. This code needs to be integrated back in from that project.
MikeTheWatchGuy 2019-06-13T22:02:36Z
3.39 PySimpleGUI & 1.39 PySimpleGUI27 13-June-2019
-
Ported the imwatchingyou debugger code into PySimpleGUI code
-
Replaced old debugger built-in code with the newer imwatchingyou version
-
Required removing all of the 'sg.' before PySimpleGUI calls since not importing
-
Dynamically create the debugger object when first call to
refresh
orshow
is made
-
-
Started the procecss of renaming Class Methods that are private to start with _
-
Needed for the automatic documentation generation that's being worked on
-
Fixed crash when clicking the Debug button
-
Fixed bug in DeleteFigure. Needed to delete image separately
-
Added more type hints
-
New
TabGroup
methodSelectTab(index)
selects aTab
within aTabGroup
-
New
Table.Update
parameter -select_rows
. List of rows to select (0 is first) -
Error checking in
Window.Layout
provides error "hints" to the user-
Looks for badly placed ']'
-
Looks for functions missing '()'
-
Pops up a window warning user instead of crashing
-
May have to revisit if the popups start getting in the way
-
-
New implementations of
Window.Disable()
andWindow.Enable()
-
Previously did not work correctly at all
-
Now using the "-disabled" attribute
-
-
Allow Comboboxes to have empty starting values
-
Was crashing
-
Enables application to fill these in later
-
MikeTheWatchGuy 2019-06-14T17:07:38Z
Documentation Overhaul
Several announcements to make. This is the first.
In the process of having portions of the documentation be generated from the code itself. It makes sense and will keep the docs up to date with the latest features. There are a high number of features that are in the code now that are not documented. Not good.
I'm serious enough about this that I hired a contractor to help make the magic happen. MUCH better docs ahead. (There are already a bunch of fixes to the Readme that he did already released)
MikeTheWatchGuy 2019-06-14T17:13:52Z
Back to Android - PyDroid3 !
I tried PyDroid3 for Android again. PySimpleGUI pip installed perfectly and ran flawlessly.
If you want to run your code using PyDroid3, you must add
import tkinter
to your files that import PySimpleGUI. It must be what triggers to use tkinter or something. I just know that without it, the program crashes.
What's fantastic about how it works is that your application and only your application is visible when it's running. It's like having a small windows desktop with as many windows as you care to make. I was even able to invoke the built-in debugger and windows were popping up for it.
I will take some photos of apps running on my Galaxy tablet soon.
It's far from a standalone solution. It LOOKS the most standalone of everything I've done on Android. Recall that Termux ran in the browser so it certainly didn't take over the screen. I am hoping for a way to directly launch my application from Android but haven't figured it out.... yet....
I highly recommend trying this one out because the success rate is really high. I was able to download the GitHub and thus access all of the Demo Programs. I added the import tkinter
to the top of the files and poof they're running on Android.
MikeTheWatchGuy 2019-06-14T17:44:37Z
Layout Verification Checks
Made some changes in the "Layout" code in an attempt to help people with the syntax of their layout
variable. We've all done it.., put a ] in the wrong place... didn't add () to an element name (e.g. sg.Cancel).
Now there's a popup that will give you a hint about what the problem is and where it is in your layout. Hopefully this is better than crashing.
Here's an example. The ] should be placed on the end of the next to the last line. Instead it's at the end. The number of [] balances out fine so PyCharm doesn't complain.
layout = [[ sg.Text('Window 1'),],
[sg.Input(do_not_clear=True)],
[sg.Text('', key='_OUTPUT_', size=(20,1)),
[sg.Button('Launch 2'), sg.Button('Exit'), sg.Debug()]]]
When you attempt to do the layout while creating the Window, you'll see this popup:
Instead of crashing, PySimpleGUI tosses out the offensive parts and continues the layout.
In this example, the resulting window was:
Here we see the last thing in the window is an Input
Element, indicating that stuff after that Input
Element is bad. Indeed, the first line in the layout that's bad is the Text
that follows the Input
Fixing the layout you'll see the full window:
Note the new "Debug" button in this layout.
MikeTheWatchGuy 2019-06-16T17:20:29Z
Projects using PySimpleGUI - Add boids to the list....
I saw this article that a friend passed to me and thought it was a great candidate for integrating with PySimpleGUI. After all, they're just balls being moved around.
https://medium.com/better-programming/boids-simulating-birds-flock-behavior-in-python-9fff99375118
So, I kicked out the calls to P5, the old graphing library, and added in PySimpleGUI.... with a twist. Since we've got a GUI, why not use it? I don't know the algorithm enough to tweak with any of the algorithm's variables, but I do have control over the number of birds at any time.
The slider was a PySimpleGUI addition. With it you can slide it down to the point the speed is to your liking.
I forked the original code, made the modifications and posted a Git here along with a new Readme:
https://github.com/MikeTheWatchGuy/boids-PySimpleGUI
It took roughly 1 hour to do this "port".
Hold on for the AMAZING part!
I decided to give the Web port a try. I changed the import from PySimpleGUI to PySimpleGUIWeb and POOF... it just worked!
Unfortunately the Qt port didn't work so well :-( In theory it should run exactly the same way, but there seems to be some bug in the movement translation.
Here you can watch it on the web (very slowly)
https://repl.it/@PySimpleGUI/Boids-on-PySimpleGUI
MikeTheWatchGuy 2019-06-17T19:01:38Z
PySimpleGUI Ver 4.0
Welcome to the new world of PySimpleGUI programming. 4.0 is available on GitHub, but not yet released to PyPI.
So where are the major hubbub features that's causing this bump from 3.39 (39 releases?!) to 4.0??
In a word....
DOCUMENTATION
It just got MUCH better thanks to the efforts of @nngogol. It's not all done yet, but at least the doc strings are in the code and are IMMEDIATELY usable.
In PyCharm, it's a real JOY to program PySimpleGUI now. And for those of you that rely on the written word, the new README is being generated from the code!! Yes, finally, the API definitions will be kept UP TO DATE with the code.
The new readme should be coming in the next few days. Until then, enjoy the fully documented API calls (pretty much.... especially the Elements)
I'm really excited about the work that's already been done.
Let's take an example. I have the "quick documentation" automated popup turned on:
This is the same as pressing Control-Q
while having the cursor on the name of an Element / Function call.
Here's what happens in PyCharm when I pause with my cursor on the Text Element:
There are 2 different "Signatures" you'll see for the function. One is a simple, showing the defaults view. Just below that is a detailed explanation of all of the parameters.
And it's going to get even better for the folks that like to read the docs online. More coming soon. For now, enjoy those parameter descriptions!
MikeTheWatchGuy 2019-06-18T17:42:34Z
__version__
PySimpleGUI is finally getting a version string. That should make a few of you happy that requested fthe change some time back. It will be the first line of code in the PySimpleGUI.py file. At the moment, we're sitting at version 4.0.0, but it is has not been posted to PyPI, so the version string is:
4.0.0 Unreleased
To indicate that the file has not yet been posted to PyPI, I am adding the word unreleased
to the end of what will be (most likely be) the new version number. NOTE that it's possible and will in fact happen a LOT, that the code with version 4.0.0 Unreleased
downloaded on one day may be different than the same version 4.0.0 Unreleased
that was uploaded today. In other words, "Unreleased" means the contents are fuzzy and can vary.
If the version were simply 4.0.0
with nothing trailing the numbers, then that is an official release and will not vary from one copy to another.
I have not yet settled on an official format for the version string. I need to do some research on the norms and how I might be able to break them.
At this time, I don't believe there is a need to include the port in the version string. It's tempting, but strictly speaking not required as you can figure out the port by looking at the import statement.
What I have been using lately, that's been a real lifesaver, is to display the value of sg
(from the statement import PySimpleGUI as sg
By going into the PySimpleGUI debugger and looking at the value or adding a print statement - print(sg)
you are able to see exactly WHERE you're PySimpleGUI.py file is located. This is THE definitive way of knowing what version is running in your code.
Since the PSG debugger is turned on by default, if you are ever in doubt as to which PySimpleGUI.py file you are running, you can find this very easily by following these steps:
-
Start your application
-
Press the
BREAK
key on your keyboard - causes the debugger pop-up window to show -
Look at the value of
sg
in the popup window
You can take things a step further and get the version of tkinter. To do this, you'll need to bring up the debugger window (not the popup). You can press Ctrl+Break
or right click on the popup window's text and choose 'Debugger'
From there you can use the REPL tab to both import tkinter and to view the version number
You can also view it by adding it as a "custom watch" on the "Variables" tab
To do this click on the button:
Then type this into the Custom Watch field:
tkinter.TkVersion
I find it a little odd that every system I have running Python is running version 8.6 of tkinter. This includes Windows. Mint Linux and a Raspberry Pi running Python (Python 3.4!).
Anyway, there's the long answer of what's coming in versioning of PySimpleGUI (and how to get PSG and tkinter versions while running using the built-in debugger).
MikeTheWatchGuy 2019-06-19T17:24:35Z
4.0.0 PySimpleGUI & 2.0.0 PySimpleGUI27 19-June-2019
Finally pushing this out the door!! Time for everyone to enjoy the new docstrings. No more mixed up understanding of parameters, at least for the primary tkinter port. The other port still need updating.
AND, this is the first release with the readme being generated. The project is still being developed so I expect there are likely some errors. Hopefully not enough to seriously hinder any newcomers.
Here are the changes that went to PyPI today
-
DOC STRINGS DOCS STRINGS DOC STRINGS!
-
Your IDE is about to become very happy
-
All Elements have actual documentation in the call signature
-
The Readme and ReadTheDocs will be generated going forward using the CODE
-
HUGE Thanks for @nngogol for both copying & adding all those strings, but also for making an entire document creation system.
-
-
New version string for PySimpleGUI.py
-
New parameter to ALL
SetFocus
calls.-
def SetFocus(self, force=False)
-
If force is True, then a call to
focus_force
is made instead offocus_set
-
-
Get - New Radio Button Method. Returns True is the Radio Button is set
-
Rename of Debugger class to _Debugger so IDEs don't get confused
-
User read access to last Button Color set now available via property
Button.ButtonColor
-
Rename of a number of callback handlers to start with _
-
Fix for memory leak in Read call. Every call to read lost a little memory due to root.protocol calls
-
Listbox.Update - New parameter - scroll_to_index - scroll view so that index is shown at the top
-
First PyPI release to use new documentation!
MikeTheWatchGuy 2019-06-24T14:45:00Z
ReadTheDocs is fully operational! http://www.PySimpleGUI.org
This site, http://www.PySimpleGUI.org, is super important as it is where ALL of the docs live. The Cookbook, Readme, Arch doc, everything.
We made a huge breakthrough yesterday. Now all of the 4.0 changes are in ReadTheDocs. Previously is was stopped at about the 2/3 point. Now it makes it to the end it is looks gorgeous.
Next thing I'll be doing to it is updating the text, adding the missing descriptions, etc.
MikeTheWatchGuy 2019-06-24T16:31:06Z
Documentation using Python's help
keyword
Because so many doc strings got dumped into
>>> help(sg.Listbox)
Help on class Listbox in module PySimpleGUI:
class Listbox(Element)
| A List Box. Provide a list of values for the user to choose one or more of. Returns a list of selected rows
| when a window.Read() is executed.
|
| Method resolution order:
| Listbox
| Element
| builtins.object
|
| Methods defined here:
|
| GetListValues(self)
|
| SetFocus(self, force=False)
|
| SetValue(self, values)
| :param values:
|
| Update(self, values=None, disabled=None, set_to_index=None, scroll_to_index=None, visible=None)
| :param values: (Default value = None)
| :param disabled: disable or enable state of the element (Default value = None)
| :param set_to_index: highlights the item at this index as if user clicked (Default value = None)
| :param scroll_to_index: scroll the listbox so that this index is the first shown (Default value = None)
| :param visible: change visibility of element (Default value = None)
|
| __del__(self)
|
| __init__(self, values, default_values=None, select_mode=None, change_submits=False, enable_events=False, bind_return_key=False, size=(None, None), disabled=False, auto_size_text=None, font=None, background_color=None, text_color=None, key=None, pad=None, tooltip=None, right_click_menu=None, visible=True)
| Listbox Element
|
| :param values:
| :param default_values: (Default value = None)
| :param select_mode: (Default value = None)
| :param change_submits: If True, pressing Enter key submits window (Default value = False)
| :param enable_events: Turns on the element specific events.(Default value = False)
| :param bind_return_key: (Default value = False)
| :param size: (common_key) (w,h) w=characters-wide, h=rows-high (Default value = (None, None))
| :param disabled: set disable state for element (Default value = False)
| :param auto_size_text: True if size should fit the text length (Default value = None)
| :param font: (common_key) specifies the font family, size, etc (Default value = None)
| :param background_color: color of background (Default value = None)
| :param text_color: color of the text (Default value = None)
| :param key: (common_key) Used with window.FindElement and with return values (Default value = None)
| :param pad: (common_key) Amount of padding to put around element (Default value = None)
| :param tooltip: text, that will appear the you hover on (Default value = None)
| :param right_click_menu: see "Right Click Menus" (Default value = None)
| :param visible: set visibility state of the element (Default value = True)
|
| ----------------------------------------------------------------------
| Methods inherited from Element:
|
| SetTooltip(self, tooltip_text)
| :param tooltip_text:
|
WORD OF CAUTION:
Note that not all methods have been properly renamed so that private methods start with _.
So, just be careful with using help
to make sure that the Method is one that's meant to be called by users. Working on this rename as quickly as I can.
MikeTheWatchGuy 2019-06-29T01:33:32Z
Pong Returns
Really early on in PySimpleGUI's history I ported a pong game that was written for tkinter. It wasn't much of a port because it made tkinter calls still.
This week I grabbed another version of pong and ported it, but this time it only uses PySimpleGUI drawing primitives. This means that it's portable! The Demo Program is called Demo_Pong_Multiple_Platforms
. In theory it should work on tkinter, Qt and Web ports, but the Qt port has some problems. However, the Web version did work!
Same source code for these 2 images, more or less. As you can see, I've got some problems still in the Graphics Primitives using PySimpleGUIWeb. It's nice to have a version that only uses PySimpleGUI calls. It means it should run on Android for example. That would be fun, especially if 2 phones were used!
(only just now noticed the difference in fonts between player 1 & 2. DOH! It's fixed now. Both are 60 point sized)
MikeTheWatchGuy 2019-07-06T17:47:48Z
Side By Side Comparisons - tkinter, PySimpleGUI
For the past several months I've been on the lookout for GUI programs or examples that can be used to directly compare and contrast an underlying GUI Framework versus PySimpleGUI (guess who's going to "win")
One way I'm going about this is to work with people that have an existing program that they may want to move to PySimpleGUI from _ GUI Framework. They have an existing program or prototype which gives us something to model / copy.
The other way is to keep an eye out on the web. Today I found myself looking through some download managers since one of our users has just written one and I wanted to see the "competitors". In my search, I ran across this tutorials page. It has a little program to show you some of the "Selection Widgets" found in tkinter.
Rather than letting PySimpleGUI to layout a compact window and let it size itself, I forced a particular size since that's what the tkinter code did and I was shooting for DUPLICATE the tkinter window. Here are the 2 windows:
OK, so they're not pixel for pixel identical. I could f*ck around with my code further or call this "close enough for normal people" and move on. So, I'm taking the "close enough" this time.
The verdict on code size.
To keep things "fair", I removed all blank lines from the code. I didn't do anything crazy like putting an if statement all on 1 line.
27 lines of code written directly in tkinter
10 lines of code written in PySimpleGUI
This directly supports that claim that PySimpleGUI programmers write 3 to 10 times less code than tkinter, WxPython, Remi and certainly Qt
Now, let's look at readability of the code. For this, I'll put some of the blank lines back.
Code written in tkinter only:
from tkinter import *
from tkinter.ttk import Combobox
window=Tk()
var = StringVar()
var.set("one")
data=("one", "two", "three", "four")
cb=Combobox(window, values=data)
cb.place(x=60, y=150)
lb=Listbox(window, height=5, selectmode='multiple')
for num in data:
lb.insert(END,num)
lb.place(x=250, y=150)
v0=IntVar()
v0.set(1)
r1=Radiobutton(window, text="male", variable=v0,value=1)
r2=Radiobutton(window, text="female", variable=v0,value=2)
r1.place(x=100,y=50)
r2.place(x=180, y=50)
v1 = IntVar()
v2 = IntVar()
C1 = Checkbutton(window, text = "Cricket", variable = v1)
C2 = Checkbutton(window, text = "Tennis", variable = v2)
C1.place(x=100, y=100)
C2.place(x=180, y=100)
window.title('Hello Python')
window.geometry("400x300+10+10")
window.mainloop()
Code written in PySimpleGUI
import PySimpleGUI as sg
data = ("one", "two", "three", "four")
layout = [[sg.Radio('Male', 1, default=True, key='_MALE_'), sg.Radio('Female', 1, key='_FEMALE_')],
[sg.Checkbox('Cricket', key='_CRICKET_'), sg.Checkbox('Tennis', key='_TENNIS_')],
[sg.Column([[sg.Combo(data, default_value=' ', size=(15,1), key='_COMBO_', pad=(0,0))]]), sg.Listbox(data, size=(25,5), key='_LISTBOX_')],]
window = sg.Window('Hello Python', layout, auto_size_text=False,default_element_size=(10,1), size=(400,300), element_padding=(10,20), margins=(20,20))
while True: # Event Loop
event, values = window.Read()
if event in (None, 'Exit'):
break
Can't wait for the Qt example!
MikeTheWatchGuy 2019-07-07T23:41:57Z
Thank you to all the awesome users!!
I'm super fortunate to hear from people frequently about their use of the package. It honestly has sustained me over the past year (on Jul 11).
Thanks for the notes, thanks for the suggestions. Some of the best features over the past 12 months have come from users. (I'll forever be grateful for the returning values as a dictionary suggestion early on)
I'm adding a FEW of the bits of notes, messages, emails that you guys/gals have sent. If you see your quote and want it removed, by all means speak up. It will be located in the readme and the ReadTheDocs version, and here in this post. No where else I can think of.
GUI Development does not have to be difficult nor painful. It can be FUN
What users are saying
(None of these comments were solicited & are not paid endorsements - other than a huge thank you they received!)
"I've been working to learn PyQT for the past week in my off time as an intro to GUI design and how to apply it to my existing scripts... Took me ~30 minutes to figure out PySimpleGUI and get my scripts working with a GUI."
"Python has been an absolute nightmare for me and I've avoided it like the plague. Until I saw PysimpleGUI."
"I've been pretty amazed at how much more intuitive it is than raw tk/qt. The dude developing it is super active on the project too so if you come across situations that you just can't get the code to do what you want you can make bug/enhancement issues that are almost assured to get a meaningful response."
"This library is the easiest way of gui programming in python! I'm totally in love with it ❤️"
"Wow that readme is extensive and great." (hear the love for docs often)
"Coming from R, Python is absolutely slick for GUIs. PySimpleGUI is a dream."
"I have been writing Python programs for about 4 or 5 months now. Up until this week I never had luck with any UI libraries like Tkinter, Qt, Kivy. I went from not even being able to load a window in Tkinter reliably to making a loading screen, and full program in one night with PySimpleGUI."
"I love PySimpleGUI! I've been teaching it in my Python classes instead of Tkinter."
MikeTheWatchGuy 2019-07-09T17:23:40Z
New Demo Program - Using threads for long tasks Demo_Multithreaded_Long_Tasks.py
This Demo has been a long time coming. Hadn't thought about it much until I received a new Raspberry Pi development system yesterday. Users have run into this problem, no doubt, and often don't know where to turn.
The complete newcomer to GUIs sometimes don't pick up on the "your GUI will freeze if you don't refresh it often". Attempts are made to perform tasks in their event loop that takes seconds or longer. It won't be long before Windows complains that your program has "Stopped Responding".
As a simple solution I wrote this Demo that uses a single thread to do the work. The concept here is that you can isolate your long-running work into a function that can be started up as a thread. When it's done, it sends a message to the GUI using a Queue.
You can see it running on Repl.it here:
https://repl.it/@PySimpleGUI/Threaded-for-doing-long-tasks
Here is what it looks like running there:
Of course with repl.it, the GUI itself is located in the upper right hand corner. Here's what it looks like running on my Windows machines:
It's located in the always growing Demo Programs area. You'll find it here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Multithreaded_Long_Tasks.py
MikeTheWatchGuy 2019-07-12T21:36:46Z
Happy Birthday! New Docs!
July 10th marked the 1 year mark for PySimpleGUI. I was looking at the release and only a few of the Elements had been created in the 1.0 release. Dictionary return values wouldn't come to be for quite some time. My how it's evolved.
1 year later and there are 4 ports underway
Running on Windows, Linux, Mac, Android, Raspberry Pi
Over 350,000 installs
Averaging about 300 visitors to the GitHub daily
Was shooting to release the new readme on the 1 year day, but missed it by a little. Oh well, that's how this project rolls.
Please understand that the documentation is not yet completed. I have a fair amount of doc strings to fix up.
The cool thing about this whole effort is that by doing these docs using doc strings, your IDE will automatically pick up the information and present it to you, showing you the different parameters in a call as well as explaining each of the parameters.
For example, with my cursor on the Radio
element, PyCharm brings up the documentation automatically:
You can access similar information by typing help(element or function)
at a REPL prompt >>>
Python will dump out all kinds of good info for you including not just the parameter meanings, but it also lists the member functions. Use these documentation tools to your advantage! They're better than anything available in the past.
There are still large sections missing, like info about the built-in debugger for example. So, the effort continues on. After getting the tkinter doc strings done, then it's time to turn to the other ports and do the same thing.
A big THANK YOU to all PySimpleGUI users that have helped make this package what it is today.
MikeTheWatchGuy 2019-07-12T21:42:57Z
More on docs....
Of course the best place to READ the docs is on ReadTheDocs (http://www.PySimpleGUI.org). There you'll get a nice table of contents down the left side. It's easier to navigate than the plain readme.
Last post showed an image of what happens when you put your cursor on a PySimpleGUI Element in your code. Let's see what happens when you do this with the other GUI packages.
Qt.... how about QRadioButton as an example:
hmmmm.... not much there... surely a button will have info...
Got some parameters this time, but zero explanation
If you're using tkinter
instead of Qt it's even worse. Every single tkinter call shows the same general purpose document:
MikeTheWatchGuy 2019-07-17T09:04:05Z
MikeTheWatchGuy 2019-07-19T22:27:23Z
Python 3.7.4 tkinter Is BROKEN - Not supported by PySimpleGUI
After much time spent by myself and multiple other parties, I've shown that the tkinter that's installed with Python 3.7.4 is broken. It does not display Table colors.
Python 3.7.2 does work and will be the highest level of Python 3.7 that PySimpleGUI will support for the time being. I'm not going to spend another minute debugging tkinter for the 3.7 team.
I'll add this to the readme / read the docs.
Sorry to all those that wasted time on this.
MikeTheWatchGuy 2019-07-20T02:48:25Z
New features for tables
I completed the Table colors Update support for Tables in PySimpleGUI. You can set the text and background colors of tables using the Update
method.
This particular feature and the massive addition of docstrings is inching us towards a 4.1 PySimpleGUI release.
MikeTheWatchGuy 2019-07-20T02:51:23Z
Ability to set background color of Tooltips using PySimpleGUI
I have exposed the background color for tooltips. You can set the variable:
TOOLTIP_BACKGROUND_COLOR
to any color string you want. You need to change the variable prior to creating your layout. Do it before making any PySimpleGUI calls.
MikeTheWatchGuy 2019-07-20T03:02:27Z
The cruel GitHub Issue Searching Results
As you can see I use GitHJub Issues for a lots of things besides just issues. The reason is really simple, when searching GitHub Issues for a problem, I definitely want these "notes", announcements, suggestions, templates, screenshots,etc, to be searched as well.
The cruel part is that GitHub shows results for these really long Issues, but when you open it up, you find THIS in the middle of the Issue:
WHAT!? Over 400 entries written are hidden. OK, so I manage to find this little box and I click it. What happens? Well, I see more, but then it's replaced with another little box
Oh, great, I'm "down to only'" 356 hidden entries". Search for "hidden entries", click again, searching, click, lather rinse repeat.
This happens for these Announcements as well as the screenshots.
I've tried to find ways of turning this off, but nothing has worked. So, it's time to break them apart so that all entries can be seen. It may take splitting into 3 or 4 or more Issues, but it's going to be worth it for sure as a lot of screenshots are hidden and a lot of good knowledge hidden as well.
MikeTheWatchGuy 2019-07-23T00:30:21Z
Pull Requests
Just updated the Issue that has the "Pull Request Policy" in it. I thought that since it's so short I'll just copy it here too.
TLDR - Not taking pull requests for core code. I'll still listen to your suggestions.
Pull Request Policy
I've talked about Pull Requests several times over the past year in the Announcements Issue. But, the way GitHub works, it hides a LOT of posts when you look at an Issue. The result is that even if you search for Pull in the Announcements Issue, you will not find the full set of posts.
Pull Requests - Not taking pull requests for core code
If you have a bug fix or suggestion for enhancement in the core code, I'm still interested in taking a peek, but I'm not doing direct merges.
Pull requests are already rare so I don't think it's going to affect much of anything.
There are a lot of reasons that I won't bother listing. Let's just sum it up as more efficient, much happier without them.
This first year has gone really well. I fully expect year 2 to be just as productive.
Still Have Something To Share?
Some users are submitting their "suggested code changes" as part of the Issue they are using to report a bug. I love these kinds of fixes and suggestions. I find them easier to digest and they don't feel like a bag of code has just been dropped into my lap that I must deal with.
This will rub a few the wrong way and for that I'm really sorry. Perhaps it's not in the spirit of Open Software to work in this manner but I hear from a lot more happy users right now than unhappy ones and so this really shouldn't have an impact.
MikeTheWatchGuy 2019-07-23T03:35:30Z
Updated Readme/ReadTheDocs and Cookbook
I'm REALLY sorry to all the newcomers that hit example #1 in the readme, the example using the "Designer tool" (pencil and paper). The problem is that the values
coming back from a Window.Read
call are going to be a dictionary rather than a list. These early example bits of code attempted to unpack the dictionary like a list which leads to crashes.
Instead of the pleasant 5 minute install and run, you likely had a 2 minute install process followed by a really large amount of time spent on trying to get the example to run. Sh*t! I'm really sorry about that.
Both the Cookbook and the main documentation have undergone a number of changes to both explain things better and removal of this kind of non-working crap! It all just got a little out of control there for a bit.
MikeTheWatchGuy 2019-08-04T18:00:29Z
Slow Going - FINALLY cramming out a release for PySimpleGUI 4.1
Sorry that it's so slow the past few weeks. These docs have been a real chore and continue to. There has never been such a long time between releases.
I'm pulling together release notes now, but it's going to take a while as there are 616 changes since to the last PySimpleGUI release and each are checked before the release will go out.
MikeTheWatchGuy 2019-08-04T19:09:39Z
PySimpleGUI 4.1 Anniversary Release! 4-Aug-2019
Long time coming. Docstrings continue to be a focus.
NOTE the Python 2 version is still in the works.
-
Version can be found using PySimpleGUI.version
-
New bit of licensing info at the top of the file
-
Types used in the doc strings. Also type hints in some comments. Because also running on 2.7 can't use full typing
-
Added using of Warnings. Just getting started using this mechanism. May be great, maybe not. We'll see with this change
-
Added TOOLTIP_BACKGROUND_COLOR which can be changed (it's tkinter only setting however so undertand this!)
-
Graph.DrawText. Ability to set
text_location
when drawing text onto a Graph Element. Determines what part of the text will be located at the point you provide when you draw the text. Choices are:-
TEXT_LOCATION_TOP
-
TEXT_LOCATION_BOTTOM
-
TEXT_LOCATION_LEFT
-
TEXT_LOCATION_RIGHT
-
TEXT_LOCATION_TOP_LEFT
-
TEXT_LOCATION_TOP_RIGHT
-
TEXT_LOCATION_BOTTOM_LEFT
-
TEXT_LOCATION_BOTTOM_RIGT
-
TEXT_LOCATION_CENTER
-
-
Flag ENABLE_TK_WINDOWS = False. If True, all windows will be made using only tk.Tk()
-
SetFocus available for all elements now due to it being added to base class. May NOT work on all elements however
-
Added Combo.GetSElectedItemsIndexes() - returns a list of all currently selected items
-
Fixed Listbox.Update - set_to_index changed to be an int, list or tuple
-
Added parent parameter to call to tkinter's askopenfilename, directory, filenames. Not sure why the root wasn't passed in before
-
Button.Update - also sets the activebackground to the button's background color
-
Graph - New parameter when creating.
float_values
. If True, then you're indicating that your coordinate system is float not int based -
Graph.Update - made background color optional parm so that visible only can be set
-
Frame.Layout returns self now for chaining
-
TabGroup.Layout returns self now for chaining
-
Column.Layout returns self now for chaining
-
Menu.Update menu_definition is now optional to allow for changing visibility only
-
Added inivisiblity support for menu bars
-
Table.Update supports setting alternating row color and row_colors (list of rows and the color to set)
-
Set window.TimeoutKey to TIMEOUT_KEY initially
-
Window - check for types for title (should be string) and layout (should be list) and warns user if not correct
-
Window - renamed some methods by adding _ in front (like Show) as they are NOT user callable
-
Another shortcut! Elem = Element = FindElement
-
SaveToDisk - will not write buttons to file. Fixed problems due to buttons having keys
-
Remapped Windowl.CloseNonBlockingForm, Window.CloseNonBlocking to be Window.CloseNonBlocking
-
Fix for returning values from a combo list. Wasn't handling current value not in list of provided values
-
Spin - Returns an actual value from list provided when Spin was created or updated
-
Chaneged FillFormWithValues to use the new internal AllKeysDict dictionary
-
Added try when creating combo. Problem happens when window is created twice. Prior window had already created the style
-
Added list of table (tree) ids to the Table element
-
Enabled autoclose to use fractions of a second
-
Added a try around one of the destroys because it could fail if user aborted
-
Popup - Icon is no longer set to default by default
-
Fix for debugger trying to execute a REPL comand. The exec is only avilable in Python 3
-
main() will display the version number in big letters when program is running
MikeTheWatchGuy 2019-08-08T01:09:14Z
It's been a minute
The documentation beat goes on. It's what most all of the time is spent on, in addition to support.
There are features and fixes going into all ports. Today I think all ports except Wx got some code change to them.
There has been so much going on and yet so little at the same time. I think spreading outward in all directions is about the best way to describe it.
Column sizes work now in PySimpleGUI (on GitHub)
This was a troubling problem that I finally managed to get my arms around. Setting a specific size now works for BOTH scrollable and non-scrollable columns. I predict this will have a very positive impact to layouts.
New documentation sections OTW include:
-
Layout control (moving elements around)
-
Generating versus declaring layouts (writing 3 or 4 lines of code that produces a window with 30 lines of elements)
-
User Defined Elements
-
User Expansion of PySimpleGUI through direct framework access
-
Patching PySimpleGUI
-
The built-in debugger
-
Doc strings for the other 3 ports
Thanks for all the inspiration folks!
MikeTheWatchGuy 2019-08-12T13:04:29Z
Micro-Demos - Small programs that do something useful and can be pasted
Sorry for a lengthy post, but it does have 4 complete programs and 2 screen shots.
What makes these Micro-Demos fun is that they are short enough to "post" on a forum or GitHub Issue or on Reddit. No link to follow, just a short complete program. No code fragment to integrate either.
There have been a number of awesome features added / completed in PySimpleGUI (the main version). The reason PySimpleGUI tends to be more complete, mature is that it's the flagship of the family of ports. It's the proving ground as well for new SDK changes.
Demo 1A - Viewing a webcam in a GUI window using OpenCV - compacted
Modified existing demo to create a super-simplified, get the point through, demo. It's a whopping 13 lines of code if compacted:
import PySimpleGUI as sg
import cv2
layout = [[sg.Image(filename='', key='image')],]
window = sg.Window('Demo Application - OpenCV Integration', layout, location=(800,400))
cap = cv2.VideoCapture(0)
while True:
event, values = window.Read(timeout=20, timeout_key='timeout')
if event in ('Exit', None):
break
ret, frame = cap.read()
imgbytes=cv2.imencode('.png', frame)[1].tobytes()
window.FindElement('image').Update(data=imgbytes)
window.Close()
Demo 1AA - Ultra Compact
This is just plain showing off. It's 7 lines in total. 8 if you add the CR to my if statement ;-)
import cv2, PySimpleGUI as sg
window = sg.Window('Demo Application - OpenCV Integration', [[sg.Image(filename='', key='image')],], location=(800,400))
cap = cv2.VideoCapture(0)
while True:
event, values = window.Read(timeout=20, timeout_key='timeout')
if event is None: break
window.FindElement('image').Update(data=cv2.imencode('.png', cap.read()[1])[1].tobytes())
But that's not very readable, so let's go back to the original for this one. It's "fancy". It doesn't have a titlebar for example. And, if you uncomment the line for the right click menu, you'll be able to exit the application if you're not running in an IDE.
Demo 1B - Viewing a webcam in a GUI window using OpenCV - commented
import PySimpleGUI as sg
import cv2
def main():
sg.ChangeLookAndFeel('Black')
# define the window layout
layout = [[sg.Image(filename='', key='image')],]
# create the window and show it without the plot
window = sg.Window('Demo Application - OpenCV Integration', layout,
location=(800,400), no_titlebar=True, grab_anywhere=True,)
# right_click_menu=['&Right', ['E&xit']],)
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
cap = cv2.VideoCapture(0)
while True:
event, values = window.Read(timeout=20, timeout_key='timeout')
if event in ('Exit', None):
break
ret, frame = cap.read()
imgbytes=cv2.imencode('.png', frame)[1].tobytes()
window.FindElement('image').Update(data=imgbytes)
window.Close()
main()
What is downright extraordinary is that no special code was put in PySimpleGUI to support OpenCV. This just naturally happens if you write the right code. The code only uses PySimpleGUI and OpenCV.
Finally, it works on PySimpleGUIQt and PySimpleGUIWeb, you guessed it... by changing the import statement. STUNNED is how I feel every time this works. BTW, the Web version flickers and is being worked by the Remi team now.
Here's the window it produces
Demo 2 - Drawing On Top of An OpenCV Stream - Released as Demo_OpenCV_Draw_On_Webcam.py
This was a feature asked about and spurred 2 new Graph
methods - BringFigureToFront
, SendFigureToBack
. The only way to "Draw" on something in PySimpleGUI is to use a Graph
Element. The poster asked about using a mouse to draw.
The Graph
Element mouse Dragging was finally completed this past week. The "Mouse Up" events were missing.
In order to "Draw" on a Graph, you need control of the Z-Order of the figures that are being drawn. In this case, the webcam image needs to be behind whatever is being drawn, thus the 2 new methods.
Without further delay, a webcam stream that you can draw red circles all over while it streams.
import PySimpleGUI as sg
import cv2
def main():
layout = [[sg.Graph((600,450),(0,450), (600,0), key='_GRAPH_', enable_events=True, drag_submits=True)],]
window = sg.Window('Demo Application - OpenCV Integration', layout)
graph_elem = window.Element('_GRAPH_') # type: sg.Graph
id = None
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
cap = cv2.VideoCapture(0)
while True:
event, values = window.Read(timeout=0)
if event in ('Exit', None):
break
ret, frame = cap.read()
imgbytes=cv2.imencode('.png', frame)[1].tobytes()
if id:
graph_elem.DeleteFigure(id) # delete previous image
id = graph_elem.DrawImage(data=imgbytes, location=(0,0)) # draw new image
graph_elem.SendFigureToBack(id)
if event == '_GRAPH_':
graph_elem.DrawCircle(values['_GRAPH_'], 5, fill_color='red', line_color='red')
window.Close()
main()
Demo 3 - "Dragging" a Selection Rectangle
We've all used a paint program where you click, drag your mouse and it creates a rectangle that matches the size specified by releasing the mouse button. Click, hold, drag, release. AS you are dragging, a rectangle is drawn, erased if you move the mouse, then redrawn. The result looks like an animation
Evidently this is called a "Rubber Band Selection Rectangle". I learn something new every day from PySimpleGUI. This code was adapted from some user code. In particular I lifted the rectangle logic. However, the original was using PIL to draw a rectangle on the image itself prior to the image being displayed. While this worked, it consumed a lot of compute power and thus wasn't as responsive as it could be.
The more efficient way to create one of these rectangles is to use the Graph
element's DrawRectangle
method. IT's super fast and will work on other ports of PySimpleGUI once the mouse code is completed in those ports (PySimpleGUIQt comes to mind)
import PySimpleGUI as sg
# image_file = r'C:\Python\PycharmProjects\GooeyGUI\logo_black.png'
image_file = None # image is optional
layout = [ [sg.Graph(canvas_size=(400, 400), graph_bottom_left=(0, 400), graph_top_right=(400, 0), key="graph", change_submits=True, drag_submits=True),],
[sg.Text("", key="info", size=(60, 1))]]
window = sg.Window("Drag a Rectangle", layout).Finalize() # need Finalize due to DrawImage call prior to Read
graph = window.Element("graph") # type: sg.Graph
graph.DrawImage(image_file, location=(0,0)) if image_file else None
dragging = False
start_point = end_point = prior_rect = None
while True:
event, values = window.Read()
if event is None:
break # exit
if event == "graph":
graph.DeleteFigure(prior_rect) # don't worry, PSG won't complain if bad ID
if not dragging:
start_point = values["graph"]
dragging = True
else:
end_point = values["graph"]
prior_rect = graph.DrawRectangle(start_point, end_point, line_color='red')
elif event.endswith('+UP'):
window.Element("info").Update(value=f"grabbed rectangle from {start_point} to {end_point}")
# enable grabbing a new rect
start_point = end_point = None
dragging = False
else:
print("unhandled event", event, values)
MikeTheWatchGuy 2019-08-12T13:25:36Z
'Combo', 'Tab', 'TabGroup' Changes - Import API calls deprecated
I'm really sorry if you implemented code using some recently released API changes.
It's rare to flat out break the PySimpleGUI API, but this is a "band-aid" moment. The changes were recent, the number of users that likely used the deleted methods are few. So, rather than slowly remove them over time, they just disappeared and were replaced by others that will give you the data you need.
Rules are meant to be broken, but not architectures. In this case, the "don't break the install base's code" rule is broken, but as explained, the size of the impact is relatively small, but I DO feel the pain of those that are impacted. I'm really sorry about this.
The problem was that I hastily made some changes to the code that don't fit the big-picture architecture of PySimpleGUI. Without boring you too much - basically I added some stuff that uses "indexes" and I named some methods in inconsistent ways or I didn't implement the right method.
ComboBox and TabGroup changes
There was a recent addition that returned the "Currently selected item" in terms of "index". This isn't how it's been done across all the ports for the other elements. The remedy is to supply methods that fit the architecture.
Combo.Get()
& TabGroup.Get()
Some elements provide a Get
method. This returns the "Current" (as in right now) value for an element. It's identical in value to what would have been returned from a call to "window.Read()`. A number of elements have this.
This method does sometimes confuse people. Newcomers, when seeing this method, sometimes think it has to be called in order to get the element's value. They don't realize that ALL element values are returned in the values
portion of the window.Read
call.
This Get
method was added to the TabGroup
Element so that the currently active tab is obtained. It was added to the ComboBox so that the current item can be read. Again, these are identical to what you will see in your call to window.Read
so use that data if you can instead of calling Get
.
Tab.Select()
A requested feature recently was the ability to make a particular tab the "active" or "selected" tab in its group. This is similar to the recently added Button.Click
. In the last release, it was implemented as a call to the TabGroup where an index was passed to the group to select a tab. This didn't follow the norm of acting directly on an element that you want to take the action. In this case, it's the tab itself that's taking an action. You could say that it's the TabGroup. From an Object kind of look, operating on the Tab made more sense.
Again, I'm sorry about this change. I have been too buried in the documentation overhaul, cookbook and demo programs. It's been a while since this kind of new capability was added and I simply didn't take the time to look at the PySimpleGUI APIs as a whole prior to implementing.
MikeTheWatchGuy 2019-08-15T13:27:06Z
Another dumb but fun demo - realtime ASCII movie from your webcam
from PIL import Image
import numpy as np
import PySimpleGUI as sg; font_size=6
# import PySimpleGUIQt as sg; font_size=8 # if using, be sure and use the second layout that is commented out
# import PySimpleGUIWeb as sg; font_size=12 # yes, it runs in a webpage too!
import cv2
"""
Interesting program that shows your webcam's image as ASCII text. Runs in realtime, producing a stream of
images so that it is actually animated ASCII text. Wild stuff that came about from a post on Reddit of all
places. The software bits that turn the image into ASCII text were shamelessly taken from this gist:
https://gist.github.com/cdiener/10491632
Brilliant work to have pulled off so much with so little Numpy
What's remarkable about this program is that the animation is created by updating individual Text Elements going
down the window, one line at a time, every time through the loop. That's 48 lines of text every time. Rough
timing shows an animation of more than 10 fps when running any of the PySimpleGUI ports.
"""
# The magic bits that make the ASCII stuff work shamelessly taken from https://gist.github.com/cdiener/10491632
chars = np.asarray(list(' .,:;irsXA253hMHGS#9B&@'))
SC, GCF, WCF = .1, 1, 7/4
sg.ChangeLookAndFeel('Black') # make it look cool
# define the window layout
NUM_LINES = 48 # number of lines of text elements. Depends on cameras image size and the variable SC (scaller)
layout = [*[[sg.T(i,size=(120,1), font=('Courier', font_size), key='_OUT_'+str(i))] for i in range(NUM_LINES)],
[ sg.Button('Exit')]]
# if using PySimpleGUIQt, use this layout instead. The text rows are too far apart otherwise.
# layout = [*[[sg.T(i, size_px=(800,12), font=('Courier', font_size), key='_OUT_'+str(i))] for i in range(NUM_LINES)],
# [ sg.Button('Exit')]]
# create the window and show it without the plot
window = sg.Window('Demo Application - OpenCV Integration', layout, location=(800,400),
no_titlebar=True, grab_anywhere=True, element_padding=(0,0))
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
cap = cv2.VideoCapture(0) # Setup the OpenCV capture device (webcam)
while True:
event, values = window.Read(timeout=0)
if event in ('Exit', None):
break
ret, frame = cap.read() # Read image from capture device (camera)
img = Image.fromarray(frame) # create PIL image from frame
# More magic that coverts the image to ascii
S = (round(img.size[0] * SC * WCF), round(img.size[1] * SC))
img = np.sum(np.asarray(img.resize(S)), axis=2)
img -= img.min()
img = (1.0 - img / img.max()) ** GCF * (chars.size - 1)
# "Draw" the image in the window, one line of text at a time!
for i, r in enumerate(chars[img.astype(int)]):
window.Element('_OUT_'+str(i)).Update("".join(r))
window.Close()
It's posted in the demo section as Demo_OpenCV_Webcam_ASCII.py
, but am posting here for easy copy and paste.
MikeTheWatchGuy 2019-08-15T13:33:09Z
THANK YOU FOR FILLING OUT THE ISSUE FORMS
Damn, we've got the best users ever here!
It's a pain in the ass to fill out an Issue form, answer the billion questions including perhaps an uncomfortable experience level one.
The experience level really helps make sure stuff is explained at a level you're likely able to easily digest. You've not going to be satisfied if a response goes way over your head and you'll be even more unsatisfied if the responses are well under your years of experience.
The experience question is not meant to embarrass or demean or any other nefarious purpose. It's an honest attempt to provide better support. Besides, you have nothing to be embarrassed about!! None of us was born with programming skills. It's a 100% learned skill and every person here had a very first day of using Python.
MikeTheWatchGuy 2019-08-16T16:59:16Z
More ASCII movies
Did one more pass at this thing. Comments removed to save space.
Controls were added to the bottom. The latest GitHub made them larger for easier use, but's not shown in the movie.
Here's a movie showing what it's like to mess around with controls:
https://youtu.be/rzvJuz5bHTg
The ability to modify one or many parameters and see the result, in realtime, is where PySimpleGUI excels greatly over a command line only option. Just by clicking a spinbox or sliding a slider I can instantly see the effect it has.
Anywhere that "Tuning" is part of the process, a GUI can potentially greatly help. The model - [Running code, stopping, changing variable in code, running code again] cannot compete with click a button and instantly see the change. CLI vs GUI people, continue to debate this as long as you want.
This same kind of "parameter modification" was used in the YOLO demo. You can easily see how changing the "Threshold" has an impact on the classifier.
So, if you want to interact more with your program directly, consider exposing the knobs to turn in a GUI. With PySimpleGUIQt you could literally make them knobs 😏
Here's the modified program that also removes the need to modify anything except the 3 lines at the top in order to move from one platform to another.
Finally, notice this program "Generates the Layout". This topic is being added to the docs.... how to "Build" a GUI layout using Python code. In this case, 48 lines of Text Elements were created in a single statement.
from PIL import Image
import numpy as np
import PySimpleGUI as sg; font_size=6; USING_QT=False
# import PySimpleGUIQt as sg; font_size=8; USING_QT=True # if using, be sure and use the second layout that is commented out
# import PySimpleGUIWeb as sg; font_size=12; USING_QT=False # yes, it runs in a webpage too! Not as good as tkinter but works
import cv2
# The magic bits that make the ASCII stuff work shamelessly taken from https://gist.github.com/cdiener/10491632
chars = np.asarray(list(' .,:;irsXA253hMHGS#9B&@'))
SC, GCF, WCF = .1, 1, 7/4
sg.ChangeLookAndFeel('Black') # make it look cool
# define the window layout
NUM_LINES = 48 # number of lines of text elements. Depends on cameras image size and the variable SC (scaller)
if USING_QT:
layout = [[sg.T(i, size_px=(800, 12), font=('Courier', font_size), key='_OUT_' + str(i))] for i in range(NUM_LINES)]
else:
layout = [[sg.T(i,size=(120,1), font=('Courier', font_size), pad=(0,0), key='_OUT_'+str(i))] for i in range(NUM_LINES)]
layout += [[ sg.Button('Exit', size=(5,1)),
sg.T('GCF', size=(4,1)), sg.Spin([round(i,2) for i in np.arange(0.1,20.0,0.1)], initial_value=1, key='_SPIN_GCF_', size=(5,1)),
sg.T('WCF', size=(4,1)), sg.Slider((1,4), resolution=.05, default_value=1.75, orientation='h', key='_SLIDER_WCF_', size=(15,15))]]
# create the window and show it without the plot
window = sg.Window('Demo Application - OpenCV Integration', layout, location=(800,400), font='Any 18')
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
cap = cv2.VideoCapture(0) # Setup the OpenCV capture device (webcam)
while True:
event, values = window.Read(timeout=0)
if event in ('Exit', None):
break
ret, frame = cap.read() # Read image from capture device (camera)
img = Image.fromarray(frame) # create PIL image from frame
GCF = float(values['_SPIN_GCF_'])
WCF = values['_SLIDER_WCF_']
# More magic that coverts the image to ascii
S = (round(img.size[0] * SC * WCF), round(img.size[1] * SC))
img = np.sum(np.asarray(img.resize(S)), axis=2)
img -= img.min()
img = (1.0 - img / img.max()) ** GCF * (chars.size - 1)
# "Draw" the image in the window, one line of text at a time!
for i, r in enumerate(chars[img.astype(int)]):
window.Element('_OUT_'+str(i)).Update("".join(r))
window.Close()
MikeTheWatchGuy 2019-08-17T20:19:19Z
window['key']
can replace window.FindElement('key')
In case you missed the excited announcement today of this new capability, be sure and check it out:
https://github.com/PySimpleGUI/PySimpleGUI/issues/1827
Briefly..... you can completely remove your calls to window.Element
or window.FindElement
and replace them with calls to:
window['key']
The code continues to compact!! This one in particular has been bugging me for a long time. I don't like "chaining" for new comers sake. And especially would like to make changing an element's settings and values easier.
Now the line of code to change an element allows your eyes to focus on the SINGLE call presented in the line of code, the call to Update
THE OLD WAY of updating an element:
window.FindElement(key).Update(value)
THE NEW WAY of updating an element:
window[key].Update(value)
This has been one of the most exciting changes since making return values a dictionary.
MikeTheWatchGuy 2019-08-17T21:29:47Z
Layout Generation
There are 3 ways I "grow" PySimpleGUI and my own knowledge.
-
Read other people's PySimpleGUI code. The author can have known Python for 2 weeks and still will be able to teach me something. Even simply layout can have some touch to them that I've not thought of. I like to see them ALL!! So please don't be shy.
-
The Reddit Challenges - There is no official contest or code challenge other than people describing their problem and then ask for a GUI recommendation. I bunch of stuff have come out of these. Most recently was an idea of showing your webcam's video stream as an ASCII image movie, a video of you through your webcam and show it in realtime in a window. So I wrote this program.
What is downright AMAZING about this program is that the way it is being shown to you is that each Text Element is Updated every time I read a webcam image and want to show it as ASCII. 48 Text Elements
. I was SURE all the ports would fail, but they all worked GREAT.
If you missed the movie, here it is https://youtu.be/rzvJuz5bHTg
The screen capture didn't do it justice as it's quite smooth (runs in Remi BTW too)
- I want a tool or something else to make my life even lazier / efficient
(4) I cheat and have some brilliant friends that help me out, or give me solutions. They deserve just as much credit as anything else listed here.
Generating Layouts
Believe it or not all that leads up to the topic of "Generating Layouts" which means Python code that creates a layout rather than it being created only by hand.
In the process of solving the problems above, especially the Reddit ones, I write more layouts, and have more opportunities to ponder more compact or more "Pythonic" (not found of tossing that word around) ways of doing things.
How to generate or create layouts differently than the brute force ways but rather by machine and by hand have not yet been added to the documentation. It's the hot topic for me today to finish.
Generating Layouts Demo ([Demo_Layout_Generation.py]
(https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Layout_Generation.py))
There are 8 different Design Patterns presented, although it'll be difficult for you to just copy and use them other than to study. Still, it's nice to have when you need to create a sh*t-load of buttons or input fields.
While used and not at all pointed out, I'll stress it in the docs, but keys can be ANYTHING. They're not limited to strings. This means they can hold something like (x,y) data. Each element in a matrix can have a key that is (row, col). The Questionnaire examples illustrate exactly what I'm talking about.
More Python Stuff, More Simple Coming....
Hoping to finish (miracles do happen) the readme and push out release(s) by the end of tomorrow.
There's a concept called "User Elements" that I don't see many people using that will be part of the docs too.
Plus even more Python stuff being looked at now. It's amazing what this language can do for this problem.
MikeTheWatchGuy 2019-08-17T21:54:45Z
Generating Layouts Code
What the heck, the code for all these layouts isn't very large, so here it is. No download needed. Maybe it'll spark an idea in your head that I can take too.
import PySimpleGUI as sg
"""
Construct #0 - List comprehension to generate a row of Buttons
Comprehensions are super-powers of Python. In this example we're using a comprehension to create 4 buttons that
are all on the same row.
"""
def layout0():
layout = [[sg.Button(i) for i in range(4)]] # A list of buttons is created
window = sg.Window('Generated Layouts', layout)
event, values = window.Read()
print(event, values)
window.Close()
"""
Construct #1 - List comprehension to generate rows of Buttons
More list super-power, this time used to build a series of buttons doing DOWN the window instead of across
"""
def layout1():
layout = [[sg.Button(i)] for i in range(4)] # a List of lists of buttons. Notice the ] after Button
window = sg.Window('Generated Layouts', layout)
event, values = window.Read()
print(event, values)
window.Close()
"""
Construct #2 - List comprehension to generate a row of Buttons and concatenation of more lines of elements
Comprehensions are super-powers of Python. In this example we're using a comprehension to create 4 buttons that
are all on the same row, just like the previous example.
However, here, we want to not just have a row of buttons, we want have an OK button at the bottom.
To do this, you "add" the rest of the GUI layout onto the end of the generated part.
Note - you can't end the layout line after the +. If you wanted to put the OK button on the next line, you need
to add a \ at the end of the first line.
See next Construct on how to not use a \ that also results in a VISUALLY similar to a norma layout
"""
def layout2():
layout = [[sg.Button(i) for i in range(4)]] + [[sg.OK()]] # if want to split, can't add newline after + to do it
window = sg.Window('Generated Layouts', layout)
event, values = window.Read()
print(event, values)
window.Close()
"""
Construct # 3 - Adding together what appears to be 2 layouts
Same as layout2, except that the OK button is put on another line without using a \ so that the layout appears to
look like a normal, multiline layout without a \ at the end
Also shown is the OLD tried and true way, using layout.append. You will see the append technique in many of the
Demo programs and probably elsewhere. Hoping to remove these and instead use this more explicit method of +=.
Using the + operator, as you've already seen, can be used in the middle of the layout. A call to append you cannot
use this way because it modifies the layout list directly.
"""
def layout3():
# in terms of formatting, the layout to the RIGHT of the = sign looks like a 2-line GUI (ignore the layout +=
layout = [[sg.Button(i) for i in range(4)]]
layout += [[sg.OK()]] # this row is better than, but is the same as
layout.append([sg.Cancel()]) # .. this row in that they both add a new ROW with a button on it
window = sg.Window('Generated Layouts', layout)
event, values = window.Read()
print(event, values)
window.Close()
"""
Construct 4 - Using + to place Elements on the same row
If you want to put elements on the same row, you can simply add them together. All that is happening is that the
items in one list are added to the items in another. That's true for all these contructs using +
"""
def layout4():
layout = [[sg.Text('Enter some info')] + [sg.Input()] + [sg.Exit()]]
window = sg.Window('Generated Layouts', layout)
event, values = window.Read()
print(event, values)
window.Close()
"""
Construct #5 - Simple "concatenation" of layouts
Layouts are lists of lists. Some of the examples and demo programs use a .append method to add rows to layouts.
These will soono be replaced with this new technique. It's so simple that I don't know why it took so long to
find it.
This layout uses list comprehensions heavily, and even uses 2 of them. So, if you find them confusing, skip down
to the next Construct and you'll see the same layout built except for loops are used rather than comprehensions
The next 3 examples all use this same window that is layed out like this:
Each row is:
Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
...
It shows, in particular, this handy bit of layout building, a += to add on additional rows.
layout = [[stuff on row 1], [stuff on row 2]]
layout += [[stuff on row 3]]
Works as long as the things you are adding together look like this [[ ]] (the famous double bracket layouts of PSG)
"""
def layout5():
questions = ('Managing your day-to-day life', 'Coping with problems in your life?', 'Concentrating?',
'Get along with people in your family?', 'Get along with people outside your family?',
'Get along well in social situations?', 'Feel close to another person',
'Feel like you had someone to turn to if you needed help?', 'Felt confident in yourself?')
layout = [[sg.T(qnum + 1, size=(2, 2)), sg.T(q, size=(30, 2))] + [sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, col)) for col in range(5)] for qnum, q in enumerate(questions)]
layout += [[sg.OK()]]
window = sg.Window('Computed Layout Questionnaire', layout)
event, values = window.Read()
print(event, values)
window.Close()
"""
Construct #6 - Computed layout without using list comprehensions
This layout is identical to Contruct #5. The difference is that rather than use list comprehensions, this code
uses for loops. Perhaps if you're a beginner this version makes more sense?
In this example we start with a "blank layout" [[ ]] and add onto it.
Works as long as the things you are adding together look like this [[ ]] (the famous double bracket layouts of PSG)
"""
def layout6():
questions = ('Managing your day-to-day life', 'Coping with problems in your life?', 'Concentrating?',
'Get along with people in your family?', 'Get along with people outside your family?',
'Get along well in social situations?', 'Feel close to another person',
'Feel like you had someone to turn to if you needed help?', 'Felt confident in yourself?')
layout = [[]]
for qnum, question in enumerate(questions): # loop through questions
row_layout = [sg.T(qnum + 1, size=(2, 2)), sg.T(question, size=(30, 2))] # rows start with # and question
for radio_num in range(5): # loop through 5 radio buttons and add to row
row_layout += [sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, radio_num))]
layout += [row_layout] # after row is completed layout, tack it onto the end of final layout
layout += [[sg.OK()]] # and finally, add a row to the bottom that has an OK button
window = sg.Window('Computed Layout Questionnaire', layout)
event, values = window.Read()
print(event, values)
window.Close()
"""
Construct #7 - * operator and list comprehensions
Using the * operator from inside the layout
List comprehension inside the layout
Addition of rows to layouts
All in a single variable assignment
NOTE - this particular code, using the * operator, will not work on Python 2 and think it was added in Python 3.5
This code shows a bunch of questions with Radio Button choices
There is a double-loop comprehension used. One that loops through the questions (rows) and the other loops through
the Radio Button choices.
Thus each row is:
Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
Text1, Text2, Radio1, Radio2, Radio3, Radio4, Radio5
What the * operator is doing in these cases is expanding the list they are in front of into a SERIES of items
from the list... one after another, as if they are separated with comma. It's a way of "unpacking" from within
a statement.
The result is a beautifully compact way to make a layout, still using a layout variable, that consists of a
variable number of rows and a variable number of columns in each row.
"""
def layout7():
questions = ('Managing your day-to-day life', 'Coping with problems in your life?', 'Concentrating?',
'Get along with people in your family?', 'Get along with people outside your family?',
'Get along well in social situations?', 'Feel close to another person',
'Feel like you had someone to turn to if you needed help?', 'Felt confident in yourself?')
layout = [[*[sg.T(qnum + 1, size=(2, 2)), sg.T(q, size=(30, 2))], # These are the question # and the question text
*[sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, col)) for col in range(5)]] for qnum, q in enumerate(questions)] + [[sg.OK()]] # finally add an OK button at the very bottom by using the '+' operator
window = sg.Window('Questionnaire', layout)
event, values = window.Read()
print(event, values)
window.Close()
# ------------------------- Call each of the Constructs -------------------------
layout0()
layout1()
layout2()
layout3()
layout4()
layout5()
layout6()
layout7()
MikeTheWatchGuy 2019-08-18T20:46:24Z
More Fun Collapsing Code - Replacing Update
call with.... nothing?
An bit of alien syntax has been added to PySimpleGUI. By no means do you have to use it, but you should understand that it exists and that you may run across it. The problem is that beginners won't understand it..... and I'm sure to use it a fair amount because it removes TWO function names from a statement.
Recall that window.FindElement(key)
was replaced by window[key]
Typically the reason you're finding the element is that you want to call the element's Update
method. When examined to see if it can be collapsed / simplified a rather strange and wonderful design pattern emerged.
Here's a little demo that will replace the text on the first line with whatever you type into the input box.
import PySimpleGUI as sg
layout = [[sg.Text('My layout', key='T')],
[sg.In(key='I')],
[sg.Button('Go')]]
window = sg.Window('My new window', layout)
while True: # Event Loop
event, values = window.Read()
print(event, values)
if event is None: break
window.FindElement('T').Update(values['I'])
window.Close()
The statement to focus on is this one:
window.FindElement('T').Update(values['I'])
You already know the FindElement trick, now it's time for the Update
trick. This is so alien..... Here goes...
Instead of getting the element and then calling Update, you "call the element". Yea, sounds weird.
Replace this line
window.FindElement('T').Update(values['I'])
with this one
window['T'](values['I'])
You are deleting .Update
from your statement. What's left is just the (parms)
portion. It looks foreign to me, but I can sure get used to it!
Of course, if you a variable that contains an element, you can "call" that variable.
MMMmmmm mmmmm that's some mighty tasty Python there!
I'm stunned daily at what this language can do and what ideas users have.
So if you see this kind of thing, you'll know what it is. I'll be sure and comment them anyway.
This change is already on GitHub and will be release to PyPI tonight
MikeTheWatchGuy 2019-08-19T14:37:23Z
YouTube Tutorial That Includes PySimpleGUI GUI
I spotted a new video on YouTube that uses PySimpleGUI.
https://www.youtube.com/watch?v=IWDC9vcBIFQ
He did a nice thing by adding an index in the description to the location it can be found in the video. He's using it in an OO design, so it was really interesting to see how he split things up.
I learn something every time I see someone else's code.
It was nice to hear some kind words about PySimpleGUI. No complaints at all. Just reinforcement that it's simple.
MikeTheWatchGuy 2019-08-19T22:04:32Z
Release PySimpleGUI 4.2 and PySimpleGUI27 2.2
The cool lookup release! No more need for FindElement. You can continue to use FindElement.
However, your code will look weird and ancient. ;-) (i.e. readable)
MORE Docstring and main doc updates!
-
New window[key] == window.FindElement(key)
-
New Update calling method. Can directly call an Element and it will call its Update method
- windowkey == window.FindElement(key).Update(value=new_value)
-
Made Tearoff part of element so anything can be a menu in theory
-
Removed a bunch of del calls. Hoping it doesn't bite me in memory leaks
-
Combo.Get method added
-
Combo.GetSelectedItemsIndexes removed
-
New Graph methods SendFigureToBack, BringFigureToFront
-
Butten release changed for better Graph Dragging
-
Now returns key+"Up" for the event
-
Also returns the x,y coords in the values
-
-
Tab.Select method added
-
TabGroup.Get method added - returns key of currently selected Tab
-
Window finalize parameter added - Will call finalize if a layout is also included. No more need for Finalize!!
-
Quiet, steady change to PEP8 user interface started
-
Now available are Window methods - read, layout, finalize, find_element, element, close
-
Should provide 100% PEP with these alone for most PySimpleGUI programs
-
-
Added finding focus across ALL elements by using the .Widget member variable
-
Fixed sizing Columns! NOW they will finally be the size specified
-
Fixed not using the initialdir paramter in PopupGetFile if the no_window option is set
MikeTheWatchGuy 2019-08-19T23:23:03Z
Coming soon.... PEP8 compliant interfaces
The latest 4.2 release has with it these new Window
methods:
read = Read
layout = Layout
finalize = Finalize
find_element = FindElement
element =FindElement
close = Close
Starting with Windows as these methods are what tend to be called the most. The Update methods for the elements are the 2nd most called and they can be dropped completely now by directly calling the element. I'll still add all the update
methods, don't worry.
I hope to have a bunch more done this week. So, if TheCamelCaseMethod and CamelCaseFuncton names are driving you crazy, then don't worry, a fix is otw.
You can call:
window.read()
in this latest 4.2 release as well as
window.close()
That should take care of 70% of the PySimpleGUI programs out there.
MikeTheWatchGuy 2019-08-21T03:11:25Z
PEP8 Compliant Interfaces for PySimpleGUI is Done!
The tkinter port of PySimpleGUI now has PEP8 named method and function names. All of the user accessable methods and functions have a new PEP8 compliant name in addition to the original names.
In other words, all of your old code continues to operate as it did before. You could even mix them if you wanted. Maybe you like the way Popup
looks instead of popup
. Take your pick.
Assuming all goes well, you can expect this to be cross-ported quickly and released to PyPI.
MikeTheWatchGuy 2019-08-21T04:52:42Z
Nice Tweet....
I go surfing for comments from time to time, just to see how the world is liking or hating PySimpleGUI. Thankfully, 99% of the comments I see posted are positive. Only recently have I taken a moment to notice that this is happening on a daily basis more and more.
Twitter I don't check as often as StackOverflow for example, but I do check it on occassion. Tonight I was treated to this surprising tweet:
And, no, I didn't pay him to say "after reading the docs", but I did thank him of course.
You guys/gals are the best user community on GitHub!
MikeTheWatchGuy 2019-08-21T22:23:07Z
Window
gets finalize
parameter
The layout
for a window used to require a chained call or a plain call to Window.Layout
. A few weeks ago, the layout became a parameter to the Window
initialization, thus removing the need to call Layout
directly.
The next on the hit-list to remove is the Finalize
call.
It took now have a parameter finalize
that you can set to True if you want the window to be finalized when it's created.
The old way:
The new way:
It will do the same thing without the chaining, which is really foreign to beginners.
Like all changes to the SDK, the old interfaces will remain for quite a while, but may eventually be phased out after all documentation and demo programs have been modified to remove those calls.
MikeTheWatchGuy 2019-08-22T01:48:35Z
Legacy Python (2.7) Users Need to Begin Planning
As is discussed in the documentation, the Python 2.7 version of PySimpleGUI will cease to exist on Jan 1 2020. There will be no copes on this GitHub. The final 2.7 release will be left up on PyPI, but no new additions nor patches will be made.
"Cease to exist" = rm PySimpleGUI27*
In the coming weeks the final PySimpleGUI27.py file will be frozen, hopefully at a nice place in terms of the features you want.After the freeze, there will be no updates passed over from the PySimpleGUI.py work.
PySimpleGUI 2019-08-22T17:14:41Z
New element_justification
parameter for Window and Container Elements
You'll find the latest (on GitHub) PySimpleGUI.py file has the ability to do 2 new things.
Sizer
Element
Add this element to a container and it will pad the container out to the specified size. It can be in 1 direction as well (i.e. only pad horizontally)
element_justification
Parameter added to Window, Column, Tab and Frame
Valid values are 'left', 'right', 'center'
You only need to specify the first letter
element_justification = 'c'
The default, of course, is left justification.
PySimpleGUI 2019-08-22T21:52:34Z
4.3 PySimpleGUI Release 22-Aug-2019
PEP8 PEP8 PEP8
Layout controls! Can finally center stuff
Some rather impactful changes this time
Let's hope it doesn't all blow up in our faces!
-
PEP8 interfaces added for Class methods & functions
-
Finally a PEP8 compliant interface for PySimpleGUI!!
-
The "old CamelCase" are still in place and will be for quite some time
-
Can mix and match at will if you want, but suggest picking one and sticking with it
-
All docs and demo programs will need to be changed
-
-
Internally saving parent row frame for layout checks
-
Warnings on all Update calls - checks if Window.Read or Window.Finalize has been called
-
Warning if a layout is attempted to be used twice
- Shows an "Error Popup" to get the user's attention for sure
-
Removed all element-specific SetFocus methods and made it available to ALL elements
-
Listbox - no_scrollbar parameter added. If True then no scrollbar will be shown
-
NEW finalize bool parameter added to Window. Removes need to "chain" .Finalize() call.
-
NEW element_justification parameter for Column, Frame, Tab Elements and Window
-
Valid values are 'left', 'right', 'center'. Only first letter checked so can use 'l', 'c','r'
-
Default = 'left'
-
Result is that all Elements INSIDE of this container will be justified as specified
-
Works well with new Sizer Elements
-
-
NEW justification parameter for Column elements.
-
Justifies Column AND the row it's on to this setting (left, right, center)
-
Enables individual rows to be justified in addition to the entire window
-
-
NEW Sizer Element
-
Has width and height parameters. Can set one or both
-
Causes the element it is contained within to expand according to width and height of Sizer Element
-
Helps greatly with centering. Frames will shrink to fit the contents for example. Use Sizer to pad out to right size
-
-
Added Window.visibility_changed to match the PySimpleGUIQt call
-
Fixed Debugger so that popout window shows any newly added locals
PySimpleGUI 2019-08-22T22:21:50Z
More Twitter?
Never thought about Twitter being a place where PySimpleGUI would be discussed.
But more and more posts are showing up. Here's a nice one from today:
#PySimpleGUI is something positive it would appear. What a contrast from other sites.
PySimpleGUI 2019-08-24T00:14:28Z
New Layouts Section in Readme / Docs
https://pysimplegui.readthedocs.io/en/latest/#layouts
Finally was able to write the section on Layouts that I've been wanting to write for some time. I highly recommend reading through it by everyone, newcomer and veteran. It could save you a LOT of time and typing.
In it 5 different ways that layouts can be manipulated are discussed. I found organizing the information to be extremely valuable. I learned a lot about howto manipulate these layout lists and to generate them as well.
Don't Copy and Paste Layout Rows, Generate Instead!
One reason for writing it was to help the folks out that are creating layouts that are pages of code long. I get why there are so many elements, it's the brute force nature of the layouts that I'm seeing "in the wild" that had me concerned.
I don't blame the less experienced programmers for being inefficient and copying code... it's what junior programmers or newcomers to Python do.
Part of the block copied layouts is the fault of the documentation lacking in this area. There have not been examples of the "right" ways to go about making efficient layouts . But, now there is!
So, please read through the "Layouts" section. Feedback is always welcomed!
PySimpleGUI 2019-08-26T23:15:07Z
PEP8-ified PySimpleGUIQt.... 2 down 2 to go!
One step closer to going PEP8 across the board!
PySimpleGUIWx and PySimpleGUIWeb are left. Web is next.
This is getting exciting! Soon we'll all be writing better looking PySimpleGUI code.
PySimpleGUI 2019-08-31T03:25:02Z
Lots of Doc Updates
Released a new version of the docs. Having been working for some time on these. It's both the readme and the version with table of contents remains http://www.PySimpleGUI.org.
Added several sections including:
Extending PySimpleGUI
Multithreading,
Sshortcut for FindElement & Element.Update,
Column justification,
Sizer Element
PEP8
HorizontalSeparator,
Table.Get for Qt
ChangeLookAndFeel values
PySimpleGUI 2019-09-02T14:50:45Z
Repl.it Voting Help Needed!
https://repl.it/bugs/p/python-automatic-package-installs-intermittently-failing
Repl.it has a voting system for determining if your bug is going to be looked at.
If you use Repl.it with PySimpleGUI then please vote on fixing this bug:
https://repl.it/bugs/p/python-automatic-package-installs-intermittently-failing
On Repl.it, simply importing a package should be enough to trigger it to pip install it. You shouldn't have to manually install PySimpleGUI or PySimpleGUIWeb. The import should be enough. It should be a copy, paste, click run experience, but not so for some projects.
Thank you and I hope you're enjoying using PySimpleGUI!
PySimpleGUI 2019-09-04T01:45:04Z
PEP8 DONE!! Mass update of all 4 ports
It's [finally] DONE!! All 4 of the ports have PEP8 bindings in the code. It's checked into GitHub but not yet released to PyPI. SOON!! REALLY REALLY SOON! (Tomorrow).
Then begins the mass conversion of the documentation and the demo programs. For many of us, this will be a jarring transition. For newcomers, this will feel quite natural I'm guessing.
This release marks the first and only general GUI package in Python that uses PEP8 methods for all of the classes. Neither Qt nor WxPython have PEP8 names for their class methods. This is because they're conversions from C++. I've never understood why they haven't provided two things:
-
snake_case_bindings for all of their class methods
-
Interfaces that aren't args *kwargs based. It's next to impossible to figure out the parameters to some of these calls without searching through the docs
More Shortcuts for PySimpleGUI-tk
Trying out a number of different shortcuts for Elements. Some of them will likely be removed as they're perhaps a couple too many provided just to see which "feels" the best to write. Examples include LBox
, DD
, R
, Rad
, Status
, Out
, PBar
, Prog
, Col
, ML
, MLine
.
The ones likely to disappear are Out, Prog since you're unlikely to be writing these very often. Their purpose after all is to save space when creating your layouts and if you only have 1 Output
element, then having Out
isn't saving you much and could be confusing.
Callable Windows
Remember the cool trick of "Calling an Element" where doing so actually calls the element's Update
method?
window[key](new_values)
Well, now you can do something similar to Window
objects. If you call a Window
object, you'll be calling that window's Read
method. So, you could write
as
The code was added to all 4 ports, so feel free to give it a try and see what you think. Yea, it's a little bit crazy, but it's a little bit rock and roll too!
Back to the Web soon!
There are a number of fixes that the fine folks at Remi completed for us that really need to get into the code. Hoping to be able to do this pretty soon. It will open up a lot of cool stuff.
Video Playback using VLC Coming!
One user demonstrated that streaming real video, with audio is not just possible with PySimpleGUI, but it's working already in his code. This means OpenCV and "flip book" videos won't be the only mechanism to show video in your PySimpleGUI windows.
Docstrings for the ports soon too
It's important to get the hard work done on DocStrings pushed out to the other 3 ports. At the moment, only the tkinter version is benefiting from this work, but soon the others will too thanks to some tools written to help
Qt Designer
More work has been happening behind the scenes on this project. Hoping to get back to working on this soon-ish.
2019 has been exciting!
2018 was pretty damned exciting, but this year is shaping up to be just as impactful as last year. The new docs look fantastic and having docstrings on everything in the tk port has been FUN to have.
Being able to have a PEP8 compliant interface to the package seemed far away and not achievable anytime soon, but thanks to the Python language, it was possible to do on all 4 ports in a relatively short period of time.
And there's still another 4 months left this year!
PySimpleGUI 2019-09-04T20:41:38Z
Getting Closer to A Final Set of Shortcuts
I took away some of the terrible shortcuts I created yesterday. I figured no one has had time to use them. For example removed OM == OptionMenu and Out==Output because OptionMenu is rarely used already and Output
elements by definition will appear only once in a layout.
I have also been working on a template you can copy that imports the Elements and their shortcuts. This will be a long import statement that you can simply copy and paste into your projects. The result is that you don't have to put sg.
onto the front of every Element in your layouts! I have to say, it feels really nice to write this way. I wish there was a way to say "Import all classes".
NEVER ever type this line of code from PySimpleGUI import *
PLEASE oh please never do that. It's SO tempting I understand, but it must not happen. Instead copy and paste this single line of code:
from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, Check, Button, B, Btn, ButtonMenu,BMenu, Canvas, Column, Col, Combo, DropDown, Drop, DD, Frame, Graph, Image, InputText, Input, In, I, Listbox, LBox, LB, Menu, Multiline, ML, MLine, OptionMenu, Output, Pane, ProgressBar, Prog, PBar, Radio, R, Rad, Sizer, Slider, Spin, StatusBar, Tab, TabGroup, Table, Text, Txt, T, Tree, TreeData, VerticalSeparator, Window, Print
This is for plain PySimpleGUI only right now because I have not yet ported all of the shortcuts to the other ports. SOON for sure!
This import is discussed in a new Demo program:
Demo_Compact_Layouts_Element_Renaming.py
I'm pasting the entire program here so that you get some context and examples of how to use it. The demo points out that you too can create your own shortcuts quite easily.
Note the use of the PEP8 bindings. Get used to them as they're going to be added to all docs and code soon and hopefully quickly.
import PySimpleGUI as sg
# Import the elements individually to save space
from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, Check, Button, B, Btn, ButtonMenu,BMenu, Canvas, Column, Col, Combo, DropDown, Drop, DD, Frame, Graph, Image, InputText, Input, In, I, Listbox, LBox, LB, Menu, Multiline, ML, MLine, OptionMenu, Output, Pane, ProgressBar, Prog, PBar, Radio, R, Rad, Sizer, Slider, Spin, StatusBar, Tab, TabGroup, Table, Text, Txt, T, Tree, TreeData, VerticalSeparator, Window, Print
"""
Demo - Compact Layouts and Element Renaming
Some layouts contain many many elements such that space becomes a premium. For experienced PySimpleGUI
programmers, there is little additional knowledge to be gained by writing
sg.Text('My text')
rather than using one of the shortcuts such as
sg.T('My text')
However, even with shortcut usage, you continue to have the package prefix of
sg.
That's 3 characters per element that are added to your layout!
The very long import statement st the top can be copied into your code to give you the ability to write
T('My text')
If you don't want to use that very-long import or perhaps want to use your own shortcut names, you can easily
create your shortcut by simple assignment:
T = sg.Text
This enables you to use T just as if you imported the Class T from PySimpleGUI. You could develop your own
template that you copy and paste at the top of all of your PySimpleGUI programs. Or perhaps perform an import
of those assignments from a .py file you create.
Note that you may lose docstrings in PyCharm using these shortcuts. You can still see the parameters when pressing
Control+P, but the Control+Q doesn't bring up the full list of parms and their descriptions. Looking for a fix
for this.
PLEASE OH PLEASE OH PLEASE NEVER EVER EVER do this:
from PySimpleGUI import *
There is a bot scanning GitHub for this statement. If found in your code, a squad of assassins will be dispatched
from the PySimpleGUI headquarters and you will be hunted down and forced to change your code.
"""
# A user created shortcut....
# Suppose this user's layout contains many Multiline Elements. It could be advantageous to have a single letter
# shortcut version for Multiline
M = sg.Multiline
# This layout uses the user defined "M" element as well as the PySimpleGUI Button shortcut, B.
layout = [[M(size=(30,3))],
[B('OK')]]
event, values = Window('Shortcuts', layout).read()
sg.popup_scrolled(event, values)
PySimpleGUI 2019-09-06T00:19:26Z
4.4 PySimpleGUI, 2.4 PySimpleGUI27 Release 5-Sep-2019
-
window() - "Calling" your Window object will perform a Read call
-
InputText - move cursor to end following Update
-
Shortcuts - trying to get a manageable and stable set of Normal, Short, Super-short
-
DD - DropDown (Combo)
-
LB, LBox - Listbox
-
R, Rad - Radio
-
ML, MLine - Multiline
-
BMenu - ButtonMenu
-
PBar, Prog - ProgressBar
-
Col - Column
-
-
Listbox - new method GetIndexes returns currently selected items as a list of indexes
-
Output - new method Get returns the contents of the output element
-
Button - For Macs don't don't allow setting button color. Previously only warned
-
ButtonMenu - new Click method will click the button just like a normal Button's Click method
-
Column scrolling finally works correctly with mousewheel. Shift+Mouse Scroll will scroll horizontally
-
Table - Get method is a dummy version a Get because Qt port got a real Get method
-
Table - Will add numerical column headers if Column Headsing is set to None when creating Table Element
-
Table - FIXED the columns crazily resizing themselves bug!!
-
Table - Can resize individual columns now
-
Tree - was not returning Keys but instead the string representation of the key
-
SetIcon will set to default base64 icon if there's an error loading icon
-
Fix for duplicate key error. Was attempting to add a "unique key counter" onto end of keys if duplicate, but needed to turn into string first
-
Columns
-
No longer expand nor fill
-
Sizing works for both scrolled and normal
-
-
Setting focus - fixed bug when have tabs, columns, frames that have elements that can get the focus. Setting focus on top-level window
-
InputText elements will now cause rows to expand due to X direction expansion
-
Frame - Trying to set the size but doesn't seem to be setting it correctly
-
Tabs will now expand & fill now (I hope this is OK!!!)
PySimpleGUI 2019-09-06T15:33:03Z
PySimpleGUI Emergency 4.4.1, 2.4.1 Release
Discovered this morning that the "Resizable Elements" meant to resize when window resizes broke general sizing, so had to scramble and turn it off. Hoping that something didn't break in the scramble to get it out.
PySimpleGUI 2019-09-06T15:34:22Z
0.28.0 PySimpleGUIQt 5-Sep-2019
FINALLY the Qt release went out to PyPI!! It's been a long time. This gets PySimpleGUIQt up to the same PEP8 level as PySimpleGUI. Next up is PySimpleGUIWx, then Web.
It's been a LONG LONG LONG time coming
-
PEP8-ified! All methods and functions have PEP8 equivalents!! It's a BFD
-
Version numbers in the code
-
New key dictionary - Window.AllKeysDict has all of the windows keys in 1 place for FASTER lookups
-
Element.Widget provides access to low level Qt Widget
-
Multiline scaling in addition to single line
-
Raised default pixel cutoff for single line scaling to 15 from 12
-
Pixel conversion done in Elements and passed through to Element class as size_px
-
Renamed lots of private functions and methods to begin with _
-
"Callable" Elements - element(new_value) will cause element.update(new_value) to be called
-
Removed all del except for the Output Element one
-
Button - Click method added. Your program can click a button as if a user did
-
ButtonbMenu - Click mehtod also added like in Button element
-
Graph Element
-
Added DrawRectangle method
-
Added RelocateFigure method
-
Added return of ID to DrawLine, DrawCircle, DrawText
-
Added Erase method to erase entire graph
-
-
Tab - added Select method so can select a Tab as if user clicked it
-
TabGroup - added Get method. Returns key of currently selected Tab, or text of Tab if no key set
-
Table - Get method returns the table - GREAT way to enable users to edit a table and get the results
-
SystemTray - uses default base64 icon if no icon supplied when creating
-
Window - new finalize parameter removes need to add chained call to finalize
-
Window.FindElement - added silent_on_error parameter
-
Window[key] is the same as Window.FindElement(key)
-
Calling a Window object calls Read for that window
-
Fix for filetypes. Bug caused (*) to be added onto filetypes when browsing for files
-
Combo returns exact value that was provided using an index into Values list instead of string from Qt
-
Listbox returns actual supplied items
-
Spinner returns avtual supplied item
-
Tabgroup returns Tab key
-
Finding element with focus now returns element regardless of type (any type of element can be returned)
-
Radio Buttons now return events if enabled
-
Graph element background colors added, uses new style class
-
Table headings supported (where not supported before??)
-
Popups switched to using new layout parm in Window call and uses keys too
PySimpleGUI 2019-09-06T20:48:38Z
Best Users Ever!
If I haven't thanked the entire group of users yet, then "THANK YOU!!"
I hear from you guys more often than I ever thought would happen and it's ALWAYS very welcomed. Some of these days and nights are a little difficult to get through, but that can turn around in an instant to hear from someone that PySimpleGUI has made an impact on their life.
And that's the way many of you have described it.... that [finally] being successful at writing a GUI had an extremely positive effect on you. It's a compliment in the highest of ways as it's what I wanted to achieve. I wanted to bring GUIs to everyone. And, I wanted GUIs to be easy for us all.
The programs everyone is writing, me included, are getting more and more complex and yet the framework's architecture is holding up quite well. I honestly haven't heard anyone say "I can't find any success using PySimpleGUI". Everyone that I can recall has had a positive experience.
I also learn from each and every one of you. Even complete beginners have something to add. Sometimes it's those folks that have the most to add because they're FRESH. They've not yet been "trained" to do things a certain way. Or maybe I see where I could document things better because a similar problem keeps happening.
Just know that messages you send or support you show on Reddit have a really big impact. And I SO very much appreciate it.
PySimpleGUI 2019-09-13T21:45:11Z
Instantly "Compress" Your Code
The "new way" of finding elements will soon be sweeping through all of the docs, cookbook and demo programs. I would love to remove FindElement from everywhere I can.
If you really want to compress, you can also remove the .Update
call that often follows it.
If you're using an editor, you can do this in 2 steps.
First is to find and replace the FindElement
or Element
calls.
Let's say I have this line of code:
What I do is search for:
and replace it with
This will cause syntax errors all over the place, but don't worry, step 2 fixes all that.
The example line now looks like this:
Step 2, if you want the mega-short way, is to replace
with
If you don't want to remove the .Update part, then replace with
The new short line looks like this:
Or if you want the longer version:
To me, the more important thing to lose is the FindElement
call.
If you REALLY want to be brave, you can replace
with
PySimpleGUI 2019-09-16T21:29:12Z
New YouTube Video That Uses PySimpleGUI
This one is the latest: https://www.youtube.com/watch?v=x5LSTDdffFk&feature=youtu.be
It's short at only 6 minutes, but the animations and explanations are thorough and very pleasant to watch. Wow, so nice to see it being taught like this.
The code for it is here: https://github.com/israel-dryer/PyDataMath-II
There are actually 2 videos he's made so far using PySimpleGUI. They are both excellent in my opinion.
This was the first one: https://www.youtube.com/watch?v=IWDC9vcBIFQ
I yet again learn something cool and awesome by reading someone else's PySimpleGUI code. I'm sure many of you recall that I create a function when I have Elements that have a lot of settings that are used over and over.
His approach was entirely different. What he did was he made a dictionary of the repeated parameters and then passed those in.
bw = {'size':(7,2), 'font':('Franklin Gothic Book', 24), 'button_color':("black","#F8F8F8")}
bt = {'size':(7,2), 'font':('Franklin Gothic Book', 24), 'button_color':("black","#F1EABC")}
bo = {'size':(15,2), 'font':('Franklin Gothic Book', 24), 'button_color':("black","#ECA527"), 'focus':True}
Then in his layout:
[sg.Button('7',**bw), sg.Button('8',**bw), sg.Button('9',**bw), sg.Button("*",**bt)],
VERY clever and one that I'll be stealing for sure :-)
PySimpleGUI 2019-09-20T15:58:44Z
Element.set_size
Experiment?
Just added to the tkinter port is the general ability, for all elements (in theory), the ability to "resize".
To set the size for an element, you call that element's set_size
function, just like you would update
or set_focus
.
As mentioned in the Enhancement Issued opened to track the progress, with this call you can set one of the sizes to None so that only 1 is changed. The parameter passed in is a single variable which is a tuple of 2 ints.
Here's a bit of demo code:
import PySimpleGUI as sg
layout = [ [sg.Text('My Window', key='-TEXT-', background_color='lightblue')],
[sg.Input(key='-IN-'), sg.Text('', key='-OUT-')],
[sg.Button('Do Something'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout, resizable=False)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event in (None, 'Exit'):
break
if event == 'Do Something':
window['-TEXT-'].set_size((20,3))
window['-TEXT-'].Update('1\n2\n3')
window['Exit'].set_size((None,2)) # Change only the height... one of the ONLY times None can be used in a size
window.close()
Please comment to the Issue if you end up using it or had problems with it.
2004
Enjoy!
PySimpleGUI 2019-09-20T16:20:33Z
Matplotlib Lives Again! (Ver 3.1.1) - Happy Data Science Day!
We've been help up for a little bit, unable to use 3.1 with PySimpleGUI. I'm happy to be able to announce that Matplotlib version 3.1.x works with PySimpleGUI again! You can safely pip install the newest Matplotlib now and it'll work with PySimpleGUI. If you have older code working with Matplotlib, you'll need to switch to this new method in order to upgrade your code.
While PySimpleGUI integrates with Matplotlib, it's technically not a "feature". It's an "Integration" with demo programs supplied to demonstrate one way to accomplish integration.
BIG thank you goes out to @Em-Bo and @dirck for their help!
All of the Matplotlib demos, save two, have been updated to reflect the changes:
Demo_Matplotlib.py
Demo_Matplotlib_Animated.py
Demo_Matplotlib_Animated_Scatter.py (which animates faster now)
Demo_Matplotlib_Browser.py
Demo_Matplotlib_Browser_Paned.py
Not done are these 2 ping demos:
Demo_Matplotlib_Ping_Graph.py
Demo_Matplotlib_Ping_Graph_Large.py
PySimpleGUI 2019-09-20T17:31:22Z
Ability to get screen size regardless of window present
Previously with PySimpleGUI-tkinter, you could get the screen dimensions after you created you window by calling window.GetScreenDimensions()
, but it only worked if you had a window already opened (thus the little 'w' on window
).
Now you can call the class method Window.get_screen_size()
with a window already opened or not:
This should some in handy for people that are trying to set initial window sizes to match some portion or all of the available screen real estate.
PySimpleGUI 2019-09-21T19:43:44Z
PySimpleGUI Discovers Twitter
It stumbled onto the Twitter folks by accident last year. Tony, a teacher from Australia, was the first I can recall that tweeted something about it.
The PySimpleGUI Twitter id is \@PySimpleGUI
(I just changed the ID)
Had my mind blown yesterday when there was a post of a screenshot of a code editor made with PySimpleGUI that was running a Calculator program that was written in PySimpleGUI.
https://twitter.com/PySimpleGUI/status/1175191301890936832
Can't wait to get my hands on this code... want to run the PySimpleGUI code editor inside of the PySimpleGUI code editor that is running a PySimpleGUI Demo program. It could go as deep as you want I would assume.
Anyway, if you're a Twitter person, please feel free to share your PySimpleGUI stuff. There IS a community there that is enjoying seeing what each other is creating. I'm still new, but it seems like a nicer community than some others.
I am such a newbie at Twitter I didn't know you can change the name. When I tried to sign up with PySimpleGUI, it gave me \@SimplePy. I didn't know I could change it! I could SWEAR I tried in the past.
I don't know what will happen if someone uses the old ID but I'm going to stick with the new
PySimpleGUI 2019-09-25T18:04:08Z
PySimpleGUI Runs on Trinket.io
Happy to announce that another platform is available to run PySimpleGUI online besides repl.it. I did have to get a paid account, but it's cheap.
Here's the demo program for Conway's game of life:
https://trinket.io/library/trinkets/447e96f4d4
Here's a demo of a recent mock-up I did for a Reddit post
https://trinket.io/library/trinkets/3fed5650f4
The downside to trinket.io is that I have to include ALL of the source required for the project, including PySimpleGUI.py.
Still, trinket looks cleaner than repl.it to the user. It's a simple "run" button without a bunch of output scrolling past that makes no sense to most people.
PySimpleGUI 2019-09-30T15:31:21Z
More Trinket.io
I've been really putting some time into the Trinket.io examples as I work on Reddit and other problems. It's difficult to get the entire list of my programs out to you. It seems like the only way is by creating a "Lesson" and adding the programs to that.
https://trinket.io/pysimplegui/courses/demo-programs#/demo-programs
It also now has me thinking that perhaps putting the GitHub demo programs on either Trinket or Repl.it could be a great thing, That's a LOT of porting as there are 180+ programs at the moment.
There is also the problem on trinket that I have to include the entire PySimpleGUI.py file as part of the project. With repl.it PySimpleGUI is automatically loaded via pip so that you get the latest and greatest released version.
So, I'm torn. Trinkit's overall experience and interface feels cleaner and easier for the end user to operate. But it's got this architecture flaw of having to include the PySimpleGUI.py file. This seems fine for the Reddit posts I'm using it for.
PySimpleGUI 2019-10-01T13:25:32Z
0.13.0 1-OCT-2019 PySimpleGUIWx
FINALLY PySimpleGUIWx released to PyPI!
Really sorry about the delay. The release notes among other things slowed me down.
-
Version numbering using sg.version string
-
PEP8 bindings!
-
Improved scaling of character to pixel sizes of elements that are multilined
-
Added Metadata variable to all elements
-
Renamed element callback functions to start with _
-
Removed del methods everywhere except Output Element
-
Can "Call" an element which will call its Update method
-
InputText element - convert default text and password char to string
-
Removed old code such as tkinter's tooltip and drag and drop from Qt
-
Shortcut I for InputText
-
Listbox added size_px parm
-
Changed type checking to use the comment style types
-
Added Element.Widget to all Elements so can access the Wx widgets directly
-
Text Element now defaults to '' so no need to specify anything if a blank Text Element (often used for output)
-
Button text converted to string when creating button
-
New Button shortcuts - B, Btn
-
VerticalSeparator - Newly supported Element
-
HorizontalSeparator - Newly supported Element
-
Slider - added size_px parm
-
Fixed leak caused by System Tray not cleaning up the timer
-
Window - added finalize paramter so can skip using chained .Finalize()
-
Window - AllKeysDict now used like other PySimpleGUI ports. Has all the keys and elements in a window
-
Window.FindElement - added silent_on_error parm like other ports have
-
Window[key] construct added that calls FindElement
-
window() - can "Call" a window you've created. Will call Window.Read()
-
Popup buttons no longer use CloseButtons for normal popups. Calls window.Close manually
-
PopupGetFolder changed to use keys, normal button, new window design patterns
-
PopupGetFile changed to use keys, normal buttons, new window design patterns
-
PopupGetText changed to use keys, normal buttons, new window design patterns
-
Default application (PySimpleGUI.main) now shows the version number like other PySimpleGUI ports
PySimpleGUI 2019-10-03T03:05:43Z
2,200 ⭐ 503,000 Installs
Hit 2 milestones today! (or close to today)
Thankfully stars are not downvotable 🙄
Have also been waiting for a while to hit the 500,000 total installs mark, both seemed to have happened this week or thereabouts.
Here is how each port contributes to the total:
THANK YOU PySimpleGUI users!! You're the BEST GitHub community ever!
PySimpleGUI 2019-10-07T21:54:00Z
The Cleanest PySimpleGUI Code
These examples may very well be some of THE best, cleanest, most modern pieces of PySimpleGUI code I've seen, and I read all the PySimpleGUI code I can. He uses type hints, or some kind of typing as it's beyond me at the moment. I'm still living in 3.5/3.6 world as the Pi is still stuck at 3.5.
Meet Israel Dryer's Notepad code - a less than 100 line PySimpleGUI program that implements a basic text editor with menus and other features you would expect.
It's portable and runs online on Trinket for example.
He also made perhaps THE best PySimpleGUI video, where he teaches you PySimpleGUI along with how to build a calculator based off an actual vintage TI calculator.
He also wrote a CODE EDITOR that also runs on Trinket. This code does some wild stuff with styling the windows, setting "themes". Has excellent menus. His stuff is very "complete" and polished. I'm pretty jealous as he out PySimpleGUI's me, easily.
Israel is one to watch for innovative uses of PySimpleGUI as well as how to utilize the Python language better while writing PySimpleGUI code.
PySimpleGUI 2019-10-16T20:50:44Z
A GitHub Star Graph
I ran into an interesting tool that graphs the number of stars a project has over time.
Here's the graph of PySimpleGUI's GitHub stars over time:
Hmmm..... not very interesting... just a slow gradual growth.
Then I started adding other projects.
It would seem that PySimpleGUI is doing pretty good!
I didn't include Kivy because it has over 10,000 stars across a 10 year span. The graph gets distorted.
PySimpleGUI 2019-10-20T01:05:15Z
Streaming Media Player!
We've got another homerun program from Israel Dryer! This time it's a media player.
This is incredible, truly incredible. Super-easy to understand code. It's at 125 now, but hasn't been "compressed" at all.
With a few minor changes that took maybe 4 minutes, it was up and running on PySimpleGUIQt. Now quite able to get it to run on PySimpleGUIWeb just yet.
I played with an earlier version and made it a borderless window. Really spiffy.
PySimpleGUI 2019-10-24T13:31:14Z
Speed of Fixes, Project expectations
When there is a problem that a user reports, it's a frustrating experience, for everyone, not just the user reporting a problem. If you personally feel like the level of support, the effort to help or the stability of the software is not now or will not be in the future, up to your level of expectations, then please don't use PySimpleGUI. You've got other choices. Go with Qt and a paid license if you need corporate level support as it's simply not possible here.
PySimpleGUI is free software. The time spent creating it was donated, the time spent supporting users is donated, and the money paid to consultants to help from time to time to helps speed things up is donated. It has taken days, nights and weekends to get to this point and continues to take that kind of effort. Quite simply there isn't enough time nor ability to be perfect, to respond in a way that meets everyone's expectations, to run a flaw-free project. Life outside this project is preciously short and has been for almost 2 years.
I understand the form that accompanies Issue submissions can be a pain in the ass. I don't know exactly how long it takes to fill out, but I can't imagine it being an hour or more. There are other open source projects that utilize similar forms, many of which are much more strict in rejecting even partially filled out submissions. Every bug system I've seen and worked with has similar data that is collected with every submission. GitHub's Issue lists are not a bug database so these forms projects use are an attempt to re-create the capabilities of a normal bug tracking system. It's far from perfect.
One problem is that some users have never seen a bug database. Many are not professional software developers. The result could be that some people feel really put-out by the Issue resolution process. It's for efficiency purposes that Issues have these forms. It's an attempt to get you, the user, back up and running ASAP. If there is any doubt there, then again, this may not be the package for you. Damn, that's a terrible thing to say, but it's honest and an attempt to short-cut your frustration. Turning away users goes against everything this software was written for.
This is not a fun announcement to make. It's one of the least fun in fact. If there's a summary here, I would say it's that there are only so many hours available for this project and there are SO many more activities that need doing that those hours provide. Some projects take weeks to reply to an issue and every attempt will be made to ensure this isn't one of them. However, there can't be any promises made on how quickly your problem will be fixed. A fast workaround is often attempted to get you on the road again, but that's not always a possibility.
I ask for your help and understanding when asking for assistance. Your problem is the most important and highest priority thing for you, but if you can step back a little and see there are other people in the same boat and the project also needs to continue to move forward, then maybe it'll help with your frustration at the inability to address problems on your timeline that meet your expectations. Patience is requested and very much appreciated.
I'm really grateful for the support and encouragement users have shown over the past couple of years. It is very appreciated. Thank you for your time, and I'm sorry if any of you have been disappointed.
PySimpleGUI 2019-10-24T16:35:02Z
Mouse Vs Python Article by Mike Driscoll
My all-time favorite Python book author, Mike Driscoll, has written a short article on PySimpleGUI!
http://www.blog.pythonlibrary.org/2019/10/23/a-brief-intro-to-pysimplegui/
It's posted on his "Mouse Vs. Python" blog and being picked up by a number of newsletters. This is super exciting as Mike's helped my Python education along through his books. Python 101 has to be a favorite as I learned a lot of stuff about the standard library I didn't know (for example the daemon setting on Threads).
I think that Mike may write something larger in the future as he's a writer for RealPython. THAT would be something to see!
Here are some of the books Mike's written that you may recognize
-
Python 101 - (eBook or Paperback or read it online)
-
Python 201: Intermediate Python - (eBook or Paperback)
-
wxPython Recipes - (eBook or Paperback)
-
Python Interviews - (eBook or Paperback)
-
ReportLab: PDF Processing with Python - (eBook or Paperback)
-
Jupyter Notebook 101 - (eBook or Paperback)
-
Creating GUI Applications with wxPython - (eBook or Paperback)
His most recent book, very recently published, is the WxPython book, so he's very very up on GUIs.
It's going to be fantastic to hear feedback from Mike! It's a great opportunity that will no doubt help improve the package.
PySimpleGUI 2019-10-29T13:49:08Z
Thank you for following naming / coding conventions!
Lagging behind on updating some of the docs, particularly the cookbook and readme. It's important to keep those up to date with the latest coding conventions (design patterns). They are the vehicle in which names and design patterns are shown, repeatedly, until you're brainwashed into naming your variables the same thing.
I want to applaud the consistency that the community has shown using the package. It's another unexpected outcome. The project has been riddled with these kinds of unexpected results. I read lots of PySimpleGUI code. As much as I can because I learn from it. What I'm seeing is consistency pretty much across the board. It's pretty cool
By consistency and coding conventions I mean the variable names, program structure, etc. 99% of the time I see
and
It may sound like I'm being picky when encouraging people to follow these but it has this huge advantage of any of us being able to pick up another's PySimpleGUI code and read it. It's easy to scan a page of code and find the event loop, where the input value are being used, etc.
The big one I'm trying to get switched over to at the moment is the replacement of FindElement
with [ ]
. But even if that change isn't made by everyone, the FindElement
or find_element
are easy to spot as well.
Seemed like something worthy of thanking the community for doing. It does have a positive impact in the end I think. Other people that are perhaps behind you in their skills have a chance to learn from you, .... take your code. .... and your artwork. 😉
PySimpleGUI 2019-10-30T19:06:52Z
Mini Media Player Anyone?
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Media_Player_VLC_Based.py
It plays back:
-
Files from your hard drive
-
YouTube links
-
DropBox links (set dl=1 in the shared link)
Another winner demo program added courtesy of Israel Dryer. Stole his bare-bones media player that's part of his larger feature rich media player and turned it into a Demo Program. Changes were coding convention stuff, etc, nothing major that's for sure.
It's maybe 55 lines of code? PyCharm says 70, but 15 lines of that are comments. Need to write a little utility to display actual lines of code. It's ridiculously small. And even then, check out how difficult these lines are in the event loop:
if event == 'play':
list_player.play()
if event == 'pause':
list_player.pause()
if event == 'stop':
list_player.stop()
if event == 'next':
list_player.next()
list_player.play()
if event == 'previous':
list_player.previous() # first call causes current video to start over
list_player.previous() # second call moves back 1 video from current
list_player.play()
Could it be done in less code using a dictionary or something, sure, but WHY? It would add significant complexity. It's not worth saving some code if you lose something so beautifully simple as this. The player buttons and how the player reacts is all right there in one place.
Code is present to allow running on Linux but I still need to test.
PySimpleGUI 2019-10-31T02:58:25Z
Notification Window - Fades in and out, click to dismiss
There's a new demo program that I think many of you will find useful and adds a very nice touch to your program.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Notification_Window_Fade_In_Out.py
This code displays a notification "window" that fades in and out and can be dismissed early by clicking on it.
The foundation for this code was sent by user @ncotrb who was nice enough to donate it to the pool of demo programs.
The unique features of this program include:
-
Option to fade in / out the window
-
Changing the mouse pointer from an arrow to a hand when over the window
-
Entire window is drawn using a single Graph Element
I was trying to turn this demo into an something callable that would run this code as a subprocess, the idea being the ability to display a notification window at any point in a user's program regardless of the state of the caller's program or even which GUI framework is being used. Wasn't able to take the idea that far so perhaps someone else can make a try at it.
PySimpleGUI 2019-10-31T21:05:30Z
Reddit New PySimpleGUI Post
https://www.reddit.com/r/learnpython/comments/dpo0a8/first_pysimplegui_project/
( gist link is this - https://gist.github.com/quirksubdol/8390e53e70db2c03cb05ecf22408ca1e )
It's nice to see success stories.
What's remarkable about this program is that it was done by a student in their second week of a Python course. Talk about ambitious!
[EDIT] A day later and it continues to be upvoted :-) Nice! I'm glad the poster is feeling good about what he's done.
PySimpleGUI 2019-11-01T00:20:05Z
Another article!?
What's better than having your favorite Python author write a story about PySimpleGUI? I'll tell you what.... it's having TWO stories written! In under a week too!
http://www.blog.pythonlibrary.org/2019/10/31/the-demos-for-pysimplegui/
PySimpleGUI 2019-11-02T03:39:37Z
My Favorite Tweet
Total newcomer to Twitter, but finding it a fascinating place for Python stuff. Never used it for anything until a few months back.
Here's my favorite Tweet I've seen so far
PySimpleGUI 2019-11-03T18:52:19Z
Code sharing for Issues
I've been using Trinket to share code instead of Pastebin or pasting into a post somewhere. The reason is that people can immediately run the code.
If you are able to post your code on either Trinket or Repl.it to demonstrate a problem, I can guarantee you that you're issue IS going to get looked at quicker and ahead of others. The difference between "follow this link and see the behavior" and "add whatever code you need to in order to get my 5 lines of code to run" is like "biking to the grocery store" versus "taking a roundtrip to Mars"
One advantage these 2 platforms give you to try your code out on is that they are Linux based (perhaps you're running Windows / Mac or running a different Linux). It's another data point.
I'm not asking that everyone put their Issue code on Trinket. It just dawned on me how handy it is for troubleshooting in addition to demonstrating or teaching.
Maybe it's a terrible idea :-) I've got lots of ideas, they're not all good however.
EDIT.... oops, I forgot to share this bit of Trinket code as an example:
https://trinket.io/library/trinkets/49c5d264d8
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-'), sg.Text('', key='-OUT-')],
[sg.Button('Do Something'), sg.Button('Exit'),
sg.Button('-FOCUS-IN-', visible=False), sg.Button('-FOCUS-OUT-', visible=False)] ]
window = sg.Window('Window Title', layout, finalize=True)
window.TKroot.bind("<FocusIn>", window['-FOCUS-IN-'].ButtonReboundCallback)
window.TKroot.bind("<FocusOut>", window['-FOCUS-OUT-'].ButtonReboundCallback)
has_focus = True
while True: # Event Loop
event, values = window.read()
if event in (None, 'Exit'):
break
if event == '-FOCUS-IN-' and not has_focus:
print('Got focus!')
has_focus = True
elif event == '-FOCUS-OUT-' and has_focus:
print('Leaving focus!')
has_focus = False
window.close(); del window
This code was part of explaining how to get new "events" to be returned through calls to window.read()
.
It's one thing to see it, it's different to run it.
BTW, this particular extension to PySimpleGUI was only recently added and is not yet been released to PyPI from what I recall. It's on GitHub.
The idea here is to bind a tkinter event to a method in a Button. Yes, it's clunky for the time being. The point is to get you something that works with a small amount of code until a better way is written. It opens up a LOT of extending of PySimpleGUI for what little is added.
PySimpleGUI 2019-11-04T18:48:30Z
Screenshots - All of them but need fewer
I've had problems posting screenshots for people to see because GitHub will hide 100's of posts in an Issue from you. I found this site BounySource that archives GitHub best I can tell and doesn't hide any posts so that you can scroll through them all.
What's needed is maybe to put a few of the better ones in the Wiki???
I'm not sure of what the "better ones" would be. It's on the list to do... along with get the code written.....
https://www.bountysource.com/issues/60766522-screen-shots
https://www.bountysource.com/issues/79595971-screenshots-scratchpad-for-posting-and-documents
PySimpleGUI 2019-11-06T01:06:38Z
Release 4.5 PySimpleGUI 04-Nov-2019
FINALLY a release goes out and this is a big one!
Sorry it's taken SO long. The readme has finally been updated with the PEP8 bindings and evidently exceeds GitHub's size for the project's homepage. The ReadTheDocs still works though http://www.PySimpleGUI.org
-
Metadata!
-
All elements have a NEW metadata parameter that you can set to anything and access with Element.metadata
-
Windows can have metadata too
-
-
Window.finalize() - changed internally to do a fully window.read with timeout=1 so that it will complete all initializations correctly
-
Removed typing import
-
ButtonReboundCallback - Used with tkinter's Widget.bind method. Use this as a "target" for your bind and you'll get the event back via window.read()
-
NEW Element methods that will work on a variety of elements:
-
set_size - sets width, height. Can set one or both
-
get_size - returns width, heigh of Element (underlying Widget), usually in PIXELS
-
hide_row - hides the entire row that an element occupies
-
unhide_row - makes visible the entire row that an element occupies
-
expand - causes element to expand to fill available space in X or Y or both directions
-
-
InputText Element - Update got new parameters: text_color=None, background_color=None, move_cursor_to='end'
-
RadioButton - fix in Update. Was causing problems with loading a window from disk
-
Text Element - new border width parameter that is used when there's a relief set for the text element
-
Output Element - special expand method like the one for all other elements
-
Frame element - Can change the text for the frame using Update method
-
Slider element - can change range. Previously had to change value to change the range
-
Scrollable frame / column - change to how mousewheel scrolls. Was causing all things to scroll when scrolling a single column
- NOTE - may have a bad side effect for scrolling tables with a mouse wheel
-
Fix for icon setting when creating window. Wasn't defaulting to correct icon
-
Window.get_screen_size() returns the screen width and height. Does not have to be a window that's created already as this is a class method
-
Window.GetScreenDimensions - will return size even if the window has been destroyed by using get_screen_size
-
Now deleting window read timers every time done with them
-
Combo no longer defaults to first entry
-
New Material1 and Material2 look and feel color schemes
-
change_look_and_feel has new "force" parameter. Set to True to force colors when using a Mac
-
Fix in popup_get_files when 0 length of filename
-
Fix in Window.SetIcon - properly sets icon using file with Linux now. Was always defaulting
PySimpleGUI 2019-11-06T23:36:39Z
0.31.0 PySimpleGUIWeb 04-Nov-2019
It's been a LONG LONG time since a PySimpleGUIWeb release. So it's overdue, especially since the PEP8 binding have been held up. I've been wanting to make sure the animations would be flicker free before releasing again and thankfully the Remi team (of one) came through again! The OpenCV demos run in a browser as a result.
-
PEP8 bindings!
-
Window - NEW way of finding elements
- Use window[key] instead of window.FindElement(key)!!
-
Winow - "calling" an existing window object will call its read method
-
Version number added both dunder version and version work
-
Renamed some variables to be private by adding _ to the front
-
METADATA added to all elements and Window
-
Ability to "call" an element. The effect is to call that element's update method
-
Removed all delete functions in the classes. Were poorly done and not consistent
-
Output element - fix for color defaults, CurrentValue contains all of the text currently shown
-
Image Element
-
Rewrite done by Remi team!!!
-
Fixes flicker when using with OpenCV
-
-
Removed quite a bit of unused code
-
Added prints where items are not yet implemented
-
Window - finalize parameter added
-
Get screen dimensions always returns (0,0) for now until can figure it out
-
Made return values computation easier
-
Two new look and feel color settings - Material1, Material2
PySimpleGUI 2019-11-07T18:05:28Z
Meme Anyone?
I've never made a Meme, but I did make this illustrative diagram, perhaps for use when people go nuts online about how sh*tty PySimpleGUI is. I think it illustrates the point well. LOL.
I'm not knocking any other GUI package. They all have their purpose and "best use" scenario. I think you guys here on this GitHub already get this or you wouldn't be the awesome users you are. I dunno, a little humor goes a long ways, even if a tad sarcastic.
PySimpleGUI 2019-11-08T11:27:12Z
Posting Issues - Do NOT post your new issue as an addition to a closed issue
A problem has recently started happening where users with a problem simply tack their problem onto the end of a Closed Issue. This is a terrible problem. It circumvents the entire bug reporting, tracking, and ultimately bug fixing process. It also provides much less information than if a new issue was opened.
It's fine, of course, to reference a closed issue in your new open issue... by all means do that.
PySimpleGUI 2019-11-08T11:29:37Z
PySimpleGUIWeb 0.31.1 posted to PyPI
There was a corrupt init file that was uploaded as part of the PySimpleGUIWeb release that I didn't catch. Thankfully someone else did and reported it quickly.
I'm really sorry this happened! I'll strive to do a better job of testing the uploaded code in addition to installing it. I HATE BUGS, so it's appreciated when they're reported early like this rather than giving up and moving onto something else, assuming someone else will post something.
PySimpleGUI 2019-11-08T18:36:08Z
New Matplotlib Demo
Managed to get an interactive Matplotlib window to run in parallel with a PySimpleGUI window. The reason for doing this is if the user wishes to use the interactive tools that a Matplotlib window normally shows. It's actually really simple. Simple enough to post here:
import PySimpleGUI as sg
import matplotlib.pyplot as plt
"""
Simultaneous PySimpleGUI Window AND a Matplotlib Interactive Window
A number of people have requested the ability to run a normal PySimpleGUI window that
launches a MatplotLib window that is interactive with the usual Matplotlib controls.
It turns out to be a rather simple thing to do. The secret is to add parameter block=False to plt.show()
"""
layout = [[sg.Button('Plot'), sg.Cancel(), sg.Button('Popup')]]
window = sg.Window('Have some Matplotlib....', layout)
while True:
event, values = window.read()
if event in (None, 'Cancel'):
break
elif event == 'Plot':
history = [0.1, 0.2, 0.5, 0.7]
plt.plot(history)
plt.show(block=False)
elif event == 'Popup':
sg.popup('Yes, your application is still running')
window.close()
PySimpleGUI 2019-11-08T19:23:08Z
0.31.0 PySimpleGUIWeb 08-Nov-2019
It's getting to be like the old days of weekly releases. Whew!
I got more help from the Remi team!!!!!!!!! (Thank you Davide!!!)
Now the Output element scrolls correctly as does the MultilineOutput. Very nice to get this kind of help from such an expert.
So, I thought it important to push it out the door to everyone quickly.
PySimpleGUI 2019-11-10T02:04:25Z
Cookbook Updates
Released the first set of a series of updates to the Cookbook. This first set were for the initial sections, the first set of design patterns, and some PEP8 renaming. Hopefully 90% or more of the PEP8 conversions are done in that document. It's been released to readthedocs.
You might not know it, but it's available via: http://Cookbook.PySimpleGUI.org
I've had some excellent suggestions of things to add. One in particular is layout explanations.
I want to rework the multi-window patterns into something much more useful than the straight linear representation that's posted now.
Much more work still ahead for it as it's the active portion of the project at this moment.
Main docs Table Of Contents "fixed" for Elements
Was reported on Reddit as a problem... there were no entries at all for the call reference section. I guess the code changed or something that caused the header levels to get messed up. I've changed it so that the elements now show up in the table of contents (http://www.PySimpleGUI.org).
PySimpleGUI 2019-11-13T04:03:05Z
A More Colorful Cookbook
The Cookbook is getting a face-lift. All of the programs will include a call to change_look_and_feel
. There's no reason that all of the Cookbook window's need to be gray. They won't run slower and the sure won't look any uglier. OK, maybe some of the color choices made in creating some of the themes weren't stellar picks, they're still better than gray and black, right?
These Cookbook edits are being rolled out as they're completed. You can see the latest in the main documentation http://www.PySimpleGUI.org and clicking on the Cookbook tab or going directly to http://Cookbook.PySimpleGUI.org
More Colorful Demo Programs
The Demo Programs are also going to get the color treatment. It's only 1 line of code after all and it's a feature that may be being overlooked because there has been next to zero examples of these colorful windows shown anywhere but in the single "GreenTan" themed window showing all of the available elements.
More Colors
With this added bit of focus on the colors / themes comes the desire to get a lot more themes available. Working on some tools to help find more color palettes as well as displaying what already exists better in the documentation.
Will be adding something to show how every entry Look and Feel entry appears so that selection is easy. It will also help inform as to what colors are not represented well.
More Graphics
Also added to the Cookbook are detailed instructions on how to create buttons that have an image instead of a rectangle. Creating Base64 buttons are a capability I want to encourage new users to not be afraid of making a custom button. It's not difficult to do and it adds literally 1 line extra of code to add an image to a button if you store the button inside the source code itself, and 0 lines extra if the image is in a file.
More Pages!
The full set of PEP8 bindings were finally included in the main documentation. This added a few more pages to the documentation... OK, a lot more.
For fun I created a PDF from the ReadTheDocs site. It is 511 pages long. 291 of those pages are the detailed call signatures for the classes, methods and functions. Because both the original methods and PEP8 versions are included, the documentation is larger than would normally be the case.
If you want to take a look at the PDF version, you'll find it checked into the GitHub at this location:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/docs/DocSnapshotFromReadTheDocs12Nov2019.pdf
PySimpleGUI 2019-11-13T04:44:04Z
International Users
It's been fun to see users from many countries having success with PySimpleGUI. A few weeks back a bunch of folks from Japan started posting info on Twitter. This evening this tutorial was Tweeted:
http://www.facialix.com/aprende-python/tutorial-creacion-de-interfaces-graficas-en-python-usando-pysimplegui/
It's written in Spanish but Google Translated it perfectly for me. Even the jokes translated 👍
I honestly don't know how international users do it. It's difficult enough learning to code GUIs in Python. Throw on top of that documentation that's not professionally written, a new GUI API and a foreign language. Wow.... much respect for the international PySimpleGUI users.
PySimpleGUI 2019-11-14T15:41:48Z
Trinket Is On Fire! 🔥
I'm stunned by how much Trinket is being used by people that I guess are checking out PySimpleGUI. The Trinket links have been posted a number of places including the main documentation, the Cookbook, and many Reddit posts.
It's been a great teaching aid in my opinion as not only can the code be shared and executed right on the site, but the "Lessons" built using the programs can include screenshots, explanatory text, etc. It's like an Interactive Cookbook. In fact, the entire Cookbook could probably be done there using the Lessons.
Looking at the list this morning, I see a LOT that have been looked at just in the past hour. I noticed this a few days ago and is doesn't seem to be letting up. The next page of the list below shows more of the Trinkets being viewed in the past 8 hours, day, etc.
There's a "lesson" to be learned here. I'm not sure what it is exactly, but something's hidden down in these stats.
PySimpleGUI 2019-11-15T14:54:01Z
2,500 Stars! THANK YOU!
Finally hit another nice milestone!
Of all the metrics that I have access to, I think stars on the GitHub are one of the best ways for me to judge "popularity" or "actual use". The reason I think this is the most accurate is that a human being needs to mouse up to that "STAR" button and click it. I don't believe anything automated is doing this.
Thanks again for being an awesome community.
It's nice to see the support and how thankful many of you are. It's really appreciated when you say "Thank You for PySimpleGUI".
For me, it's a nice compliment, but what registers more is that a difference was made. Someone, a person, a programmer, a non-programmer, a human being benefited from this thing that was made. kSomeone may have been able to make their first GUI using PySimpleGUI. Or maybe they finally made their first GUI, after having tried before. Or...? Who know, but I'm going to take it as a difference of some kind was made and that's a really nice thing to read.
Thank you for your patience
I know things have been a bit slow, but know the best that can be done is being attempted. Some of these bugs and stuff may take a week or more to get to fixing and releasing. My hope is that in the meantime you are able to continue to make progress on your project in some other way or using a workaround or patched code.
I've been "patiently waiting" for the PyCharm bug fix that will enable docstrings to work for all of the renamed classes. It's been a very long time. So, if you've been waiting a very long time for a bug, I'm really sorry. If you think it's been "lost" say something so that it's brought back into the queue of stuff that's being actively worked.
Thank you for the support
That's the overall message here.
PySimpleGUI 2019-11-15T18:50:55Z
Look and Feel Theme Additions - Almost Completed
Have been working on adding a LOT of new color themes as well as a renaming the existing ones using a new naming convention. The old names still work, don't worry!
The new theme names all start with either Light or Dark followed by the background color and sometimes a number. This will allow you to "Guess" at some themes to try.
Maybe you're looking for a dark theme with a purple background... DarkPurple, DarkPurple1, DarkPurple2, etc, are good candidates for you to try.
If you want a preview of these Themes, you can simply call:
And you will be shown a window like this:
It's a super-quick and easy way for you to choose a theme. Drop that one line at the top of your code to get the window and then write down the theme name.
Fuzzy Theme Names
One new addition (thank you @Israel-Dryer) is a fuzzy theme name matcher. This allows you to specify theme names that are not exactly the same as the one shown on the preview. You can add spaces for example. Or swap words around. It's very clever and the results are nice. You can guess at themes and be confident you'll see SOME colors on your window. I can't guarantee that'll look great, but you can always choose another.
Back to Bugs / Issues after this
Trying to get bugs fixed in-between this Theme stuff, but finding it hard to multi-task when in heads-down mode. Give me another day and I'll get back to the queue of Issues.
The Code to Make Preview Window
I wanted to also share this code that was released as a demo. It's pretty extraordinary that the previewer window with all those themes was made without needing to do anything special in PySimpleGUI. It's shockingly short, AND, it runs on all of the platforms except for PySimpleGUIWx which is still lagging a bit. But as you can see, it runs on tktiner, Qt, and Remi. For Remi because the frame isn't labelled, I needed to add a line for the text telling the name of the Theme.
One of the things I like about this code is the use of "User Defined Element" or "Compound Element" which is the sample_layout
function. I also like how the window is built using simple +=
operators. It makes putting together a layout look very easy for a beginner.
[EDIT] OH! I forgot the best thing that I discovered while making it... you can change look and feel settings midway through a layout definition and the new values will be used for the elements that follow the change. That is how I managed to get 1 single window to display all of the Themes. Note at the top of the loop where the Frames are being added, there is a call to change_look_and_feel.
import PySimpleGUI as sg; web=False
# import PySimpleGUIWeb as sg; web=True
# import PySimpleGUIQT as sg; web=False
WINDOW_BACKGROUND = 'lightblue'
def sample_layout():
return [[sg.Text('Text element'), sg.InputText('Input data here', size=(15,1))],
[sg.Button('Ok'), sg.Button('Cancel'), sg.Slider((1,10), orientation='h', size=(10,15)) ]]
layout = [[sg.Text('Here is a complete list of themes', font='Default 18', background_color=WINDOW_BACKGROUND)]]
row = []
for count, theme in enumerate(sg.ListOfLookAndFeelValues()):
sg.change_look_and_feel(theme)
if not count % 9:
layout += [row]
row = []
row += [sg.Frame(theme, sample_layout() if not web else [[sg.T(theme)]]+sample_layout())]
if row:
layout += [row]
sg.Window('Preview of all Look and Feel choices', layout, background_color=WINDOW_BACKGROUND).read()
PySimpleGUI 2019-11-16T03:37:31Z
Presenting... the PySimpleGUI Color Palette... 108 Choices of Color Combinations
Just about DONE with the work on turning 1,700 of color palettes into PySimpleGUI Themes. I don't know how good of a job I did, but at least a new "Standard" fell out of the process.
When starting on this last week, there were 27 different look and feel "themes". Now there are 108. The original 27 are still there, with their original names. AND, they've been duplicated using the new naming convention.
New Naming Convention
The way the new names work is as follows. First there's a Dark / Light designation. Then the background color, then a number from 1 to N, where N can and will vary per entry. For example, there are 4 "DarkGrey" settings and 6 "DarkPurple".
There are also 2 special names, Default, Default1. The first being the system defaults with the PySimpleGUI default buttons and Default1 specifies that all elements use the system defaults including the buttons. BLAND... please don't add to the number of boring gray windows. You don't have to go nuts with color, but damn, anything is better than gray on gray on gray.
New Fuzzy Matching
Finally, the name you pass into the change_look_and_feel
call itself can now vary. No longer do you have to spell the dictionary key letter for letter. Now you can add spaces, mix around the words, and the code will attempt to find a matching theme for you.
Rewarded For Your Mistakes
Rather than punishing you with a gray window if you choose a Look and Feel Theme color that's not valid, you'll instead be treated to a random window Theme. You'll still be warned on the console about the error, provided with a list of valid entries, but the main window will be themed using a random palette. It's good to branch out every now and then and try something new, right? Well, now you don't have a choice.
Reminder - This is currently only located on GitHub and is currently only been made to the tkinter port. Once finalized, all ports will get updated quickly.
The Official List
I think this is the final list and that no changes will be made that will break your code if you were to use it.
But What If I Don't Remember
If you're ever in need for the quick reference image above but don't know where to find one, then generate one yourself by calling:
and you too will be treated with a large window filled with these little frames.
PySimpleGUI 2019-11-16T09:38:40Z
4.6.0 PySimpleGUI 16-Nov-2019
-
Themes!!!
-
Added a LOT of Look and Feel themes. Total > 100 now
-
Doctring comments
-
PEP8 bindings for button_rebound_collback, set_tooltip, set_focus
-
Spin Element Update - shortened code
-
Allow tk.PhotoImage objeft to be passed into Image.update as the data
-
DrawRectangle - added line_width parameter. Defaults to 1
-
Fix for Slider - was only setting the trough color if the background color was being set_focus
-
Added a deiconify call to Window.Normal so it can be used to restore a window that has been minimized. Not working on Linux
-
Combo - Fix for not allowing a "0" to be specified as the default
-
Table - Saving the Frame that contains a table in the member variable table_frame. This will enable the frame to be changed to expandable in the future so that the table can be resized as a window expands.
-
LOTS AND LOTS of Look and Feel themes!!!!
-
Added SystemDefaultForReal to look and feel that will prodce 100% not styled windows
-
Changed the "gray" strings in look and feel table into RGB strtings (e.g. gray25 = #404040). No all graphics subsystems
-
Removed Mac restriction from Look and Feel setting changes. All color settings are changed EXCEPT for the button color now on a Mac
-
"Fuzzy Logic" Look and Feel Theme Selection - No longer have to memorize every character and get the case right. Now can get "close enough" and it'll work!! (Thank you again @Israel-dryer for this bit of technology)
-
New function - preview_all_look_and_feel_themes. Causes a window to be shown that shows all of the currently available look and feel themes
-
Removed use of CloseButton in popup get file, folder, text. Was causing problems where input fields stopped working. See bug on GitHub
PySimpleGUI 2019-11-16T16:33:08Z
To Finish The Themes.....
I've made the changes to all 4 ports to support the new Color Themes as well as the new functions to display them, etc. Note that the PySimpleGUIWx port doesn't have the Frame Element completed so the function that displays all of the settings in a window doesn't work yet on PySimpleGUIWx (hmmmm.... a damned good reason to complete that work!)
PySimpleGUI 2019-11-16T20:33:00Z
0.30.0 PySimpleGUIQt 16-Nov-2019
TWO ports down with the new themes! (plus more stuff in there too...)
-
THEMES!! Over 100 new Look and Feel themes to choose from!
-
New func preview_all_look_and_feel_themes() that will display a large window with all possible themes shown
-
Metadata! Now available on all elements when creating and accessable directly by program
-
Metadata added to SystemTray objects and Window objects
-
Metadata parameter added to all shortcut buttons and funcs
-
Completed removal of PyQt5 code
-
ML, MLine shortcuts added for Multiline (input)
-
MLineOut shortcut for MultilineOutput
-
Text element text is optional now
-
Fixed bug in BrowseFiles button. Was only getting first item in list instead of full list of filenames
-
BMenu shortcut for ButtonMenu
-
PBar, Prog shortcuts for ProgressBar
-
Range is now properly set in Slider.Update
-
Background color supported for MenuBars now
-
Added 5 extra pixels to window size. Now adding a total of 10 so things don't get cut off
PySimpleGUI 2019-11-18T01:26:05Z
0.14.0 PySimpleGUIWx 17-Nov-2019
-
105 Look and Feel Themes to choose from!
-
New "Fuzzy" look and feel selection
-
Preview all look and feels not yet supported due to lack of Frame support
PySimpleGUI 2019-11-18T01:26:21Z
0.33.0 PySimpleGUIWeb 17-Nov-2019
-
Added autoscroll parameter to the MultilineOutput.update method
-
TONS of new Look and Feel Themes
-
Fuzzy name matcher for change_loo_and_feel call - string doesn't have to perfectly match now
-
New preview_all_look_and_feel_themes function displays all of the colors for the Themes
PySimpleGUI 2019-11-18T01:28:22Z
ALL FOUR of the PySimpleGUI ports have been updated on PyPI!
It's been over only a 2-day span that the new color themes were completed and integrated into each of the ports. Now all of them have been posted to PyPI so it's safe for you to use the theme colors across all of the ports.
The pressure was on to get all those themes out at the same time. It is important that PySimpleGUI code stay as in-sync as possible. This was an opportunity to get things synced up a little. At least all the colors are present in the ports.
PySimpleGUI 2019-11-18T17:52:42Z
Mini-Excel Demo Program
Not sure where this idea came from... likely Reddit. Someone asked for an excel-like GUI that allows you to navigate using the arrow keys. This one also allows you to sort data by clicking on a column heading. There's also a button that dumps the data out in a list format so you can paste into code.
You can run the code online on Trinket.
https://pysimplegui.trinket.io/demo-programs#/tables/navigate-using-arrow-keys-sort-by-column
Of course it's also in the Demo Programs area:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Table_Simulation_Arrow_Keys.py
Clicking "Show Table" button shows this window that you can copy from
One thing to notice about this demo is the layout definition....
layout = [[sg.Text('Click on a column header to sort by that column', font='Default 16')]] + \
[[sg.Text(' ' * 15)] + [sg.Text(s, key=s, enable_events=True, font='Courier 14', size=(8, 1)) for i, s in enumerate(COL_HEADINGS)]] + \
[[sg.T(r, size=(4, 1))] + [sg.Input(randint(0, 100), justification='r', key=(r, c)) for c in range(MAX_COLS)] for r in range(MAX_ROWS)] + \
[[sg.Button('Show Table As Lists'), sg.Button('Exit')]]
It is created by "adding together" multiple layouts. There is a section in the documentation about creating layouts in this manner.
The reason for doing it this way is the two list comprehensions that are present in the middle 2 sections of the layout.
PySimpleGUI 2019-11-19T05:07:25Z
Cookbook Updates Continue
A reminder that the Cookbook is undergoing a series of updates. A good number of recipes and information that's been put in recently has been in the area of..... THEMES!
Yea, the topic that won't seem to go away, but it will soon I promise. To date there has been no place where modifying themes or explaining how to make new one has been posted in any of the docs. So, taking the opportunity to document the Look and Feel Themes while continuing the Cookbook changes.
There is at least another 50% more of the Cookbook that needs updating so I don't expect the update work to complete in the short term.
PySimpleGUI 2019-11-19T15:31:35Z
New PySimpleGUIQt Demo - imwatchingyou
Combined with PySimpleGUIQt
In case you're new to PySimpleGUI or wasn't aware of the built-in debugger or the standalone imwatchingyou package, here's a quick reminder.
The base PySimpleGUI package has the imwatchingyou
debugger built into it. The other ports of PySimpleGUI do not have the debugger built into them.
PySimpleGUI 2019-11-19T16:52:58Z
Thread Demos Rework / Rename
There was some overlap in the multi-threaded demos. There are currently 4 Demo Programs that are multi-threaded design patterns:
-
Demo_Multithreaded_Different_Threads.py - Uses multiple functions (threads), each potentially doing different work
-
Demo_Multithreaded_Long_tasks.py - Design pattern meant for a single piece of work that takes a long time
-
Demo_Multithreaded_Multiple_Threads.py - Uses a single function but runs it as multiple threads
-
Demo_Multithreaded_Logging.py - A user supplied demo that integrated a multi-threaded logging project with PySimpleGUI
The Multiple Threads Demo is currently running on Trinket. May also add the Long Tasks one since it's the simplest of the 4.
PySimpleGUI 2019-11-19T17:13:41Z
MAC USERS - change_look_and_feel
is enabled for you in PySimpleGUI (tkinter port)
One part of releasing the 100+ color themes was to open it up for Mac users. You guys can now use the colors. I'm not sure why I didn't think of this before.... all of the colors are changed except for buttons. I believe only the button colors are causing trouble on Macs (a very very old problem).
Please give it a try and see if things look good to you or not. If a Demo Program changes the look and feel and it's not a good one for you, then you can simply delete the call to change_look_and_feel
.
Welcome to the world of color! I hope the experience doesn't suck.
PySimpleGUI 2019-11-21T15:27:42Z
MAC USERS - New Button Solution For tkinter Port!!
Mac users have had a really rough go of things with PySimpleGUI, the plain tkinter port. The big problem has always been button color. This has left Mac users with 2 options.
-
Live with only white buttons with black text
-
Switch to PySimpleGUIQt
The downsides are pretty evident. The two biggest in my opinion - You miss a lot of the new features as they are added to PySimpleGUI first and then cross-ported over to PySimpleGUIQt. And the second is that Qt is huge in size.
Yesterday I stumbled onto a solution! (I also asked for help with ttk styling to that maybe ttk Buttons can be used in the future).
That solution is to use a Text
element. Your buttons will be a little square-ish, but they already are pretty close to that with tkinter (NO knock to you tkinter!). I created a McButton
as a test. It would be great to get some Mac users' feedback on how this looks.
Here is the McButton
in use on a Window's machine along with a normal button:
And here is the code:
import PySimpleGUI as sg
sg.change_look_and_feel('Dark Blue 3')
def McButton(text, button_color=sg.DEFAULT_BUTTON_COLOR, key=None, size=(None, None)):
return sg.Text(text, size=size if size != (None,None) else (len(str(text))+1,1), relief=sg.RELIEF_RAISED, enable_events=True, key=key if key is not None else text, text_color=button_color[0], background_color=button_color[1], justification='center', border_width=1)
layout = [ [sg.Text('Test of Buttons')],
[sg.Input(key='-IN-')],
[sg.Button('Button?', size=(8,1), key='-NORMAL BUTTON-'), sg.Button('Exit', key='-EXIT-')],
[McButton('Button?', key='-MAC BUTTON-'), McButton('Exit')]]
window = sg.Window('Button Test', layout)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event in (None, 'Exit', '-EXIT-'):
break
window.close()
If this works well for Mac users (PLEASE try, and try changing the look and feel too), then I will begin designing how to make the McButton the standard for Macs and function in a way that is as close to the normal button as possible. It'll be tricky but I think it's possible.
At the moment, this solution is limited in that a BrowseButton doesn't use them. It's an entirely user-code based solution at the moment.
However, if a user wanted to create their own browse button it's possible, but I need to make a change to the Browse buttons so that they can be created invisible. As it is now, you'll need to make these buttons invisible yourself.
One Browse workaround would be to
-
create the Browse Button
-
make the Browse Button invisible (after finalizing the window)
-
add a McButton with 'Browse' as text to your layout
-
inside the Event Loop, if you get a click on the Browse McButton, then call the real Browse Button's
click
method
Here is a program that demonstrates doing this
import PySimpleGUI as sg
sg.change_look_and_feel('Dark Blue 3')
def McButton(text, button_color=sg.DEFAULT_BUTTON_COLOR, key=None, size=(None, None)):
return sg.Text(text, size=size if size != (None,None) else (len(str(text))+1,1), relief=sg.RELIEF_RAISED, enable_events=True, key=key if key is not None else text, text_color=button_color[0], background_color=button_color[1], justification='center', border_width=1)
layout = [ [sg.Text('Test of Buttons')],
[sg.Input(key='-IN-'), sg.FileBrowse(key='-REAL BROWSE-'), McButton('Browse', key='-McBrowse-')],
[sg.Button('Button?', size=(8,1), key='-NORMAL BUTTON-'), sg.Button('Exit', key='-EXIT-')],
[McButton('Button?', key='-MAC BUTTON-'), McButton('Exit')]]
window = sg.Window('Button Test', layout, finalize=True)
window['-REAL BROWSE-'].update(visible=False)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event in (None, 'Exit', '-EXIT-'):
break
if event == '-McBrowse-':
window['-REAL BROWSE-'].click()
window.close()
Of course it's not an ideal way to do things, but it works. If you've been watching, one thing I'm focused on generally speaking is getting users enabled to do something. If there's a problem that I can't immediately fix then I try to find a workaround at least. Some are better than others.
This workaround isn't all THAT bad in the end. To get a Browse Button you'll need to add 1 extra element to your layout and add 3 lines of code. That's it. As workarounds go, this one is pretty good.
I'll post this as another Issue as I would like a conversation to happen about this with Mac users before any serious attempt be made to create a new type of Mac specific button as it could be a fair amount of work.
emallay 2019-11-21T16:00:09Z It doesn't build for me. Error triggered by line 13 in the code, with error of:
File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/init.py", line 1476, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown color name "2"
Running on a Mac 10.14.5 with Python 3.7.3 and PySimpleGUI v4.6 via PyCharm. As a quick test, I pasted in your Color Pallet script from your earlier post and that ran fine on my system.
PySimpleGUI 2019-11-21T17:17:35Z I've opened a new Issue for these tests....
https://github.com/PySimpleGUI/PySimpleGUI/issues/2226
I just posted an update there. I needed to hard code the buttons. Please try the code from the Issue. There are 2 tests.
Sorry about that!
PySimpleGUI 2019-11-21T22:01:26Z
New Send Email Demo Program
Created another "integration" type of demo. In this case it integrates PySimpleGUI with smtplib which is actually not a huge deal to do of course. The GUI portion is a basic form that you fill out and then click "send". No magic there at all.
The magic in this particular demo is the imports....
import PySimpleGUI as sg
# import PySimpleGUIWeb as sg
# import PySimpleGUIWx as sg
# import PySimpleGUIQt as sg
Take your pick of ports. They all work. It's the kind of thing that's supposed to happen with PySimpleGUI where 1 program can be run on any of the PySimpleGUI ports. For this one it worked out really well with the exception of the popup_quick_message
call. Autoclosing popups aren't functional yet in the web port, but they are in the other ports.
The way I got around this limitation was to not make the popup call if the port being used is the web port:
if sg.__name__ != 'PySimpleGUIWeb': # auto close popups not yet supported in PySimpleGUIWeb
sg.popup_quick_message('Sending your message... this will take a moment...', background_color='red')
There's a new variable added to each off the ports that can be used in the future to tell which port is being used. This will remove the need to rely on the filename to match the port's name. The variable is call.... port
. So instead of using sg.__name__
in the future you'll be able to use sg.port
(after I get the change released to PyPI.
Here is how the 4 ports looked when running this code:
It's awesome that the Themes worked! The "Dark Blue 3" worked right out of the box.
When a Demo is created, it's usually tested against at least PySimpleGUIQt.
PySimpleGUI 2019-11-23T21:19:57Z
Weekend goal == ttk.Button
== Mac Buttons for real
I've decided to take yet another shot at ttk styling.
So far today I've had a couple of breakthroughs on the existing ttk widgets (Tab group, combo, progress bar and also tables (table background colors are working again!)).
It's got me hopeful that I can get the real ttk buttons working which means.... Buttons for Macs!!!!!
I mean real buttons for Macs too... and it also means better looking buttons for Linux and PCs perhaps too.
It's going to take a ton of work but worth it in my opinion.
One key to all this mess seems to be NOT mixing "Themes". It I try to style one widget using the "default" theme and another using the "clam" theme, then one of them loses all styling. This was an ongoing problem and in fact a number of things have been broken due to this.
It means, however, potentially have to choose a single theme for the entire window and sticking to it even though some elements expose the theme to you.
It may be safer to make a theme setting for the Window object and use that instead of the individual element themes. This will save you from having to set the theme for each element. Hmmm... a good idea regardless perhaps.
Anyway, goal for the weekend is ttk buttons! Stretch goal is to not lose button images in the process.
PySimpleGUI 2019-11-24T05:54:43Z
TTK BUTTONS! (And the other ttk widgets work properly now too)
I finally had the breakthrough I've been waiting almost 2 years for... oy... There has been SO much time wasted, err spent, on this ttk stuff, but it's worth it since there was really no other way to implement some of these Widgets (combo boxes, tabs, tab groups, tables, trees, ....)
Now things like the background color of tables work properly as do the "selected tab color".
There were 2 new parameters added to the Window call.
One is to override the use of normal buttons and to instead force that ttk buttons be used. At the moment, ttk buttons are only used on the Mac by default.
The other is a "theme" setting. Instead of setting themes on individual elements, you set them on a window-wide basis. The choices are till the same:
THEME_DEFAULT = 'default'
THEME_WINNATIVE = 'winnative'
THEME_CLAM = 'clam'
THEME_ALT = 'alt'
THEME_CLASSIC = 'classic'
THEME_VISTA = 'vista'
THEME_XPNATIVE = 'xpnative'
There still needs to be a bunch more work to be done in order to get the size parameter to make sense and to attempt button images. I might also add a parameter to the Button element itself so that individual buttons can be made to be ttk buttons instead of the entire window having to be ttk buttons or not.
Popups need to use the right settings too. It works for the default, but there needs to be a system-wide setting of whether or not to use ttk buttons too so that popups choose the right one.
For now I'm thrilled I've got SOMETHING for Mac people to try that may fix the button problems once and for all!! THAT would be quite a Christmas present!
PySimpleGUI 2019-11-24T22:46:27Z
Demo Program -Demo_Cursor_Changed_To_Hand.py
(Extending PySimpleGUI-tkinter)
New demo program!
Not long ago I saw someone extend the tkinter PySimpleGUI by changing the cursor that is shown when the mouse is placed over one of the Elements. It's a handy thing to be able to change the cursor (mouse pointer) into a hand when the mouse is over a clickable link.
As usual when extending PySimpleGUI it involves accessing the tkinter Widget directly. In this case you call the config
method for the tkinter widget and pass in a string for the parameter cursor
.
Rather than post the entire program, here is the line of code to add to change an element's cursor / mouse pointer.
# This is a line from the layout
[sg.Text('www.PySimpleGUI.org', font=('default 12 underline'), text_color='blue', enable_events=True, key='-LINK-')],
# This line changes the cursor for that Text Element
window['-LINK-'].Widget.config(cursor='hand2')
The result is that when the mouse pointer is moved over the Text it is changed into a hand.
There are a shocking number of cursor's available.
I found that the 'watch' cursor animates on Windows as the "spinning donut of death".
PySimpleGUI 2019-11-25T07:01:48Z
Tip - Use popup_quick_message
before long operations
It's no fun to have a GUI that takes a long time to start before you're able to show the main window. For programs that take a long time to startup, I never quite know if the program was started or not. Some of these tkinter based applications with a lot of button or input fields can take several seconds to build and show the window. In the meantime, the user sits wondering if they need to double click again.
Rather than sit wondering, instead display a message using a popup
. You don't want to use a normal blocking popup window. What you need is something that will not block and will also auto-close once the main window finishes loading. The popup call that will do this exact thing for you is the popup_quick_message
.
This popup displays a message without a titlebar and will automatically close after a certain amount of time. Regardless of how much time is being requested for the autoclose, the autoclose will not happen until the long operation completes. The reason for this is that tkinter is not threaded and so until you make another tkinter call, the autoclose won't be able to run.
The result is that the message stays on the screen for as long as your operation takes.
This line of code:
sg.popup_quick_message('Building your table... one moment please...', background_color='red', text_color='white', font='Any 14')
creates this window which will close when your real window is created:
So, the next time your program is taking a long time to start, throw a line of code like this onto the start of your program. It makes for a better user experience, even if that user is you.
PySimpleGUI 2019-11-26T04:25:17Z
Release Candidate 4.6.0.66 - ttk buttons and themes/styles - Almost ready for PyPI
I'm ready to post to PyPI but want a Mac person to try this new release first. There's no posting to PyPI if it doesn't work on the Mac.
Windows and Linux users are going to want to get this release too as all of the ttk Element have their colors and styles working correctly now, perhaps for the first time. The secret is to not attempt to mix themes across elements/widgets or even across windows. Pick a theme and stick with it.
This release feels like a significant one in many ways and really hope that it brings Mac folks back into the tkinter tent rather than being forced out and over to PySimpleGUIQt as the only other option.
It also gives windows users a lot more styling options for Tables, Trees, Comboboxes, Progressbar, and Buttons. There are other ttk widgets that are worth look over now that I know how to configure them.
I'm working on release notes now. Hoping to hear from a Mac user tonight as a quick verification so that I can post to PyPI.
PySimpleGUI 2019-11-27T00:04:41Z
4.7.0 PySimpleGUI 26-Nov-2019
TTK WIDGETS! Welcome back Mac Users!
-
Significant progress on using ttk widgets properly
-
Added ttk buttons - MACS can use colored buttons again!! (Big damned deal)
-
The existing ttk based Elements are now correctly being colored and styled
-
Ability to set the ttk theme for individual windows or system-wide, but no longer on a single Element basis
-
Ability to use ttk buttons on a selective basis for non-Mac systems
-
port variable == 'PySimpleGUI' so that your code can determine which PySimpleGUI is running
-
InputText new parameter - use_readonly_for_dsiable defaults to True enables user to switch between a true disable and readonly setting when disabling
-
Rework of progress bar's ttk style name
-
Button - new parameter use_ttk_buttons - True = force use, False = force not used, None = let PySimpleGUI determine use
-
Macs are forced to use ttk buttons EXCEPT when an image is added to the button
-
TabGroup - can no longer set ttk theme directly
-
Window new parameters
-
ttk_theme - sets the theme for the entire window
-
use_ttk_buttons - sets ttk button use policy for the entire window
-
-
More Window layout error checking - checks that rows are iterables (a list). If not, an error popup is shown to help user find error
-
Fixed progessbars not getting a key auto assigned to theme
-
New Window method - send_to_back (SendToBack) - sends the window to the bottom of stack of all windows
-
Fixed normal tk button text - was left justifying instead of centering
-
Fixed table colors - wasn't setting correctly due to bad ttk styling
-
Fixed tree ccolors - wasn't setting correctly due to bad ttk styling
-
TabGroups now function correction with colors including currently selected tab color and background color of non-tab area (next to the tabs)
-
New set_options parameters
-
use_ttk_buttons - sets system-wide policy for using ttk buttons. Needed for things like popups to work with ttk buttons
-
ttk_theme - sets system-wide tth theme
-
progress_meter_style parameter no longer used and generates a warning
-
-
list_of_look_and_feel_values now sorts the list prior to returning
-
Removed Mac restriction on Button colors from look and feel calls. Now can set button colors to anything!
-
popup_scrolled new parameters - all popups need more parameters but these are for sure needed for the scrolled popup
-
background_color
-
text_color
-
no_titlebar
-
grab_anywhere
-
keep_on_top
-
font
-
-
Test harness changes to help test new ttk stuff (want to shrink this window in the future so will fit on Trinket, Pi, etc
Why the big fuss about Mac users?
Button colors now work on the Mac when running the tkinter port of PySimpleGUI (plain PySimpleGUI).
At the moment Mac users either pass on the package or use PySimpleGUIQt.
Now Mac users can enjoy all of the more advanced / early features of PySimpleGUI that they miss if only running PySimpleGUIQt.
Upgrade!
Be sure and delete any PySimpleGUI.py files you have laying around that you downloaded from GitHub. The bug fixes have been rolled into this PyPI release so you should no longer need the version you download.
There are plenty of other reasons to upgrade including that ALL ttk widgets should operate properly now - Table, Tree, Combo, Button, ProgressBar,Tab/TabGroup. That's a LOT of elements that were affected. The colors should work where they were broken before. The THEMES will also now properly work, BUT, you should be aware of the new way themes work.
ttk Theme have not been properly documented
Previously ttk themes were selectable on a per Element basis... at least that's what was being attempted, with the result being utter failure. They no longer are.
Themes are set at the Window and System Levels. Note that mixing themes in a multi-window application is dicey.
To set a window's theme, use the ttk_theme
parameter when you create your Window
. You can also change the theme system-wide so that all windows created will be the same theme. This is done via set_options
ttk Buttons
The Mac will use ttk buttons by default. If the button has an image, then it'll use the older buttons. On Window/Linux, you can use ttk buttons, but again, normal buttons will be used when buttons with images are shown.
The parameter use_ttk_buttons is a tri-state boolean:
None
- use default algorithm. on Windows non-ttk buttons are used. On Mac ttk buttons are used
True
- use ttk buttons for all normal buttons
'False' - do not use ttk buttons for any buttons (Including on the Mac)
You can specify use of ttk buttons at the individual button level, for an entire window, or for all windows. For example, to switch over to 100% ttk buttons you call set_options
More docs soon
The readme has been updated but more updates are needed this week for sure!
The priority was to get the calls documented and get the code shipped ASAP! Wanted to get these Buttons out to Macs users ASAP.
PySimpleGUI 2019-11-28T02:23:14Z
Unicode Character Demo
Added a new demo (Demo_Unicode_Characters.py) that spotlights the use of Unicode characters in PySimpleGUI programs.
These made great arrows for buttons for example.
You can use the demo to dump out ranges of the characters, copy and paste individual characters for use in your code, etc.
You can directly paste these characters straight into your code. Want an right arrow button? No problem:
Which results in:
There are a couple of other tricks in this demo such as:
-
changing the font size of a multiline output element on the fly using a spinner.
-
using an animated popup for long-running operations
-
calling refresh while updating a multiline so that the GUI doesn't appear to freeze and the user sees the updates immediately
Enjoy!
PySimpleGUI 2019-11-28T12:25:32Z
Thankful for awesome users!
Hope everyone has a great holiday
Wanted to take a moment and thank everyone for creating a great community here on GitHub. It's been a good year and so many of you are patient and show your appreciation even when reporting problems that are holding up your progress. It's honestly appreciated and makes it easy to work on this package.
Hoping to get quite a bit done with the time left in 2019.
This month marks my second year using Python and it's been a ton of fun. I learn from every PySimpleGUI program I read.
PySimpleGUI 2019-11-30T04:29:15Z Any other PySimpleGUI users that work with pen and paper? Digging back through the old notes to get the feature matrices for the ports. There's been a significant detour over the summer to deal with the project infrastructure (documentation, the Trinket online Cookbook, etc).
Here are a few of the notebooks that were used to create PySimpleGUI. For me it's gotta work on paper before it works on the computer.
To get back on track with the ports I need the feature matrices put onto a Kanban board so they can be prioritized and worked along with the Issues and Enhancement requests.
"If you don't know where you're going, any road will get you there"
PySimpleGUI 2019-11-30T07:18:42Z
New Custom Color Chooser Demo Program
This demo you can use to make your own color picker instead of the builtin one.
The demo is called Demo_Color_Chooser_Custom.py. It consists of a function and a test harness.
With VERY minimal changes I was able to get the code to run on all four ports of PySimpleGUI!
Here's the test harness which is essentially the user code that would use the chooser button.
if __name__ == '__main__':
sg.change_look_and_feel('Light Brown 4')
layout = [[sg.In(key='-CHOICE-'), sg.B('Color Picker')],
[sg.Ok(), sg.Cancel()]]
window = sg.Window('My application', layout)
while True:
event, values = window.read()
if event in (None, 'Cancel'):
break
if event.startswith('Color'):
window.hide()
color_chosen = color_chooser()
window['-CHOICE-'].update(color_chosen)
window.un_hide()
When you run the code, this is your user's window:
When you click on the Color Picker button:
After choosing a color:
Here are the different ports of PySimpleGUI and the window that was built
PySimpleGUI 2019-11-30T08:05:35Z
Warning # 1 - PySimpleGUI27 will be deleted on Dec 31, 2019
December is upon us and that means the countdown until the end of life for Python 2.7.
As stated a number of times, PySimpleGUI27 will be removed from this GitHub on Dec 31 of this year. If you want a copy of the 2.7 code, now is the time to make the copy because it's going to disappear.
I'll send out a number of warnings between now and the 31st.
PySimpleGUI 2019-11-30T23:47:51Z
New and Improved "Theme Maker" Posted
One thing I want to encourage all users to do is USE COLOR for your windows! Please no more gray windows. If I thought there wouldn't be a revolt I would make the default window be one of the look and feel themes, but I don't want to go that far. It's already a stretch using the blue buttons as the default.
To make it easier for people to create their own themes using the 1700+ color palettes downloaded from colorhunt https://colorhunt.co/palettes I've reworked the Theme Maker program that I used to create the latest batch.
This new version is much more user friendly as it has an initial popup window that lets you select how many candidate themes to see per window (not everyone has enormous monitors evidently) as well as enable you to jump into the middle of the palette table.
Those settings will create a single row of "candidate themes" based on a single palette entry, starting at palette #500. The resulting window was this:
(I kinda like the far right one! But will refrain from adding more at this point)
I started hunting at the beginning of the palette table when creating the last batch of themes. I didn't make if very far into the 1,700. Even starting at 500 should give you a fresh batch of themes to choose from.
So, next time you're really stumped for a good color theme, you can always download the theme maker and see if something it creates catches your eye.
If you do come up with another awesome theme then post it as an enhancement and I'll consider adding it to the standard list available to all users.
New variable - CURRENT_LOOK_AND_FEEL
The current look and feel is now saved so that you can change the look and feel and then set it back again. This was used in the recent custom color chooser demo. It's written as a popup what allows you to pass in a look and feel to use. It will use the supplied look and feel and then will set it back to the one that was previously in use.
PySimpleGUI 2019-12-01T01:31:19Z
TTK Buttons With Images
Checked in changes today that enable you to:
-
specify buttons for ttk Buttons when you create them
-
perform updates to ttk Buttons to change the images
I believe this will put ttk Buttons at the same level as normal buttons.
I'm waiting for confirmation from Mac users that the images work before I release to PyPI. Once I get some feedback, I'll release it beyond GitHub.
background = sg.LOOK_AND_FEEL_TABLE['LightBrown1']['BACKGROUND']
layout = [ [sg.Text('My Window')],
[sg.Button('test', image_data=sg.DEFAULT_BASE64_ICON, border_width=0, use_ttk_buttons=True, button_color=('black',background)),
sg.Button('Exit')] ]
PySimpleGUI 2019-12-01T21:00:50Z
Multiline
Element - Can Output Multicolored Text
Damned happy to say that this monkey is finally off my back!
The Multiline element can now be updated with text that has a text and background color of your choosing.
It was released to GitHub for both PySimpleGUI and PySimpleGUIQt. I expect to release a new release today to PyPI for PySimpleGUI so this change will likely make it into that release.
Here's a demo program that was also created and posted in the demo section to give you a jump start.
import PySimpleGUI as sg
# import PySimpleGUIQt as sg
"""
Demonstration of how to work with multiple colors when outputting text to a multiline element
"""
sg.change_look_and_feel('Dark Blue 3')
MLINE_KEY = '-MLINE-'+sg.WRITE_ONLY_KEY
layout = [ [sg.Text('Demonstration of Multiline Element\'s ability to show multiple colors ')],
[sg.Multiline(size=(60,20), key=MLINE_KEY)],
[sg.B('Plain'), sg.Button('Text Blue Line'), sg.Button('Text Green Line'),sg.Button('Background Blue Line'),sg.Button('Background Green Line'), sg.B('White on Green')
] ]
window = sg.Window('Demonstration of Multicolored Multline Text', layout)
while True:
event, values = window.read() # type: (str, dict)
print(event, values)
if event in (None, 'Exit'):
break
if 'Text Blue' in event:
window[MLINE_KEY].update('This is blue text', text_color_for_value='blue', append=True)
if 'Text Green' in event:
window[MLINE_KEY].update('This is green text', text_color_for_value='green', append=True)
if 'Background Blue' in event:
window[MLINE_KEY].update('This is Blue Background', background_color_for_value='blue', append=True)
if 'Background Green' in event:
window[MLINE_KEY].update('This is Green Backgroundt', background_color_for_value='green', append=True)
if 'White on Green' in event:
window[MLINE_KEY].update('This is white text on a green background', text_color_for_value='white', background_color_for_value='green', append=True)
if event == 'Plain':
window[MLINE_KEY].update('This is plain text with no extra coloring', append=True)
window.close()
PySimpleGUI 2019-12-03T00:38:37Z
Debug Print Goes Multi-Colored
Riding on the new capability of being able control the color of characters output in a Multiline
element, I've added the ability to control the output when you call Print
or EasyPrint
.
These are the calls that produce a debug window. You call Print
just like you would a normal print, but instead of outputting to your console, the characters are output to the "Debug Print Window".
The idea of a Debug Window came about so that instead of seeing your print statements being output on a console (that may be not visible or particularly ugly), they would be output to a window that you have a lot of control over. For example, it will match your application's look and feel settings.
There are a number or parameters to the Print calls and tonight 2 more were added - text_color
and background_color
.
Here's a Debug Print Window that's produced when you run PySimpleGUI without importing it, or you run PySimpleGUI.main()
.
What is being printed is the variable event
and values
. To make it easier to see the event
it is blue on a white background. This is achieved with 2 print statements because one has color and the other uses the default colors of the look and feel settings. Like normal print statements, this is done by setting the parameter end=''
in the call to Print
.
Here are those 2 prints.
Note that the colors will only be used when the Debug Window is created without setting the parameter to use re-routed stdout. The default is to not use re-routed stdout. In other words, the default is that colors will work.
PySimpleGUI 2019-12-03T01:04:03Z
Python in the Classroom
PySimpleGUI has always had Education as one of the major motivators and reasons for the project. Enabling kids to write GUIs sooner is the goal.
There was a Discord server set up recently for people interested in using Python for education named "Python in Education". If you want to join the fun, the server is here https://discord.gg/gKnKqZf
One of the ways I've been exploring how to go about getting further into the classroom was to order some books written about teaching Python to kids.
One of those books, Coding Project in Python, arrived today. I didn't know what to expect in the way GUIs. Wasn't sure if this book even covered them. I totally cracked up when I saw the cover.
It all looks normal, typical programming kind of words and symbols. Quick and easy to understand that it's got the basics covered. And then there's the statement in the upper left corner. It would appear that indeed GUIs are being taught. Of all things to choose to put on the cover, I'm not sure this would be the one I would have chosen to reach out and grab a kids attention. This should be interesting 😏
PySimpleGUI 2019-12-04T17:25:20Z
More from "Coding Projects in Python"
One of the fun games presented is a memory matching game using buttons. Because of the way button callbacks are specified, Lambda expressions needed to be explained. How kids are expected to learn Lambda beats me.
PySimpleGUI 2019-12-04T17:27:50Z
New ANSI Color output Demo Program
A new demo released
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Script_Launcher_ANSI_Color_Output.py
It will output the results of the script in color if ANSI color codes are returned.
There is a potential problem however. It seems like the popen
call strips out these codes. The parser code does work as strings with ANSI codes have been run through it and the multiline updates correctly with the right colors.
If you have trouble and are able to figure out a different call to make to run the script so that the ANSI codes are properly returned, please say something so the demo can be updated!
PySimpleGUI 2019-12-05T01:54:33Z
4.8.0 PySimpleGUI 4-Dec-2019
Multicolored multiline text! Often asked for feature going way back
ttk Buttons can have images
Print in color!
-
Multiline Element got 2 new parameters to the update method
-
text_color_for_value - color for the newly added text
-
background_color_for_value - background color of the newly added text
-
-
New Print/EasyPrint parameters and capability
-
text_color, background_color - control the text's color and background color when printing to "Debug Window"
-
Must be done only when used in mode where stdout is not re-routed (the default)
-
Wouldn't it be really nice if normal print calls had this parameter?
-
Print(event, text_color='green', background_color='white', end='')
-
-
ttk Buttons
-
can have images. No longer forces Buttons with images to be the old tk Butons. Now you can choose either
-
can update the button color
-
can update the button image
-
-
Set warning filter so that warnings are repeated
-
New global variables:
-
CURRENT_LOOK_AND_FEEL - The current look and feel setting in use. Starts out as "Default"
-
BROWSE_FILES_DELIMITER - Defaults to ";" It is the string placed between entries returned from a FilesBrowse button
-
TRANSPARENT_BUTTON - Depricated - was being used incorrectly as it was a relic from the early days. It's value was a color of gray
-
-
Window - gentle reminder if you don't choose a look and feel for your window. It's easy to stop them. Add a change_look_and_feel line
-
Test harness uses a debug window so don't be shocked when 2 windows appear when running PySimpleGUI by itself
-
Prints the "Event" in Green on White text
-
Prints the "values" normally
-
PySimpleGUI 2019-12-06T16:14:18Z
An impressive user application!
@JitsuP created a multi-window, multi-threaded application using PySimpleGUI. The GUI portion took 3 days in total. You can find all of the screens in the "User Screenshots" issue.
Here's a GIF of the main window where you can see both text output as well as a progress meter running that are fed by a thread. Coming from a complete newcomer to Python, this is an amazing creation!
PySimpleGUI 2019-12-07T04:03:31Z
Tab colors and visibility!
Cracking the ttk nut has resulted in the gift that keeps on giving. This time the winner is tabs.
While coloring of individual tabs isn't a possibility in PySimpleGUI at this point, tabs in a general way are! This is a huge improvement. The selected background color also works correctly.
Previously the only color that you could change was the tab text color and the color of the text for selected tabs.
These new changes add:
-
Tab background color
-
Selected tab background color
-
Tab visibility
-
Enable/Disable tabs (not sure if this was working correctly before)
Windows went from this
To this:
and this when making the tab visible
One thing I've noticed is that you cannot make the first tab start out as invisible. If you want that then you'll need to finalize the window first and then perform an update
to make it invisible.
It's possible to make all of the tabs invisible.
Because TabGroup does not have an update
method yet it's not possible to make the entire TabGroup invisible. I was surprised to see it missing. I guess no one else has noticed either.
These capabilities need to be cross-ported to PySimpleGUIQt as some parameters are new and it appears that because the main PySimpleGUI port didn't support the colors neither did the PySimpleGUIQt port.
I will be making one additional change which is to set the default tab background color to match the look and feel theme. Perhaps making them the same color as the buttons is a good default. I dunno yet but not-gray is a good guess as to what they will be, unless you're using the "default" look and feel. More thought needed....
For now, just really happy to be able to deliver this capability.
You can expect a rapid release to PyPI!
Here is the demo code that was posted to the Demo Programs and was used to make the screenshots above
#!/usr/bin/env python
import PySimpleGUI as sg
# Simple example of TabGroup element
sg.change_look_and_feel('Dark Brown 1')
tab1_layout = [[sg.Text('Tab 1')],
[sg.Text('Put your layout in here')],
[sg.Text('Input something'), sg.Input(size=(12,1), key='-IN0-')]]
tab2_layout = [[sg.Text('Tab 2')]]
tab3_layout = [[sg.Text('Tab 3')]]
tab_group_layout = [[sg.Tab('Tab 1', tab1_layout, key='-TAB1-'),
sg.Tab('Tab 2', tab2_layout, visible=False, key='-TAB2-'),
sg.Tab('Tab 3', tab3_layout, key='-TAB3-')]]
layout = [[sg.TabGroup(tab_group_layout,
selected_title_color='blue',
selected_background_color='red',
tab_background_color='green',
enable_events=True,
key='-TABGROUP-')],
[sg.Text('Make tab number'), sg.Input(key='-IN-', size=(3,1)), sg.Button('Invisible'), sg.Button('Visible')]]
window = sg.Window('My window with tabs', layout)
tab_keys = ('-TAB1-','-TAB2-','-TAB3-')
while True:
event, values = window.read() # type: str, dict
print(event, values)
if event is None:
break
if event == 'Invisible':
window[tab_keys[int(values['-IN-'])-1]].update(visible=False)
if event == 'Visible':
window[tab_keys[int(values['-IN-'])-1]].update(visible=True)
window.close()
PySimpleGUI 2019-12-07T15:12:49Z
New YouTube Video! It teaches PySimpleGUI rather than showing a project
Check out this new video by one of our long-time users.
https://www.youtube.com/watch?v=cLcfLm_GgiM
There have been a number of videos produced lately, but they's all been project focused, not focused solely on PySimpleGUI and how to use it.
It's an interesting blend and different than the series of videos made early on that go through each Element one by one.
It's really well produced!
PySimpleGUI 2019-12-07T18:54:12Z
More Tab Color Changes
Now that PySimpleGUI has the ability to set tab color and the text color, it's time to put it to use.
In the upcoming 4.9 release (already on GitHub as 4.8.0.6, the tab colors will be automatically set for you based on the current look and feel.
If you don't have any look and feel defined, you'll get the same gray window as always....
In release 4.8 if you set a look and feel, the tabs looked like this:
The text color was being set correctly, but it was the same for both selected and non-selected tabs.
In release 4.9, the same code look like this:
As far as "defaults" go, I think that's a pretty attractive window! Stuff matches really well.
4.9 is being shoved out the door ASAP today. Working on changes to the documentation still, but it should be finished soon.
PySimpleGUI 2019-12-08T00:31:07Z
4.9.0 PySimpleGUI 7-Dec-2019
The "Finally Nailed Tabs" release
-
Colors for Tabs!
-
When creating TabGroup can now specify
-
Text & Background color of all tabs
-
Text & Background color of selected tab
-
If nothing is specified then the Look and Feel theme will be used (which turned out GREAT)
-
-
Tab visibility - Can finally control individual tab's visibility using update and when creating
-
More "Look and Feel" Themes! There's no excuse to be grey again. There are now 126 themes to choose from
DefaultNoMoreNagging
DarkBlack1
DarkBlue12
DarkBlue13
DarkBlue14
DarkBlue15
DarkBlue16
DarkBlue17
DarkBrown5
DarkBrown6
DarkGreen2
DarkGreen3
DarkGreen4
DarkGreen5
DarkGreen6
DarkGrey4
DarkGrey5
DarkGrey6
DarkGrey7
DarkPurple6
DarkRed2
DarkTeal10
DarkTeal11
DarkTeal12
DarkTeal9
LightBlue6
LightBlue7
LightBrown12
LightBrown13
LightGray1
LightGreen10
LightGreen9
LightGrey6
-
preview_all_look_and_feel_themes now has a columns parameter to control number of entries per rows
- also made each theme display smaller due to large number of themes
Here are the new themes
The complete set that's in 4.9
PySimpleGUI 2019-12-08T15:18:59Z
PyDroid3 Revisited
Until I saw a post on Reddit about PyDroid3 the other day I had completely forgotten about PySimpleGUI's ability to run there. So, I gave it another try to see what's changed.
Either I didn't know it, or (more likely) forgot about it, but OpenCV runs on PyDroid3 too. This meant that the Demo Programs that use OpenCV should also run. And, run they did!
I made a new folder under the Demo Programs to put the demos that have been modified for PyDroid3. Generally speaking you need to make 2 changes.
-
add
import tkinter
to the top of the demo to tell PyDroid3 your app has a GUI -
add
location=(0,0)
to yourWindow
creation so the window is visible. The auto-centering doesn't seem to do the right thing.
For the OpenCV Demos, if you want the forward facing camera, change the camera to 1 instead of 0.
It helps to enlarge your controls too. Sizes meant for a mouse don't work so well with fingers. They work, but are a little too small for my fingers. Changing the font or the size of elements the layout took care of that.
Was able to simply Pip install PySimpleGUI and it picked up the 4.9 release. Awesome stuff if you want to run your code on your phone!
PySimpleGUI 2019-12-08T22:46:59Z
PyDroid3 + OpenCV + PySimpleGUI = FUN!
Posted more information, a GIF, images, instructions for installation, in this Reddit post
https://www.reddit.com/r/Python/comments/e80m8z/run_opencv_pysimplegui_programs_on_your_phone/
The PyDroid3 folks are to be commended for this rather significant achievement of getting OpenCV running. It's easy to then lay PySimpleGUI on top of that work and end up with a very nice little Android application that uses your phone's cameras.
PySimpleGUI 2019-12-09T22:14:53Z
4.10.0 PySimpleGUI 9-Dec-2019
"Oh crap the debugger is broken!" + "Pretty Progress Bars" release
-
Fix for built-in debugger not working
-
Important due to upcoming educational usage
-
Has been broken since 4.5.0 when a change to Finalize was made
-
-
ProgessBar element colors set using Look and Feel colors
- Combination of button color, input element, and input element text are used
I'm taking a chance here and made a sizable change to the Progress Bar color scheme. The always-green color wasn't making sense when all other elements, now including tabs, were being colored based on the Look and Feel Theme. So, now you'll find Progress Bars match the rest of your window.
The formula is that it uses the button's background with the input area's color.... unless the the background color for the window matches the button background in which case it'll use the input element's text color. After looking at 40+ random themes, they all looked great to me so I'm letting it go. If you don't like the colors, you can always set it back to the original color which can be found in the variable:
DEFAULT_PROGRESS_BAR_COLOR_OFFICIAL
The release was uploaded to PyPI and GitHub and the documentation was updated as well. There was additional documentation added for the TTK themes, ttk buttons, running on Android, ...
PySimpleGUI 2019-12-10T01:22:45Z
A 24/7 Operation
It's one thing to work on a project constantly, it's another to see other people using it constantly.
I find it amazing to see SO much activity when I check out the different places PySimpleGUI information is posted. Any time of day that I check, someone's recently been doing something with it.
On Trinket it seems like there's always someone discovering PySimpleGUI and going through all of the applications and trying them. Every time I check, someone's run something within the past hour.
I've never done videos on YouTube before, so that's a new experience too. When I checked out the stats there, I was shocked to see so many people watching what I think of as "old, crappy" videos because they were made so long ago and I didn't / don't know how to make a decent video. Regardless, people are watching the damned things and I guess learning as I don't get a ton of simple questions posted here.
It's really rewarding to see that lots of people are now able to create and run GUIs in Python. While there are still a good number of people that dislike PySimpleGUI and can't seem to get on board with it being an alternative architecture, there are even more that do see the value and want to use it. The question of whether or not there's a "there there" is being answered by all these fine users.
JitsuP 2019-12-10T15:07:15Z We Thank you for your Handwork Mike.
I never thought it would of been this simple to make something that we see every day in our life and wondered How the hell they did it. And now we all can do it.
Other than finding bugs and sharing our problems , let us know if we could help any other.
I will make video or gif once I am done my project.
PySimpleGUI 2019-12-10T21:23:09Z
4.11.0 PySimpleGUI 10-Dec-2019
The Element & Window bindings release
-
Element.bind - New method of all Elements
-
Enables tkinter bindings to be added to any element
-
Will get an event returned from window.read() if the tkinter event happens
-
-
Window.bind - New method for Windows, just like Elements
-
Enables tkinter bindings to be added to Windows
-
Will get an event returned from window.read() if the tkinter event happens
-
-
TabGroup fonts - can now set the font and font size for Tab text
Well, sorry about the daily PyPI releases. It's almost the old days where new features ship daily/weekly. There have been some cool things recently is all and they're needed immediately by some applications.
One such application is this Minesweeper game that I stole and quickly reworked to use this new bind. They were getting direct tkinter callbacks.
Here's the original article in Japanese
https://learnku.com/articles/37714
And here is the adapted for release 4.11.0 code running on Trinket
https://pysimplegui.trinket.io/sites/minesweeper
Trinket has tiny number of pixels so it looks huge.
I'll post a Demo Programs version that looks a lot better. Here's what it looks like running on Windows:
There are a number of you that are asking for features that this will help. A recent one was wanting a popup keyboard to show up when an input field receives focus. You could poll for it, but by binding the event you don't need to poll (no timeout on window.read()
)
Enjoy!
PySimpleGUI 2019-12-11T15:53:44Z
"Towards Data Science" article on Medium
Stumbled onto this article that's posted on Medium. I'm not a Medium subscriber (yet) and am not sure how it all works in terms of segmenting into specific fields.
https://towardsdatascience.com/learn-how-to-quickly-create-uis-in-python-a97ae1394d5
What I found mind-blowing is that this is not the first article written by Costas Andreou, the author, but it's his most popular by a long ways.
This article was posted on Dec 6, five days ago. His second most popular Data Science article was posted on July. He's posted 7 articles in the Data Science section and I am measuring "popular" by looking at the "claps" statistic that is posted by Medium with the article.
89 claps for his July 2019 article.
1,505 claps for the PySimpleGUI article
It's nice when someone discovers the purpose and the reason behind PySimpleGUI.
He summarized the reason PySimpleGUI was written in these 3 statements:
There are essentially 3 big Python UI libraries; Tkinter, wxPython and PyQT. While reviewing all three, I realized that everything that I liked about Python was nowhere to be found in using these libraries. Python libraries, in general, make a very good job of abstracting away the super technical. If I needed to work with Object Oriented Programming, I might as well have loaded up Java or .Net.
To the point....
everything that I liked about Python was nowhere to be found
I've been searching for the words to describe this difference between almost all other areas that Python covers and GUIs. It's the "get things done in 2 or 3 lines and be done" experience. Want threads, socket communication, queues, semaphores as a first month beginner? It's no problem with Python and in fact simple.
The responses written to the article are statistically similar to responses to posts about PySimpleGUI on Reddit....
1 thanking the author for introducing him to an easy way to write GUIs
4 responses recommending other packages or websites.
Loved the "You need to look at Kivy" response as that's all it said.
When it comes to GUIs, people seem to head to the corner belonging to what they know and only what they know. If someone doesn't know any GUI package, then PySimpleGUI has a higher chance of being considered.
I'm glad the author took a look at the other packages first and mentioned this
PySimpleGUI 2019-12-13T00:54:25Z
Mac Users - It's Child's Play to Move top Python.org Releases
A new Python for Kids book arrived this week.
I have already been surprised by a few things in the book...
One is that it's SO NEW! The install instructions show downloading version 3.7.
The other surprising thing was the instructions shown for the Mac
I saw no mention of "Homebrew" anywhere.
My takeaway is that if it's good enough for kids then it's likely good enough for you too.
I have heard only good stories so far from the users here that have installed non-Homebrew versions. No nightmares, no disasters so far to report.
I wish I had heard about this capability prior to the rush to get the ttk buttons done. Then again, there wouldn't be all the great coloring of tabs and stuff now if I didn't do the ttk buttons, so maybe it's just as well.
PySimpleGUI 2019-12-13T01:17:26Z
Google Trends... the little GUI that could....
Qt's PySide2 and PySimpleGUI launched in the same month, July 2018.
Qt of course has instant name recognition and plenty of searches for PySide2 were happening in July 2018.
Over time PySimpleGUI has been getting more and more Google search hits. It's to the point now that they're tied.
PySimpleGUI 2019-12-13T02:33:06Z
A PySimpleGUI IDE
I've been working with teachers a lot lately. One thing that's come up is their use of Adafruit's "Circuit Playground Express" boards.
These are little embedded systems boards that run Circuit Python.
You connect via a serial port to do I/O. It looks like a flash drive to windows.
As a result, I was able to take the Text Editor application that was written by Israel Dryer and adapt it to become an IDE. It's crazy that it's already working after maybe 30 minutes of working on it.
As you can see, there's a sliding pane at the bottom that is showing the serial communications. The code that is running on the board is shown in the editor. I can modify that code, save it and the board will auto-reboot and start running the code. It makes for instant turnaround of code changes.
Next up is an "auto-plotter" feature. The Mu Editor has one of these. The concept is that in your embedded program you print out tuples of data (1,2 3) and it will plot these on a line graph over time. For each item in the tuple is another line. I can output to Matplotlib plots for example or use the PySimpleGUI drawing primitives to do it. LOTS of options available.
The nice thing about this is that it's 150 lines of PySimpleGUI code. That's it. So anyone that wants a new feature in the IDE can simply make a change to the source code and run it. No need to make a change to the Mu editor which I'm sure is a big deal to do.
PySimpleGUI 2019-12-13T21:38:32Z
Reddit needs this added to their website's design
The site learnku.com where I located the amazing Minesweeper code, has a box at the bottom of the page to enter comments. I realize that the translation may be choosing words that aren't exactly correct, but I like the ones they chose.
Reddit could learn a thing or two....
PySimpleGUI 2019-12-14T20:26:17Z
Disabled Button Colors
The 4.11.0.5 release on GitHub has an extra feature added to it that was logged long ago. I may have logged it. It's been a long time.
Button
and Button.update
have a new parameter disabled_button_color
.
Here's the definition from the Button
DocString
:param disabled_button_color: Tuple[str, str] colors to use when button is disabled (text, background). Use None for a color if don't want to change. Only ttk buttons support both text and background colors. tk buttons only support changing text color
It takes a tuple, just like button color is a tuple. (text, background).
If you don't want to change one of them, then set the value to None
(a very rare instance where None is OK in a PySimpleGUI tuple).
This will change your button's color when it is set to disabled.
As you can see from the DocString, only ttk buttons support changing both colors. Normal, Tk Buttons, only support changing the text color.
Enjoy!
PySimpleGUI 2019-12-15T02:09:38Z
imwatchingyou
Release 2.3.0 14-Dec-2019
-
Addition of location parameter to popout window
-
Addition of location parameter to main debugger window
-
Added version number string
-
Changed the REPL to be a single line
-
Looks and acts like the built-in debugger inside PySimpleGUI
PySimpleGUI 2019-12-15T04:37:41Z
4.12.0 PySimpleGUI 14-Dec-2019
Finally no more outlines around TK Elements on Linux
-
Fixed a long-term problem of the mysterious white border around (almost) all TK Elements on Linux
-
Ability to set the disabled button colors
-
New Button and Button.update parameter - disabled_button_color
-
Specified as (Text Color, Background Color) just like button colors
-
For Normal / TK Buttons - can set button text color only
-
For TTK Buttons - can set both a disabled button and text color
-
Either parameter can be None to use current setting
-
-
Removed use of CloseButton from Popups (still have a bug in the CloseButton code but not in popups now)
-
Combobox - removed requirement of setting disabled if want to set to readonly using update method
-
Fix for cancelling out of file/folder browse on Linux caused target to be cleared instead of just cancelling
-
Removed try block around setting button colors - if user sets a bad color, well don't do that
-
Now deleting windows after closing them for popup
PySimpleGUI 2019-12-15T21:33:43Z
Code Completion Tip
If you're a PyCharm user (and perhaps a VS user too), then I'm sure you enjoy using code completion. You might have noticed in either a demo program or in the PySimpleGUI.py file itself that type hints are done via comments. This was done for potability reasons as the code was used to make the 2.7 version PySimpleGUI as well as PySimpleGUI running on 3.5.
A good example of wanting code completion but not being able to use it is in something like a Graph
Element. There are a number of drawing primitives for a Graph
Element and they have docstrings for them too.
Let's say you've got a Graph Element in your layout and you want to draw a couple of axis lines prior to the window.read
call.
window = sg.Window('Canvas test', layout, grab_anywhere=True,
background_color='black', no_titlebar=False,
use_default_focus=False, finalize=True)
graph = window['graph']
graph.draw_line((SAMPLES//2, 0), (SAMPLES//2,SAMPLE_MAX),color='white')
graph.draw_line((0,SAMPLE_MAX//2), (SAMPLES, SAMPLE_MAX//2),color='white')
This code first gets the graph element by looking up with a key and then storing the result in the variable graph
. When it comes time to add the draw_line
onto the graph
variable, you will not see the different primitives available because Python/PyCharm doesn't know what type graph
is.
Adding a type is as easy as adding a comment. In this case, to tell PyCharm that graph
is a Graph
Element, add a comment onto the assignment:
Now PyCharm knows that the graph
variable is a Graph
object and code completion will work!
You'l find places in the PySimpleGUI.py code where a variable is assigned to itself.
This is done so that I can add the type hint as a comment. These statements usually look more like:
The Element.Widget
variable always (should always) has a type hint on it so that when you're trying to use it in your code, the correct code completion will take place. For a Text
Element in tktinter, this is how Widget
is defined in the class definition
Now in your code when you reference the Element.Widget
variable for a Text
Element, you'll see the type hints for the tkinter Label
widget.
I'm sure there are many more ways of using these type hint comments than what I'm doing. If you know more ways that would be helpful, post them! Open an Issue with a type [Helpful Hints] or something like that.
PySimpleGUI 2019-12-15T22:43:07Z
Posted @jason990420 's Minesweeper and Solitaire Games on Reddit today!
https://www.reddit.com/r/Python/comments/eb5dbj/solitaire_and_minesweeper_fun_and_games_with/
Maybe it'll get more people building fun stuff like these. Then again, it's Reddit, so more likely to get boos then anything else 🤔
PySimpleGUI 2019-12-16T17:28:17Z
PySimpleGUIQt's Buttons are now 3D
I know that's a weird kinda thing to announce. 3D buttons. Aren't they ALL 3D? Well, not in PySimpleGUIQt evidently. I didn't even notice until someone posted on Reddit and then an Issue here 12 days ago.
As suspected it was a Style Sheet problem. Sheet man! Bitten again and again.
I'm still trying to get the "Default" case to work.
If you use a call to change_look_and_feel
then it looks good.
Here's the "Dark Red" theme showing 1 button menu and 2 buttons. I depressed one of the buttons to show that it animates to 3D.
I'll keep looking to try and see why the default settings aren't working. The Style Sheet for the button looks identical to when I'm using a look and feel theme so puzzled what's being set that's outside of the button.
PySimpleGUI 2019-12-16T18:51:52Z
Must Change the "Default Button Color" on Qt.
If the default "PySimpleGUI White on Blue" button is used, then the animation for the button is lost when using PySimpleGUIQt.
If you watch how Qt animates buttons, the TEXT of the button stays still. It's only the surrounding rectangle that changes. In the case of a dark blue button, you can't see the animation that Qt is trying to draw. It's there and it's drawing the animation, but it's black on dark blue and cannot be detected using your eyes.
The result is that a NEW button color is needed for PySimpleGUI when no colors are selected. There is a "Default" that has no colors at all, but that setting makes flat buttons. I'm modifying the "Default1" Look and Feel to use my own gray button which does show up as 3D
Here's what it will look like now with "Default1" the supposed "System Settings"
Here's what it looks like if nothing is set, the old "Default1" setting
It does do an interesting highlight of light blue when you mouse over, but there's no animation. I'll look into the highlighting too.
The plan is for now to use these gray buttons and to find a new "Default PySimpleGUI Button" color that is not gray.
Some may not like the Dark Blue button that you get now. I'm not sure as people don't complain. It helps "watermark" applications that are built using PySimpleGUI. One look at a window with this specific color of blue button ("#082567") and white text and you know it's a PySimpleGUI window.
The icon is a bit of a giveaway too :-) It's another one that most people don't notice. I think many/most think it's a Python icon on the windows.
PySimpleGUI 2019-12-17T00:11:43Z
An "Official PySimpleGUI Color Theme"
What would you choose? It's getting to be time, at least for Qt and likely the others, to choose an entire look and feel theme for all PySimpleGUI windows.
I would just as soon replace the "Nag" message in the Window
call with a default look and feel.
Over the past few weeks "Dark Blue 3" has been winning in all of the new posts I've made.
Here's how the "Everything Bagel" looks using that color theme
And here are the 108 currently available themes
PySimpleGUI 2019-12-18T19:41:02Z
PySimpleGUI Charting Era Has Arrived
There were a couple of key drawing primitives that were holding back PySimpleGUI from being able to drag things around on a Graph. You could move them manually but there was no easy way to grab them with your mouse.
There is also a demo program posted that was used to create the GIF:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Graph_Drawing_And_Dragging_Figures.py
Now real drawing or flow charting kinds of applications can be made.
The features are starting to pile up again so might to a PyPI release soon.
PySimpleGUI 2019-12-19T03:20:57Z
4.13.0 PySimpleGUI 18-Dec-2019
Table and Tree header colors, expanded Graph methods
-
Element.expand new parameter - expand_row. If true then row will expand along with the widgets. Provides better resizing control
-
Using math.floor now instead of an int cast in Graph Element's unit conversions
-
Graph.draw_point - now using caller's graph units for specifying point size
-
Graph.draw_circle - converted radius size from user's graph units.
-
Graph.draw_circle - added line_width parameter
-
Graph.draw_oval - added line_width parameter
-
Graph.get_figures_at_location - new method for getting a list of figures at a particular point
-
Graph.get_bounding_box - returns bounding box for a previously drawn figure
-
Table and Tree Elements
-
3 new element creation parameters
-
header_text_color - color of the text for the column headings
-
header_background_color - color of the background of column headings
-
header_font - font family, style , size for the column headings
-
-
Defaults to using the current look and feel setting
- Uses similar algorithm as Tabs - Input Text background and text colors are used
-
-
Spin element - fixed bug that showed "None" if default value is "None"
-
Test Harness sets incorrect look and feel on purpose so a random one is chosen
PySimpleGUI 2019-12-19T15:32:59Z
New Names Coming For "Look and Feel"
PySimpleGUI has gone through a number of "name changes". From FlexForm to Window, Read to read, there has always been an evolution underway to make the APIs clearer and easier to use. More SIMPLE.
Look and Feel is becoming simply "Theme".
Just as other name changes, this is an addition, not a replacement. Your old code that calls change_look_and_feel will keep working without problem, just as calling your window a FlexForm continues to work for those ancient applications.
The risk is in confusing ttk themes with PySimpleGUI themes, but I don't think it's a very big risk as the newest ttk parameters that use theme are called ttk_theme for this very reason.
The new functions being added are:
set_theme()
get_theme()
I'm still pondering how to provide access to individual theme settings such as the background color. At the moment, using the new settings you would need to use this expression to print the current background color
Not a good long-term, Simple interface.
Perhaps something like:
theme_background_color()
This convention, a function starting with theme_
, could be extended to all of the various theme settings. theme_text_color()
, theme_input_text_color()
, theme_input_background_color()
These color themes are climbing in popularity with a number of user programs allowing the user to set their own window theme that is saved in a settings file and used for all future runs of the program.
However, changes to Themes necessitate changes to all of the PySimpleGUI ports simultaneously, so it's a big decision when a change is made like this one.
PySimpleGUI 2019-12-22T13:13:42Z
Themes - New calls, New default
The previous post is a little off from what's been changed and checked in.
Where 2 functions were discussed about there is only one now:
theme()
There are 2 ways to call. To set a theme, call with the theme name.
To get the current theme, call with no parameter
The other calls all start with theme_
so that they'll be easy to search for in the documentation.
These will all be PEP8 compliant calls. No SnakeCase for themes.
New Default Theme == "Dark Blue 3"
I've decided to move forward with Dark Blue 3 being the default theme for all platforms. It's a white text on a blue-gray background. My hope is that the trend I see for darker UIs these days will match this new default. However, it's no so dark as to appear super dark overall. It's just dark enough that white text works better than light.
The input fields remain a light color with black text.
It would be nice to have a "Light" colored default chosen at the ready in case of a user revolt. Anything but gray is my choice in general.
Here's the all-widgets demo
And a popup window
This is what the old default looked like on Windows
PySimpleGUI 2019-12-23T01:49:57Z
Lightened the Repo Load....
I forgot that there were movies uploaded with the YOLO machine learning example code. The result was the PySimpleGUI project ZIP was large and the majority of it was those stupid movies! DOH!
It's been moved over to another repo - https://github.com/PySimpleGUI/PySimpleGUI-YOLO
The zip went from 89 MB to 14 MB. -sigh- I'm sorry people... I didn't know it was so large.
14 MB is much better, especially when you consider that is all of the ports and all of the demo programs combined.
PySimpleGUI 2019-12-23T14:38:04Z
4.14.0 PySimpleGUI 23-Dec-2019
THEMES!
-
theme is replacing change_look_and_feel. The old calls will still be usable however
-
LOTS of new theme functions. Search for "theme_" to find them in this documentation. There's a section discussing themes too
-
"Dark Blue 3" is the default theme now. All windows will be colored using this theme unless the user sets another one
-
Removed the code that forced Macs to use gray
-
New element.set_cursor - can now set a cursor for any of the elements. Pass in a cursor string and cursor will appear when mouse over widget
-
Combo - enable setting to any value, not just those in the list
-
Combo - changed how initial value is set
-
Can change the font on tabs by setting font parameter in TabGroup
-
Table heading font now defaults correctly
-
Tree heading font now defaults correctly
-
Renamed DebugWin to _DebugWin to discourage use
PySimpleGUI 2019-12-23T14:39:47Z
The New Theme Calls
This is the list of new functions that are used to set, modify, and get information about themes that were just released in 4.14.0
To set the theme, instead of calling change_look_and_feel
you now simply call theme
There are a number of other functions to get and set various theme colors and other settings.
theme_background_color
theme_border_width
theme_button_color
theme_element_background_color
theme_element_text_color
theme_input_background_color
theme_input_text_color
theme_progress_bar_border_width
theme_progress_bar_color
theme_slider_border_width
theme_slider_color
theme_text_color
These will help you get a list of available choices.
PySimpleGUI 2019-12-23T15:33:34Z
PyIDM
I would like to spotlight this amazing project.
https://github.com/pyIDM/pyIDM
Here's the project owner's description:
Alternative to IDM (Internet Download Manager):
The main reason for making this application is the lack of free open source download managers which has multi-connection, high download speed, and resume capability, also can download youtube videos, in same time has a good gui design, to achieve that, decision made to use the high speed library 'pycurl', a threading module for multi-connection, youtube_dl, and an easy and beautiful PySimpleGUI module for designing the gui user interface
It's a Python version of the popular "Internet Download Manager". It has a ton of functionality!
A lot of parallel processing is going on. He also used UNICODE characters in a clever way to show arrows, turning text into graphics in the process.
This is a great example of the enabling technology that PySimpleGUI contains. Programmers that didn't feel comfortable creating GUIs using the other frameworks are finding a nice home with PySimpleGUI. Because it makes the GUI stuff easy, more time can be spent on polishing it and working on functionality.
PySimpleGUI 2019-12-23T18:57:50Z
PySimpleGUI Debugger in Your Browser!
This is just plain crazy.
You're all aware of Trinket by now, the site where you are able to run PySimpleGUI code in your browser. Make no mistake, the code is running in your browser, not a backend server somewhere.
I was astonished when I pressed the BREAK key and was able to pull up both the debugger popout window and the main debugger window. Both ran as they should. I was able to interact while the program was running in the background.
PySimpleGUI 2019-12-24T17:57:18Z
0.31.0 PySimpleGUIQt 24-Dec-2019
Themes and more!
-
Added port string so can identify which port is being used (PySimpleGUIQt)
-
Removed the Mac speific button and system color settings. Not sure why they existed at all since it's Qt, not tkinter
-
Like all PySimpleGUI ports, the default theme is now "DarkBlue3"
-
TRANSPARENT_BUTTON redefined as an a string explaining that if you're using it, you're not getting what you thought you were
-
BROWSE_FILES_DELIMETER so that it can be changed to something other than ';' for systems that ';' is a valid char for filenames
-
Can drag and drop into a Multiline Input Element!
-
Colored text output for Multiline (hmmm...but not MultilineOutput.. may have to add it)
-
Tree Element
-
Support for enable_events
-
Returns selected rows when reading
-
-
Window - better error checking and warnings for window layouts
-
Button - changes to help with getting animations back
-
TabGroup - Tab positions now supporrted
- left, right, top, bottom, lefttop, leftbottom, righttop, rightbottom, bottomleft, bottomright, topleft, topright
-
Tables & Trees - text color and background color now work. Don't appear to have worked before
I know it SEEMS like nothing happens with the PySimpleGUIQt port, but there is new things added more frequently than you might realize.
This release, while focused on getting the "themes" APIs all consistent across all the ports, there are a number of good sized features include.d
PySimpleGUI 2019-12-24T20:10:12Z
0.34.0 PySimpleGUIWeb 24-Dec-2019
Theses +
-
New theme apis that replace the change_look_and_feel call (see primary PySimpleGUI port for more info)
-
New default theme is Dark Blue 3
-
Added ported string so can tell this is the "PySimpleGUIWeb" port
-
Removed platform specific code that was barring Macs from using colors, even for the web
-
Changed "TRANSPARENT_BUTTON" string to invalidate it. It was misunderstood and should not bave been inlucded in anything
-
Ability to change the files delimeter for browse files to filenames can have ; in them
PySimpleGUI 2019-12-24T22:18:45Z
Saving Elements As An Image
I've uploaded a couple of sample programs that have a function that will enable you to save the contents of the element as an image file in PNG, JPG, or GIF format (perhaps others too).
The 2 demos are:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Graph_Drawing_And_Dragging_Figures.py
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Save_Window_As_Image.py
They both contain this function that makes it all possible.
First be sure and import from PIL the function that will be doing the saving:
Then use this function to save the element as an image file. If you want to save an entire window's contents, then you'll want to place your layout into a single Column element and then save that column element.
It's SUPER SIMPLE and easy to do!
def save_element_as_file(element, filename):
"""
Saves any element as an image file. Element needs to have an underlyiong Widget available (almost if not all of them do)
:param element: The element to save
:param filename: The filename to save to. The extension of the filename determines the format (jpg, png, gif, ?)
"""
widget = element.Widget
box = (widget.winfo_rootx(), widget.winfo_rooty(), widget.winfo_rootx() + widget.winfo_width(), widget.winfo_rooty() + widget.winfo_height())
grab = ImageGrab.grab(bbox=box)
grab.save(filename)
PySimpleGUI 2019-12-24T22:37:28Z
0.15.0 PySimpleGUIWx 24-Dec-2019
Themes!
-
Picked up the new "theme" APIs like all 4 ports got
-
Dark Blue 3 is the new official color theme for PySimpleGUI
-
Added "port" string so that your code can detect which port of PySimpleGUI is being executed
-
Removed restriction on Macs (totally didn't make sense that it was there as it blocked a tkinter problem, not a Wx one)
-
Depricated the TRANSPARENT_BUTTON variable as it was being misunderstood by users and was misleading
-
BROWSE_FILES_DELIMITER can be changed to change the default ';' delimeter between filenames in FilesBrowse button
-
Frame Element! BUT, it's only a partial solution as I am unable to set the background color (need to understand how panels work). It's better than nothing
PySimpleGUI 2019-12-24T22:45:27Z
Merry Christmas & Happy Holidays to Everyone... Everywhere...
Well, all 4 ports received their updates in the past 24 hours, so they're all up to date with the big "theme" API changes. They each got some new features in the process too.
Next step is to re-release all of the Demos with the new theme use as well as showcasing some of the more recent additions.
There needs to be more cross-porting from tk to Qt in the near future as some of the color changes need to be expanded there.
I want to take a moment and thank all of the PySimpleGUI users. 🙏 Everyone has been really supportive and helpful over the past 17 months. So many of you have been around from the start and the newcomers are nice too. I get private messages and emails that have been really helpful and very encouraging. It helps keep those releases rolling out knowing PySimpleGUI is making a difference.
I really appreciate the patience in taking the time to fill out the form, check through the materials to try and help yourself. It seems to be working out well for everyone in the end. There are not a lot of questions posted elsewhere so it's enabled prioritization as well as enabling you folks to help each other, which has happened on a number of occasions.
It's an exciting year ahead for PySimpleGUI. 😃
PySimpleGUI 2019-12-26T17:25:34Z
No ''
Required
A while back the Text
and Button
elements got a sneaky little addition. Most people don't take advantage of it. For these elements you do not need to enter any text if the text is blank.
If you have an output only element then you can write it:
No text value of ''
required. The same goes with Buttons
InputText
/ Input
elements have always had the default text set to ''
so that you don't need to specify it there either. Just use:
Shortcuts
Since we're talking about shrinking code. There are some very short shortcuts to remember. T
is Text
, B
is Button
, I
is Input
, R
is for Radio
. The Combo
can be specified as a DropDown
or DD
for short. ListBox
is of course LB
.
Skipping .update
And for the super lazy, you can drop the word .update
when updating elements. To update the Text
element I defined earlier, I can write:
I've seen a few people do this, so if you're reading someone else's code and see that weird construct, that's what's happening... an update
is being called.
Not recommended but possible is to drop the .read
from window
calls. This is a valid construct which calls window.read()
.
PySimpleGUI 2019-12-27T03:17:59Z
Photo Colorization With PySimpleGUI
Putting the final touches on a new Demo Program.
This time it's a photo colorizer. You can use images or even your webcam for a colorized video.
Check out what it did with this Ansel Adams photo!
It's using a combination of OpenCV and numpy to implement a colorization technique created by Richard Zhang et al that's described here:
http://richzhang.github.io/colorization/
I would like to add a couple more features like saving to disk before releasing it.
The amazing thing, as usual with Python and PySimpleGUI, is that the code required was 60 lines of actual code. That's all.... wow.... what an amazing language.
PySimpleGUI 2019-12-27T19:05:13Z
Colorizer Completed And Posted
Wow what a fun little project this ended up being. I was able to make the controls super responsive. As soon as you take an action, something happens. Past a folder path into the input above the listbox and it immediately populates the list. Click an item in the list and it's immediately previewed.
Loads of features like the ability to save the resulting image to a JPG, PNG, GIF, etc.
Posted about it on Reddit
https://www.reddit.com/r/Python/comments/ege02j/a_photo_and_webcam_deep_learning_colorizer_in/
And created a separate project for it on GitHub
https://github.com/PySimpleGUI/PySimpleGUI-Photo-Colorizer
It's SUPER easy to get up and running and it's some amazing AI technology at work.
It's been tested on Windows, Linux and a Mac and is working great.
PySimpleGUI 2019-12-29T16:46:00Z
Help PyIDM Get Found...
A while back a lot of kind PySimpleGUI users "voted" to have PySimpleGUI listed in the Vinta Awesome Python Applications. It's seen by a lot of people and it really helps projects that get listed.
They have a voting system to help determine what gets included.
I've been actively using this PyIDM software to do large downloads and it's amazing. It a multi-threaded bit of magic. And it's worthy of being found and used by other people
Python needs more actual applications that get used by end users. Here's an opportunity to have one get noticed.
To vote, go to this link:
https://github.com/vinta/awesome-python/pull/1450
And click to add a 👍 emoji
Here is a detailed bit of instructions.
PySimpleGUI 2020-01-01T14:28:03Z
Bye Bye PySimpleGUI27
As promised, the 2.7 version of PySimpleGUI is no longer hosted here.
I want to thank the 114,000 pip installs out there.
Unfortunately there have been over 5,000 pip installs of PySimpleGUI27 in the past month.
I'm trying to determine what to do about PyPI. I really hate to blow up all those installs by deleting all of the releases but I think that's likely the best course of action. Security experts claim that continuing to support 2.7 is basically supporting opening people up to security issues.
PySimpleGUI 2020-01-02T19:22:36Z
Demo - PyLab
I didn't know that Matplotlib had multiple sub-packages beyond PyPlot. Today I learned about PyLab
https://www.tutorialspoint.com/matplotlib/matplotlib_pylab_module.htm
Someone asked about embedding PyLab plots so I made a separate demo to show how to embed these plots in the same way that Matplotlib plots are embedded. The technique used for PyLab and Matplotlib are identical.
Here's the demo program
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Matplotlib_PyLab.py
The actual plotting code I copied from the tutorial page and it looks like this:
import pylab
from numpy import sin
from numpy import cos
x = pylab.linspace(-3, 3, 30)
y = x**2
pylab.plot(x, sin(x))
pylab.plot(x, cos(x), 'r-')
pylab.plot(x, -sin(x), 'g--')
The result is this window.
PySimpleGUI 2020-01-02T19:30:13Z
Demo Reddit Searcher
Recently learned about Reddit's APIs. I hadn't paid much attention to them in the past. In the spirit of helping users integrate different technologies with PySimpleGUI I decided to make a little search program that will search for a string in Reddit posts and comments.
It will show you the results in a browser as well.
PySimpleGUI 2020-01-03T23:38:57Z
Corporate Users
If you're a corporate user, I would like to hear from you. PySimpleGUI is LGPL3 licensed, so you're allowed to use it for your corporate products as long as your publish any changes you make to the code. Please email [email protected] if you're a corporate user. I hope you're finding a lot of success using PySimpleGUI if you're using it at work. It's meant to be used for both personal and corporate projects.
PySimpleGUI 2020-01-04T01:50:08Z
"Dynamic Layouts" Window.extend_layout
has arrived
Hopefully this new capability is simple enough to be understood and at the same time has enough depth to be useful.
A new Window
method was just added. extend_layout
will add a layout onto the end of any PySimpleGUI container element or window. It only takes 2 parameters
def extend_layout(self, container, rows):
"""
Adds new rows to an existing container element inside of this window
:param container: (Union[Frame, Column, Tab]) - The container Element the layout will be placed inside of
:param rows: (List[List[Element]]) - The layout to be added
:return: (Window) self so could be chained
"""
The first parameter is container
. This is a container element or a window object. Containers are Columns, Frames and Tabs. Additionally you can pass in the window itself as the container and the layout will be added to the end of the window.
The second parameter is rows
and is your layout that you wish to add.
If you want to be able to add elements to some location in your window in the future, then create a Column or other container at that location in your window. Then when you're ready to add more to it, pass in that container/window and the list of rows of elements.
This program demonstrates how to use the call
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Text('Click to add a row inside the frame'), sg.B('+')],
[sg.Frame('Frame',[[sg.T('Frame')]], key='-COL1-')],
[sg.Input(key='-IN-'), sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Button'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
i = 0
while True: # Event Loop
event, values = window.read()
print(event, values)
if event in (None, 'Exit'):
break
if event == '+':
window.extend_layout(window['-COL1-'], [[sg.T('A New Input Line'), sg.I(key=f'-IN-{i}-')]])
i += 1
window.close()
Will be adding to the docs soon too.
PySimpleGUI 2020-01-04T02:04:00Z
Window.extend_layout
Example 2
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Text('Click to add a row inside the frame'), sg.B('+', key='-B1-')],
[sg.Text('Click to add a row inside the Window'), sg.B('+', key='-B2-')],
[sg.Frame('Frame',[[sg.T('Frame')]], key='-COL1-')],
[sg.Input(key='-IN-'), sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Button'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
i = 0
while True: # Event Loop
event, values = window.read()
print(event, values)
if event in (None, 'Exit'):
break
if event == '-B1-':
window.extend_layout(window['-COL1-'], [[sg.T('A New Input Line'), sg.I(key=f'-IN-{i}-')]])
i += 1
if event == '-B2-':
window.extend_layout(window, [[sg.T('A New Input Line'), sg.I(key=f'-IN-{i}-')]])
i += 1
window.close()
PySimpleGUI 2020-01-08T01:46:03Z
Demo Repositories
Experimenting with posting demos as repos.
The colorization project has been pretty popular and it got me thinking that some of these simple demos are actually interesting by themselves.
I created one for the rainmeter style CPU core monitor.
Posting it by itself offers the opportunity to include a bit more information along with the code.
https://github.com/PySimpleGUI/PySimpleGUI-Rainmeter-CPU-Cores
jason990420 2020-01-09T03:13:05Z Maybe you forgot to set Text size, (10, 1) ?, so graphs[i].text_display('{} CPU {:2.0f}'.format(i, util)) just display first one or two chars and no usage shown. Wah ~ 20 cores, all I have just 4 ........
PySimpleGUI 2020-01-09T03:36:00Z DOH! You're right (of course). It looks a lot more impressive with the stats
PySimpleGUI 2020-01-09T04:02:55Z
4.15.0 PySimpleGUI 08-Jan-2020
Dynamic windows! Extend your layouts after your window has been created.
Graph Element - change coordinates after created
Fixes for various issues
-
Window.extend_layout
-
Graph.change_coordinates - realtime change of coordinate systems for the Graph element
-
theme_text_element_background_color - new function to expose this setting
-
Radio & Checkbox colors changed to be ligher/darker than background
-
Progress bar - allow updates of value > max value
-
Output element does deletes now so that cleanup works. Can use in multiple windows as a result
-
DrawArc (draw_arc) - New width / line width parameter
-
RGB does more error checking, converts types
-
More descriptive errors for find element
-
popup_error used interally now sets keep on top
-
Element Re-use wording changed so that it's clear the element is the problem not the layout when re-use detected
-
Window.Close (Window.close) - fix for not immediately seeing the window disappear on Linux when clicking "X"
-
Window.BringToFront (bring_to_front) - on Windows needed to use topmost to bring window to front insteade of lift
-
Multiline Scrollbar - removed the scrollbar color. It doesn't work on Windows so keeping consistent
-
Changed how Debug Windows are created. Uses finalize now instead of the read non-blocking
-
Fix for Debug Window being closed by X causing main window to also close
-
Changed all "black" and "white" in the Look and Feel table to #000000 and #FFFFFF
-
Added new color processing functions for internal use (hsl and hsv related)
-
popup - extended the automatic wrapping capabilities to messages containing \n
-
Test harness uses a nicer colors for event, value print outs.
-
_timeit decorator for timing functions
PySimpleGUI 2020-01-10T04:28:37Z
4.15.1 PySimpleGUI 9-Jan-2020
Jammed out a quick patch to remove a bad change to popup
.
PySimpleGUI 2020-01-17T00:00:20Z
0.35.0 PySimpleGUIWeb 16-Jan-2020
-
Fixed Slider crash caused by latest Remi release
-
Brought over latest Theme code from PySimpleGUI-tk (text background color, changed all black and white refs to hex)
-
New Graph.change_coordinates method
-
Removed check for no image specified in Image.update (so cal specify visibility without changing image for example)
Sorry this took longer to get out than it should have, especially since it was crashing
PySimpleGUI 2020-01-18T21:27:14Z
ptoaster
- A PySimpleGUI Toaster Window
Just released a new package. I figure, what the heck, why not make some of these interesting demos actual packages. They're good enough, right? I hope so. If not, I'm sure Reddit will tell me if I'm not.
You'll find the GitHub here:
https://github.com/PySimpleGUI/ptoaster
You can pip install it:
pip install ptoaster
It is based on the Demo Program:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Notification_Window_Fade_In_Out.py
I did significant reworking of the program to remove all direct tkinter calls as well as r3emoved all of the time.sleep calls. The result is a much more interactive and responsive program.
Oh, the most important part.... it's written using the multi-processing library. You can expect to see a lot more of these multi-processing based demos now that I've discovered how to use them correctly. This enables you to do things like splash windows or other "background windows" that are truly in the background. It is entirely separate from your main program.
While tempting to use this for LOTS of stuff, I want to make sure I don't also abuse it. Or, then again, maybe abuse is exactly what's needed!
I also posted this one on Reddit, so if you want to be a part of the discussion, you'll find it here: https://www.reddit.com/r/Python/comments/eqmikl/ptoaster_a_package_for_displaying_toaster_style/
PySimpleGUI 2020-01-27T14:25:28Z
The PySimpleGUI Architecture - More refinement in the explanation...
I've been working on documenting PySimpleGUI at a high level. One key difference between PySimpleGUI and other GUI frameworks is in the handling of "events" and how the code is organized.
This chart shows 3 libraries and how user code interacts with them. Two are GUIs, one is the Standard Library "Queue" library and its interface.
PySimpleGUI is modeled using the same architecture as other Python libraries that receive outside events or data. Rather than user code being executed, the event information is saved until the application asks for it.
PySimpleGUI 2020-01-27T14:34:31Z
Side by Side Compares
Whenever possible I try to duplicate the results created by tkinter, Wx, or Qt code.
This part week the Real Python folks published a NEW Tkinter Tutorial! Yes, it's 2020 and for some reason there are not enough basic tkinter tutorials in the world.
Anyway, their first big program example is how to convert from F to C.
Here are the resulting windows when the code below is executed.
tkinter window:
PySimpleGUI window:
Example 1 - Convert temperatures
import tkinter as tk
def fahrenheit_to_celsius():
"""Convert the value for Fahrenheit to Celsius and insert the
result into lbl_result.
"""
fahrenheit = ent_temperature.get()
celsius = (5/9) * (float(fahrenheit) - 32)
lbl_result["text"] = f"{round(celsius, 2)} \N{DEGREE CELSIUS}"
# Set-up the window
window = tk.Tk()
window.title("Temperature Converter")
window.resizable(width=False, height=False)
# Create the Fahrenheit entry frame with an Entry
# widget and label in it
frm_entry = tk.Frame(master=window)
ent_temperature = tk.Entry(master=frm_entry, width=10)
lbl_temp = tk.Label(master=frm_entry, text="\N{DEGREE FAHRENHEIT}")
# Layout the temperature Entry and Label in frm_entry
# using the .grid() geometry manager
ent_temperature.grid(row=0, column=0, sticky="e")
lbl_temp.grid(row=0, column=1, sticky="w")
# Create the conversion Button and result display Label
btn_convert = tk.Button(
master=window,
text="\N{RIGHTWARDS BLACK ARROW}",
command=fahrenheit_to_celsius
)
lbl_result = tk.Label(master=window, text="\N{DEGREE CELSIUS}")
# Set-up the layout using the .grid() geometry manager
frm_entry.grid(row=0, column=0, padx=10)
btn_convert.grid(row=0, column=1, pady=10)
lbl_result.grid(row=0, column=2, padx=10)
# Run the application
window.mainloop()
The PySimpleGUI version of this code produces a similar, but better looking window, in quite a bit less code. 23 lines of "real code" in the Real Python example.
This PySimpleGUI version is, uhm, 9 lines. Maybe I cheated and did something special in Python to reduce the number of lines? No, I didn't do anything like that. In fact it could have been shortened further but I resisted. There is the added feature that pressing the return key will perform the conversion just as clicking the button does.
from PySimpleGUI import Text, Input, Button, Window
layout = [[Input(size=(5,1), justification='r', key='-TEMP-F-'), Text('°F'), Button('→', bind_return_key=True), Text(size=(8,1), key='-TEMP-C-')]]
window = Window('Temperature Converter', layout)
while True:
event, values = window.read()
if event is None:
break
window['-TEMP-C-'].update(f"{(5/9) * (float(values['-TEMP-F-']) - 32):.2f}°C")
window.close()
PySimpleGUI 2020-01-28T15:34:04Z
print_to_element
added to GitHub in Tk and Qt
Today both PySimpleGUI and PySimpleGUIQt gained a new function:
def print_to_element(multiline_element, *args, end=None, sep=None, text_color=None, background_color=None):
"""
Print like Python normally prints except route the output to a multline element and also add colors if desired
:param multiline_element: (Multiline) The multiline element to be output to
:param args: List[Any] The arguments to print
:param end: (str) The end char to use just like print uses
:param sep: (str) The separation character like print uses
:param text_color: The color of the text
:param background_color: The background color of the line
"""
Here's a demo program that shows how to make the call
# import PySimpleGUI as sg
import PySimpleGUIQt as sg
"""
Demonstration of how to work with multiple colors when outputting text to a multiline element
"""
sg.theme('Dark Blue 3')
def main():
MLINE_KEY = '-MLINE-'+sg.WRITE_ONLY_KEY
layout = [ [sg.Text('Demonstration of Multiline Element\'s ability to show multiple colors ')],
[sg.Multiline(size=(60,20), key=MLINE_KEY)],
[sg.B('Plain'), sg.Button('Text Blue Line'), sg.Button('Text Green Line')],
[sg.Button('Background Blue Line'),sg.Button('Background Green Line'), sg.B('White on Green')] ]
window = sg.Window('Demonstration of Multicolored Multline Text', layout)
while True:
event, values = window.read() # type: (str, dict)
print(event, values)
if event in (None, 'Exit'):
break
if 'Text Blue' in event:
sg.print_to_element(window[MLINE_KEY], 'This is blue text', text_color='blue', end='')
if 'Text Green' in event:
sg.print_to_element(window[MLINE_KEY], 'This is green text', text_color='green')
if 'Background Blue' in event:
sg.print_to_element(window[MLINE_KEY], 'This is Blue Background', background_color='blue')
if 'Background Green' in event:
sg.print_to_element(window[MLINE_KEY], 'This is Green Background', background_color='green')
if 'White on Green' in event:
sg.print_to_element(window[MLINE_KEY], 'This is white text on a green background', text_color='white', background_color='green')
if event == 'Plain':
sg.print_to_element(window[MLINE_KEY], 'This is plain text with no extra coloring')
window.close()
if __name__ == '__main__':
main()
It's identical to the Print
function that already exists. The difference is that the first parameter is a Multiline
element to "print" to. This allows you to "print" to multiple locations a window, not just to Output elements.
Does not work for MultilineOutput elements yet as those do not yet have color support.
Enjoy! Go make some colorful stuff!
PySimpleGUI 2020-01-31T15:14:33Z
The Recent Slow Going Explanation and Need to Commercialize
I'm sorry that the Issues have been piling up recently, some not yet responded to. I'm doing my best to get to them all.
The past few months have been spent trying to ensure a future for PySimpleGUI beyond the next few months.
While PySimpleGUI is licensed using an Open Source license, the development of PySimpleGUI has not been an Open Source development effort. The project has been intentionally structured as a high-burn, highly-focused and intense effort at getting a proof of concept built and deployed with the intention of commercializing so that the future is a secure one.
Some may not agree with this approach, but PySimpleGUI would not have been made available publicly if commercializing was not part of the plan. It was initially written as a package used to provide a GUI framework for another product also being commercially developed. A decision to open up the usage of PySimpleGUI to the public as I saw a real need there that could be filled and so in Feb 2018 PySimpleGUI was released.
The problem with this approach is that at some point funding will run out if there is no revenue coming in and and that's exactly what's happened. Two years of full-time development and investment in consulting help has taken its toll.
Thank you to everyone for the support and patience. I'm hopeful that things work out so that project has a future.
PySimpleGUI 2020-01-31T16:20:14Z
300,000 Installs of PySimpleGUI-tk and 708,000 Overall
The plain tkinter port of PySimpleGUI has just crossed the 300,000 pip installs mark. Thanks for everyone for making this happen!
A Qt / Pyside2 Comparison
One yard stick that PySimpleGUI can be measured against is Qt, and in particular pyside2. PySimpleGUI and pyside2 were released in the same month in 2018, July.
Pyside2 has 720,000 installs. Of those, some portion of them come from the 112,000 installs of PySimpleGUIQt.
It's pretty remarkable that an unmarketed GUI package can capture the attention that PySimpleGUI has when compared against the efforts of a well-funded effort like Qt's pyside2.
Popularity / Trend
Google Trends shows that while launched at the same time, PySimpleGUI has steadily increased in search popularity as compared to pyside2.
PySimpleGUI 2020-02-08T16:34:19Z
Thanks for the support! 3,240 Stars and 400 Public Repos
Again PySimpleGUI has the best user community on GitHub! Very supportive bunch you folks are. The stars really help demonstrate "popularity" to people that aren't familiar with Python GUIs and what's popular with users at the moment. They're personally motivating to see as well as it means people are coming to take a look and like what they see. It's awesome when that happens!
These numbers are some of the better stats to use as they are not computer generated and it's difficult to manipulate them. Pip installs are a stat that's not quite as accurate as they don't represent individuals making discrete actions since a good number of pip installs are not the initial install but instead upgrades, etc.
Building applications using PySimpleGUI is by far the best way to contribute if you're wanting to contribute. Others learn from your code (including yours truly) and are motivating to see as well. They give other people that are considering making a GUI application hope that they too will be successful. Some user programs have been turned into either demos or entire projects. The ptoaster repo is a great example of a user posting some code that turned out to be super-cool stuff.
TIP - If you post a repo on GitHub for your PySimpleGUI project, PLEASE post some screenshots. It's super easy to drop screenshots into your readme. For projects that do this, they get a lot more attention from other people. People like pictures.
PySimpleGUI 2020-02-08T17:39:01Z
Thank you for not using import *
Every time I see a tkinter based program with from tkinter import *
I'm SO thankful that I never see any of the PySimpleGUI users doing this. I don't recall anyone, at any time, use an import * with PySimpleGUI.
It's like someone posted one example way back when that had an import * and then everyone copied that example and used it as the basis of their code, which was then copied by the next person, and the next, and still today people are copying code that has from tkinter import *
at the top.
It's interesting that tkinter is one of the only packages that where I see this import problem. It's rarely done with any other package. Why is that?? (rhetorical question) Whatever the reason, I'm damned glad none of your fine users have done this to PySimpleGUI.
There have been a few demo programs written recently that import individual objects and functions, but that was done to create super-simple appearing code for presentations, etc. It's funny that when a few people saw these simple programs, they complained about importing the individual objects and liked seeing the sg.
prefix. Here's an example of one of those demos:
from PySimpleGUI import Window, Text, Button
layout = [ [Text('Look, this is a real window!')],
[Text('Complete with buttons')],
[Button('Ok'), Button('Cancel')] ]
window = Window('Window Title', layout)
event, values = window.read()
window.close()
PySimpleGUI 2020-02-08T19:32:51Z
Experimental-ish Window.read(close=True)
Finally got around to adding this enhancement. It touches such a fundamental piece of the system (read
) that it makes me quite nervous.
It'll bring back the good old days of being able to write a 1-line GUI.
import PySimpleGUI as sg
event, values = sg.Window('Window Title', [[sg.Text('Enter Something')], [sg.Input(key='-IN-'),],[sg.Button('OK'), sg.Button('Cancel')]]).read(close=True)
In the Enhancement request that was opened last year I specified the parameter as close_window
but stayed simple with close
PySimpleGUI 2020-02-09T21:23:03Z
System Tray Icon - for tkinter??
I've completed and released to GitHub a version of the SystemTray
interface that is currently implemented in PySimpleGUIWx and PySimpleGUIQt. The biggest differences are:
-
The icon doesn't actually run in the system tray but instead as an icon near the system tray
-
The message balloon doesn't look the same. Instead it's a transparent window that is borrowed from the ptoaster project
-
There is no "X" on the message balloon, but clicking it will close it, as well as return a click event to your program. I'll add a separate "X" button soon
I'm blown away that it works, at all, and even more that it looks so similar when the same code is run.
Here's how my Issues Watcher menu looks when run on PySimpleGUIWx
And here's how it looks running the PySimpleGUI version
Even the tooltip looks similar
I'm sure some people will think of this as really clunky and ugly looking, but I know also some will find it an interesting way to be able to interact with their code when they can't install Wx or Qt on their system but still want a system tray feature.
Hopefully I'll be able to release this to PyPI soon-ish. I'm a little spooked by the read with close feature being added, but delaying releasing only means that even more features get jammed into this release. It's already looking pretty full.
PySimpleGUI 2020-02-10T18:50:54Z
Case Study - Using the SystemTray Feature on Tkinter
I've started running both my PySimpleGUIWx based GitHub issues watcher application and the new PySimpleGUI based one.
When a new Issue is filed, I get a popup window. I made the tkinter one have a Titlebar so I could tell the difference.
Here is the result of both running and detecting a change in the Issues:
Both programs turned their icons red to indicate the change in addition to the popup window.
Here is the initial state of both icons:
The net is that while not ideal, it's possible to almost completely duplicate the look and feel of a system tray icon. The PySimpleGUI interface is identical either way. The code you see running for the 2 images above are identical, a pretty amazing capability.
Not Tried on Mac / Linux
A quick warning about this interface. The SystemTray code for PySimpleGUI has not been tried on Linux and Mac. It should work just fine, but nothing is for sure at this point. I'll be testing it on Linux today.
PySimpleGUI 2020-02-20T14:14:06Z
Printing to Multiline Elements
New print capability is coming to PyPI later today, as version 4.16.0, once the release notes and documentation changes are done.
The Output
element is certainly very handy for re-routing your print
statements to your GUI window. A new capability is the function print_to_element
.
It has a somewhat unusual call structure, but hopefully the sample code will explain how best to use it. A lambda expression or function is an ideal way of handing this call.
Here's the function definition:
def print_to_element(multiline_element, *args, end=None, sep=None, text_color=None, background_color=None):
"""
Print like Python normally prints except route the output to a multline element and also add colors if desired
:param multiline_element: (Multiline) The multiline element to be output to
:param args: List[Any] The arguments to print
:param end: (str) The end char to use just like print uses
:param sep: (str) The separation character like print uses
:param text_color: The color of the text
:param background_color: The background color of the line
"""
And here is a test harness that shows one way of converting your print
statements to use this new capability.
import PySimpleGUI as sg
print = lambda *args, **kwargs: sg.print_to_element(window['-ML-'+sg.WRITE_ONLY_KEY], *args, **kwargs)
# If you prefer using a function over lambda, then here's your function
# def print(*args, **kwargs):
# sg.print_to_element(window['-ML-'+sg.WRITE_ONLY_KEY], *args, **kwargs)
layout = [
[sg.Multiline(size=(70,20), key='-ML-'+sg.WRITE_ONLY_KEY)],
[sg.Button('Go')],
]
window = sg.Window('Stdout is rerouted test', layout)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event is None:
break
if event == 'Go':
print('This is a test of print', end='', text_color='red')
print('Here is the line that should be on the same line')
window.close()
OK, a few things to notice about this code.... the first one being the lambda that starts us off. This expression is what maps your current print
statements to instead of printing to the console, calling PySimpleGUI's multiline output.
You can directly call the print_to_element
every time you want to output, but it will make for some ugly code. Better to use a function / lambda expression. Lambda may be unsettling to some as it's being directly called rather than used as a parameter.
There are 2 parameters in the print_to_element
call that are also in calls to print - end
, sep
. The other parameters are used to control the color of the output and which element the output will be routed to.
Here is the result of running the code and pressing the Go button a couple of times:
One final note.... the key
for the Multiline
element has a modifier added to the string - WRITE_ONLY_KEY
. Any element that has this value as part of the key will NOT be included in the return values dictionary. This is why you'll see in the screenshot that the values variable is empty. Normally the Multiline
element would return a value but since this one is being used to output only then it's best to exclude it from the return values as the data is meaningless and it could get lengthy.
Note that the "write only indicator" value is a constant variable, in this case the variable is sg.WRITE_ONLY_KEY
. This is not the actual string value that is added onto your key.
This new function print_to_element
could have easily been part of the user code, but because print
functionality is already supported for the output element and the debug window, it made sense to provide a slightly more unified interface that includes printing not just to the debug window but also to any element in your layout.
Providing more GUI options for moving print
output from the normal command line seemed like a good addition.
PySimpleGUI 2020-02-20T14:34:39Z
Window.read(close=True)
This new feature was already mentioned before but it's worth mentioning again since it's going to be released to PyPI later today.
WAY back in the early days of PySimpleGUI it was possible and easy to create a single-line of code that would display a window, get the data from the user and return the values. With the addition of the close
parameter that capability is again available to PySimpleGUI users.
Here's a bit of code to show one way of using this parameter.
import PySimpleGUI as sg
login = sg.Window('Enter your login name',
[[sg.Text('Login Name: '), sg.Input()],
[sg.Button('Submit', bind_return_key=True)] ]).read(close=True)[1][0]
print(f'Your login ID is {login}')
The line of code beginning with login
is a little tricky... to make it event trickier, the word read
can be removed as the default "call" action on a window is to call read
. Remember that window()
is the same was window.read()
. Removing the read
you would have this line of code:
login = sg.Window('Enter your login name',
[[sg.Text('Login Name: '), sg.Input()],
[sg.Button('Submit', bind_return_key=True)] ])(close=True)[1][0]
Let's leave the read in there however and pull it apart a little.
The layout of the window is included as the second parameter in the Window
creation instead of using the typical variable named layout
. For a complex layout, I recommend using a variable, but for when you are trying to really compact stuff down, don't be afraid to try these kinds of calls out.
The first part creates your window:
sg.Window('Enter your login name',
[[sg.Text('Login Name: '), sg.Input()],
[sg.Button('Submit', bind_return_key=True)] ])
Then we add on the .read
to read the newly created window. This is where we add the close
parameter so that the window will automatically close when the read returns.
Finally, we parse out the values returned from window.read()
. Recall that normally the call structure for a read call is:
Looking at our 1-line call, notice two indexes being used.
The first index is [1]
and will give us the values
portion of the returned values. Since we did not specify a key in the Input
element, the automatic numbering will be used. The first value in the return values will be [0]
which is what we're wanting.
You can also use the traditional design pattern you're used to for reads, the variables event
and values
.
event, values = sg.Window('Enter your login name',
[[sg.Text('Login Name: '), sg.Input()],
[sg.Button('Submit', bind_return_key=True)] ]).read(close=True)]
print(f'Your login ID is {values[0]}')
Inline Custom (user defined) popup
The "read with close" construct can also be used to create your own popup
functionality quite easily. It removes the need for a call to window.close()
and removes the need for a window
variable too.
Here's an "in-line" version of popup.
import PySimpleGUI as sg
long_string = '123456789 '* 40
event, values = sg.Window('This is my custom popup',
[[sg.Text(long_string, size=(60,None))],
[sg.B('OK'), sg.B('Cancel') ]]).read(close=True)
print(f'Button clicked was {event}')
When you run the code, this is the result
There's one trick in this call that's perhaps not documented and that is the ability to choose None
for the height in the size
parameter. This will cause PySimpleGUI to create a Text
element that fits the size of the string. It will use however many rows that are required.
So, the next time you're feeling like popup
need more button choices added, make your own instead using this 1-line popup construct.
PySimpleGUI 2020-02-20T21:12:27Z
4.16.0 PySimpleGUI 20-Feb-2020
The "LONG time coming" release. System Tray, Read with close + loads more changes
Note - there is a known problem with the built-in debugger created when the new read with close was added
-
System Tray - Simulates the System Tray feature currently in PySimpleGUIWx and PySimpleGUIQt. All calls are the same. The icon is located just above the system tray (bottom right corner)
-
Window.read - NEW close parameter will close the window for you after the read completes. Can make a single line window using this
-
Window.element_list - Returns a list of all elements in the window
-
Element.unbind - can remove a previously created binding
-
Element.set_size - retries using "length" if "height" setting fails
-
Listbox.update - select_mode parameter added
-
Listbox.update - no longer selects the first entry when all values are changed
-
Listbox.get - new. use to get the current values. Will be the same as the read return dictionary
-
Checkbox.update - added ability to change background and text colors. Uses the same combuted checkbox background color (may remove)
-
Multiline.update - fix for when no value is specified
-
Multiline - Check for None when creating. Ignores None rather than converting to string
-
Text.update - added changing value to string. Assumed caller was passing in string previously.
-
Text Element - justification can be specified with a single character. l=left, r=right, c=center. Previously had to fully spell out
-
Input Element - justification can be specified with a single character. l=left, r=right, c=center. Previously had to fully spell out
-
StatusBar Element - justification can be specified with a single character. l=left, r=right, c=center. Previously had to fully spell out
-
Image Element - can specify no image when creating. Previously gave a warning and required filename = '' to indicate nothing set
-
Table Element - justification can be specified as an "l" or "r" instead of full word left/right
-
Tree Element - justification can be specified as an "l" or "r" instead of full word left/right
-
Graph.draw_point - changed to using 1/2 the size rather than size. Set width = 0 so no outline will be drawn
-
Graph.draw_polygon - new drawing method! Can now draw polygons that fill
-
Layout error checking and reporting added for - Frame, Tab, TabGroup, Column, Window
-
Menu - Ability to set the font for the menu items
-
Debug window - fix for problem closing using the "Quit" button
-
print_to_element - print-like call that can be used to output to a Multiline element as if it is an Output element
PySimpleGUI 2020-02-21T01:20:42Z
0.36.0 PySimpleGUIWeb 20-Feb-2020
Fixes problem that was triggered by a Remi update
-
Allow empty value to be specified when creating Image element
-
Fix for Text element crashing following the Remi 2020.2.5 release
- Crash will show trying to use method "set_layout_orientation"
This is the first time I've pinned a PySimpleGUIWeb release directly to a Remi release. There have been a couple of times now where a Remi release has broken PySimpleGUI badly enough that PySimpleGUI failed to run following the Remi upgrade. I need time between Remi releases so that these can be found and fixed prior to users running into trouble.
PySimpleGUI 2020-02-21T01:42:00Z
ptoaster-style Notifications Now Builtin
A BONUS for you in the 4.16.0 release.
Part of the new System Tray functionality for the PySimpleGUI tkinter port are the notification windows like from the ptoaster package.
https://github.com/PySimpleGUI/ptoaster
ptoaster is a little different because it runs the notification windows in the background, as a subprocess. The notification windows that are part of the System Tray code do not run as a subprocess. The call does not return until the notification window closes.
The notification window can be directly called using a class method for the SystemTray
class.
Because it's a class method, you can call it directly without actually making a SystemTray object.
This code:
created and showed this little window in the bottom right corner of the screen:
Here is the documentation for class method - SystemTray.notify
SystemTray.notify
Displays a "notification window", usually in the bottom right corner of your display. Has an icon, a title, and a message
The window will slowly fade in and out if desired. Clicking on the window will cause it to move through the end the current "phase". For example, if the window was fading in and it was clicked, then it would immediately stop fading in and instead be fully visible. It's a way for the user to quickly dismiss the window.
notify(title,
message,
icon=...,
display_duration_in_ms=3000,
fade_in_duration=1000,
alpha=0.9,
location=None)
Parameter Descriptions:
|Name|Meaning|
|---|---|
|title|(str) Text to be shown at the top of the window in a larger font|
|message|(str) Text message that makes up the majority of the window|
|icon|Union[bytes, str] A base64 encoded PNG/GIF image or PNG/GIF filename that will be displayed in the window|
|display_duration_in_ms|(int) Number of milliseconds to show the window|
|fade_in_duration|(int) Number of milliseconds to fade window in and out|
|alpha|(float) Alpha channel. 0 - invisible 1 - fully visible|
|location|Tuple[int, int] Location on the screen to display the window|
|||
| return | (int) reason for returning |
There are 4 possible values for the icon
parameter. The default is the INFORMATION icon.
SYSTEM_TRAY_MESSAGE_ICON_INFORMATION
SYSTEM_TRAY_MESSAGE_ICON_WARNING
SYSTEM_TRAY_MESSAGE_ICON_CRITICAL
SYSTEM_TRAY_MESSAGE_ICON_NOICON
Or you can specify your own icon using a PNG/GIF image encoded in Base64 or as a filename.
PySimpleGUI 2020-02-21T20:33:13Z
SimpleKivy 👀
I want to spotlight an interesting Kivy technology that borrows from the PySimpleGUI layout architecture. The result is a cool hybrid PySimpleGUI and Kivy.
https://github.com/SuperMechaDeathChrist/SimpleKivy
@SuperMechaDeathChrist has been a supporter of PySimpleGUI from way back, bringing video playback to the list of integrations. It's great to see offshoots like this! What a great group of users the PySimpleGUI crowd is, right.... was I right, huh... huh?
PySimpleGUIDroid (the Kivy port) has been in a holding pattern for a bit. Don't expect movement quickly. So, in the meantime....
Take a look at SimpleKivy. It could be a quick way to a Kivy GUI. It looks cool to me. 👍
PySimpleGUI 2020-02-21T20:38:18Z
PSG-LookyFeely 👀
And while you're cruising around GitHub looking at the cool PySimpleGUI related things, stop into the LookyFeely repository.
https://github.com/definite-d/PSG-LookyFeely
Themes have been one of the best additions to PySimpleGUI in 2019. This project takes them further, providing tools to make awesome themes.
It's another great example of a user doing some really positive, helpful community oriented things. Awesome stuff to see.
Check out the readme for some nice screenshots. I'm liking the colors!
And, there have been some really advanced tools in the works that I think will be super cool to use so keep an eye open for new stuff too.
PySimpleGUI 2020-02-22T00:27:57Z
MosaicMaker When features become applications
An interesting lesson that's emerging from the PySimpleGUI effort. You can take a utility with a feature, add a GUI to it, and you've got yourself an application / product.
This project is a great example of creating a standalone application that's VERY handy using PySimpleGUI.
https://github.com/flipswitchingmonkey/MosaicMaker
It uses ffmpeg to create a contact sheet for your movie. The program runs both as a command line application as well as one with a GUI.
It leverages one small part of ffmpeg. You could take a number of ffmpeg operations and write a nice little application based on them. I hope someone does more of these kinds of utilities.
Python is SO handy for processing stuff and now with PySimpleGUI it's trivial to turn things into applications, perhaps the result will be more applications that can be run by normal people.
PySimpleGUI 2020-02-22T21:26:29Z
A Pip Update GUI
On Medium there have been a series of PySimpleGUI articles written by Costas Andreou under the topic of Data Science. They've been quite popular and I like the code he writes.
His latest project enables you to do bulk updates on your pip installed packages, on a selective basis. You can choose the package using checkboxes.
I don't like that these are all on Medium as it's a subscription service.
https://towardsdatascience.com/building-a-python-ui-to-keep-your-libraries-up-to-date-6d3465d1b652
The originally posted code froze the GUI while the pip command is being initially run to get the list of packages. I have a LOT of packages installed so it takes a very long time.
Rather than repeatedly seeing windows offer me the opportunity to close the window, I decided to make an animation instead of freezing.
To do that, all I had to do was run the subprocess as a Thread. This was the async mechanism that I needed in order to keep on executing and showing that animation.
This little window is shown and animates while the pip command runs.
This is the first part of the program that gets the list of packages while running an animation on the screen.
fhandle = open(r'C:\temp\update.txt', 'w')
thread = threading.Thread(target=lambda: subprocess.run('pip list --outdated', shell=True, stdout=fhandle), daemon=True)
thread.start()
while True:
sg.popup_animated(sg.DEFAULT_BASE64_LOADING_GIF, 'Loading list of packages', time_between_frames=100)
thread.join(timeout=.1)
if not thread.is_alive():
break
sg.popup_animated(None)
fhandle.close()
The addition was to encapsulate the subprocess in a Thread which I cleverly did as a lambda expression (rare victory!)
Here's the full code from the article with the animation added.
import subprocess
import pandas as pd
import re
import PySimpleGUI as sg
import threading
fhandle = open(r'C:\temp\update.txt', 'w')
thread = threading.Thread(target=lambda: subprocess.run('pip list --outdated', shell=True, stdout=fhandle), daemon=True)
thread.start()
while True:
sg.popup_animated(sg.DEFAULT_BASE64_LOADING_GIF, 'Loading list of packages', time_between_frames=100)
thread.join(timeout=.1)
if not thread.is_alive():
break
sg.popup_animated(None)
fhandle.close()
df1 = pd.DataFrame(columns=['Package', 'Version', 'Latest', 'Type'])
fhandle = open(r'C:\temp\update.txt', 'r')
AnyPackagesToUpgrade = 0
for i, line in enumerate(fhandle):
if i not in (0, 1): #first two lines have no packages
df1 = df1.append({
'Package': re.findall('(.+?)\s', line)[0],
'Version': re.findall('([0-9].+?)\s', line)[0],
'Latest': re.findall('([0-9].+?)\s', line)[1],
'Type': re.findall('\s([a-zA-Z]+)', line)[0]
}, ignore_index=True)
AnyPackagesToUpgrade = 1 #if no packages, then don't bring up full UI later on
formlists = [] #This will be the list to be displayed on the UI
i = 0
while i < len(df1): #this is the checkbox magic that will show up on the UI
formlists.append([sg.Checkbox(df1.iloc[i, :])])
formlists.append([sg.Text('-'*50)])
i += 1
layout = [
[sg.Column(layout=[
*formlists], vertical_scroll_only=True, scrollable=True, size=(704, 400)
)],
[sg.Output(size=(100, 10))],
[sg.Submit('Upgrade'), sg.Cancel('Exit')]
]
window = sg.Window('Choose Package to Upgrade', layout, size=(800, 650))
if AnyPackagesToUpgrade == 0:
sg.Popup('No Packages requiring upgrade found')
quit()
definedkey = []
while True: # The Event Loop
event, values = window.read()
# print(event, values) # debug
if event in (None, 'Exit', 'Cancel'):
break
elif event == 'Upgrade':
for index, value in enumerate(values):
if values[index] == True:
#print(df1.iloc[index][0])
subprocess.run('pip install --upgrade ' + df1.iloc[index][0])
print('Upgrading', df1.iloc[index][0])
print('Upgrading process finished.')
I may make one more pass at it so that it can be generalized and put into the Cookbook as a recipe for running background processes while showing an animation.
PySimpleGUI 2020-02-23T13:25:47Z
A Request for Help With Getting a PySimpleGUI Application Listed 👀
One project that's been a good "portfolio" project to be able to show people what PySimpleGUI is capable of is the PyIDM project (Internet Download Manager functionality written in Python). It's super cool and is mind blowing how well it does many tasks simultaneously.
Getting listed in some of the curated Python lists is one important way projects get found. I know it gave PySimpleGUI a big boost to be listed on Vinta
You may recall the plea for help in getting PySimpleGUI listed?
The PySimpleGUI community can help out one of their own by voting for this hard working open source project on Vinta. It requires 25 votes. So far there are 11. It took months for PySimpleGUI to get there, but it was worth the begging to get there as more people found the project.
PLEASE consider taking a moment and going to this page to upvote. https://github.com/vinta/awesome-python/pull/1450
To vote, look for the little face on the issue (just like this issue has one). Click it and choose a thumbs up.
PySimpleGUI 2020-02-23T22:52:26Z
Making Button Images Transparent Using Themes
In order to make a button with an image blend so that it's flush and doesn't have a square around it, you need to set the button color to match the background that it is sitting on.
These buttons from a MIDI player are an example.
For each of the 3 buttons that have images in that portion of the window, they each have their button_color parameter set to:
This leverages the "theme" function calls to get the color of the background and to set the color of the text to be the same as the window's text color.
Do not try to use the old constant TRANSPARENT_BUTTON
as it is being completely removed. It was changed to be a big warning string, but I found that is crashing tkinter when it's passed in, so it's best that it be completely removed in the next PyPI release. It's original value was a color of gray that matched the only-gray-windows that existed way back when PySimpleGUI launched.
PySimpleGUI 2020-02-24T01:31:16Z
MIDI Looper Project
PySimpleGUI was and continues to be a means to an end. A way to get a user interface.
OK, so maybe this interface isn't at all pretty and it's pretty klunky, but for what it does, it's fantastic.
I often learn piano pieces using MIDI and a piano hooked up to the computer. This allows me to playback midi files using my piano. Because I'm learning the pieces, I often want to loop on sections of music as I practice it over and over. And of course I need to slow things way down (thus the tempo slider).
This crude program is actually an entire workbench of sorts for learning music in this manner.
I use the slider at the bottom as trims. I roughly mark where I want the looping to occur then I use the sliders to position the exact spot of the beginning and end of the loop.
It's actually a very vert old program that used the call to FlexForm
instead of Window
. Dusted it off tonight to add the tracks as a listbox so that I can easily skip from one track to the next in a non-sequential way. Using the next and previous track buttons was getting old. And it looks 1,000 times better. Still plenty more to fix on it, but for now, it's good enough and I'm back up and running.
I encourage you to make tools and utilities and stuff like this that you can use. Adding a user interface onto other people's code can do amazing things. That's all that's happening in almost all of the PySimpleGUI demo projects. They're integrating other code with a user interface.
PySimpleGUI 2020-02-24T14:18:49Z
Animated Shell Notification
There is nothing more frustrating to every user and programmer for that matter than to have your OS display:
YOU know your program is busy running a shell command... your user MAY know your program is busy running a shell command.
Wouldn't it be nice if the user and the operating system both also knew that you're program is busy, not hung?
Well, this technique will do just that.
Instead of seeing the "you're hung, do you want to kill the program" dialog box, you'll see this animation:
How can this be? 😳
Here's how....this code was posted as a Demo in the demo programs area, but because it's so short, I'm including it here:
import subprocess
import PySimpleGUI as sg
import threading
"""
Demo - Run a shell command while displaying an animated GIF to inform the user the
program is still running.
If you have a GUI and you start a subprocess to run a shell command, the GUI essentually
locks up and often the operation system will off to terminate the program for you.
This demo fixes this situation by running the subprocess as a Thread. This enables
the subproces to run async to the main program. The main program then simply runs a loop,
waiting for the thread to complete running.
The output from the subprocess is saved and displayed in a scrolled popup.
"""
def process_thread():
global proc
proc = subprocess.run('pip list', shell=True, stdout=subprocess.PIPE)
thread = threading.Thread(target=process_thread, daemon=True)
thread.start()
while True:
sg.popup_animated(sg.DEFAULT_BASE64_LOADING_GIF, 'Loading list of packages', time_between_frames=100)
thread.join(timeout=.1)
if not thread.is_alive():
break
sg.popup_animated(None)
output = proc.__str__().replace('\\r\\n', '\n')
sg.popup_scrolled(output)
Expect to see this construct pop up in PySimpleGUI code more and more. We need to learn ways to run these long-running background operations in the background so that the user experience can be improved. It's much nicer to see an animation playing than a static window.
PySimpleGUI 2020-02-24T15:54:34Z
popup_notify
One of the nice things about the popup
family of calls is the ability to add as many parameters to display as you wish. It's nice not having to construct a single string to display because an API call only has a single "message" parameter. This is the situation with the call SystemTray.notify
.
In the spirit of supplying a popup
function for displaying small windows such as the fade in/out notification window I've created a new popup called popup_notify
.
Here's the definition for it
def popup_notify(*args, title='', icon=SYSTEM_TRAY_MESSAGE_ICON_INFORMATION, display_duration_in_ms=SYSTEM_TRAY_MESSAGE_DISPLAY_DURATION_IN_MILLISECONDS,
fade_in_duration=SYSTEM_TRAY_MESSAGE_FADE_IN_DURATION, alpha=0.9, location=None):
"""
Displays a "notification window", usually in the bottom right corner of your display. Has an icon, a title, and a message. It is more like a "toaster" window than the normal popups.
The window will slowly fade in and out if desired. Clicking on the window will cause it to move through the end the current "phase". For example, if the window was fading in and it was clicked, then it would immediately stop fading in and instead be fully visible. It's a way for the user to quickly dismiss the window.
The return code specifies why the call is returning (e.g. did the user click the message to dismiss it)
:param title: (str) Text to be shown at the top of the window in a larger font
:param message: (str) Text message that makes up the majority of the window
:param icon: Union[bytes, str) A base64 encoded PNG/GIF image or PNG/GIF filename that will be displayed in the window
:param display_duration_in_ms: (int) Number of milliseconds to show the window
:param fade_in_duration: (int) Number of milliseconds to fade window in and out
:param alpha: (float) Alpha channel. 0 - invisible 1 - fully visible
:param location: Tuple[int, int] Location on the screen to display the window
:return: (int) reason for returning
"""
Let's see this popup in action. This call:
sg.popup_notify('Check it out... this is a popup!','Part 1', 'Part 2', '1234567890 '*6, title='Looks just like a popup!')
Creates this window and effect in the bottom right corner of the window.
If you don't like the placement, you can set the location parameter. This line will create the window so that the upper left corner is centered in the window.
sg.popup_notify('Check it out... this is a popup!','Part 1', 'Part 2', '1234567890 '*6, title='Looks just like a popup!', location=(sg.Window.get_screen_size()[0]//2, sg.Window.get_screen_size()[1]//2))
PySimpleGUI 2020-02-24T19:28:59Z
Animated Lengthy Shell Commands
A new function was just added.... shell_with_animation
.
This is a super-high-level call that you could argue doesn't belong in the PySimpleGUI APIs. But I saw an opportunity to create an interesting capability that may help spur programs that use command line programs to create full applictions.
The recent "Mosaic" project that uses ffmpeg to create a contact sheet of images from videos was the catalyst for this. Some demo code was developed to help show animations while background operations are running. That demo code ended up being pulled into PySimpleGUI itself.
The result is a single function call that you can call that will run a shell command and return a string with that command's output. While the command is running, an animated GIF will be shown until the operation completes. Rather than push a demo onto you to modify it seemed a lot easier to just give you a more complete solution, built right into the APIs.
Here's the function definition:
def shell_with_animation(command, args=None, image_source=DEFAULT_BASE64_LOADING_GIF, message=None, background_color=None, text_color=None, font=None, no_titlebar=True, grab_anywhere=True, keep_on_top=True, location=(None, None), alpha_channel=None, time_between_frames=100, transparent_color=None):
"""
Execute a "shell command" (anything capable of being launched using subprocess.run) and
while the command is running, show an animated popup so that the user knows that a long-running
command is being executed. Without this mechanism, the GUI appears locked up.
:param command: (str) The command to run
:param args: List[str] List of arguments
:param image_source: Union[str, bytes] Either a filename or a base64 string.
:param message: (str) An optional message to be shown with the animation
:param background_color: (str) color of background
:param text_color: (str) color of the text
:param font: Union[str, tuple) specifies the font family, size, etc
:param no_titlebar: (bool) If True then the titlebar and window frame will not be shown
:param grab_anywhere: (bool) If True then you can move the window just clicking anywhere on window, hold and drag
:param keep_on_top: (bool) If True then Window will remain on top of all other windows currently shownn
:param location: (int, int) (x,y) location on the screen to place the top left corner of your window. Default is to center on screen
:param alpha_channel: (float) Window transparency 0 = invisible 1 = completely visible. Values between are see through
:param time_between_frames: (int) Amount of time in milliseconds between each frame
:param transparent_color: (str) This color will be completely see-through in your window. Can even click through
:return: (str) The resulting string output from stdout
"""
This test harness consists of these 2 lines of code:
output = sg.shell_with_animation('pip', 'list', message='Loading your pip list', background_color='white', text_color='red', font='Helvetica 15')
sg.popup_scrolled(output, font='Courier 10')
The result is this animation is played while the pip list
is executed
And then a scrolled popup is used to display the string returned from the command.
It looks like a little extra information is on the front of what's returned from the command. Will have to look into what that is and how to edit it away. In the meantime I think it's highly usable in its current state.
I dunno, maybe this was a terrible idea. We'll see. It seems GUI programs run up against these kinds of concurrency problems often and often programmers are at a loss as to what to do. Most simply go off and do whatever long task needs to be done, letting the user fight with the OS to keep their program running.
It took me a day or two of fiddling with this stuff to figure out a workable solution, so I can only imagine how long a beginner would take. I'm no expert and there is likely a better way to do all of this that someone is likely to point out to me.
Anyway, again the hope is that more command line programs' features can be turned into full-applications using a capability like this one.
PySimpleGUI 2020-02-25T13:28:01Z
Image.update_animation_no_buffering()
Do you have a lengthy GIF file that you want to playback but have been unable to use the update_animation
code due to the short, 1000 frame, video maximum length?
If so then you'll like the new method for the Image
element, update_animation_no_buffering
. You call this method in the same way you call the update_animation
method. The difference is in the name.... there is no buffering performed. As a result, frames are read and decoded on the fly as they are needed.
The animated popup still uses the older update method as it's assumed these are short little videos. You can easily create your own 'popup' style window that has an Image
element in it that you call the update method for yourself.
PySimpleGUI 2020-03-02T14:13:04Z
The 1-line Popup
Every couple of weeks someone posts something, somewhere, suggesting an addition to popups. It's highly unlikely to happen as mentioned in the documentation. Here's why...
It's trivial to create your own popup, in-line, using 1 line of code. You might recall a post a few weeks back about the new Window.read(close=True)
capability that enables the 1-line compactness. If not, here's a refresher and a great example of it being put to good use.
Pay attention to an important fact about how the Text
element's sizing works.
OK, so, YOU have a need to show a drop-down in addition to a normal bit of text. Or maybe you want 3 buttons in your popup. Don't take the time to file an enhancement when you can solve the problem yourself in a line of code.
Here's a 3-button example done in 2 lines of code, one for creating a message, the other for showing it.
import PySimpleGUI as sg
# This is an inline custom window like a popup
my_msg = 'This is a multiline bit of text that automatically wraps and adjusts the\nmessage\nThe Text Element automatically adjusts'
event, values = sg.Window('My Popup Title',[[sg.Text(my_msg, size=(40,None))],
[sg.Button('Ok'), sg.Button('Cancel'), sg.Button('Exit')]]).read(close=True)
Here's a true 1-line call that's a bit more crowded.
import PySimpleGUI as sg
event, values = sg.Window('My Popup Title',[[sg.Text('This is a multiline bit of text that automatically wraps and adjusts the\nmessage\nThe Text Element automatically adjusts', size=(40,None))], [sg.Button('Ok'), sg.Button('Cancel'), sg.Button('Exit')]]).read(close=True)
Text
Sizes
Note that in this example the height field for the Text
element can be set to None
to specify the height should be computed. This is the only element that works this way. Don't try putting None
in other elements' sizes. This capability is specific to the tkinter port of PySimpleGUI, although it would be good to be able to do this in all of the ports.
The Lesson - Don't Be Afraid To Make a Window
For those that are starting with popups and are outgrowing them, there are plenty of simple ways of solving your problem waiting for you to discover. They're simple, quick to learn, documented, and easy to understand & put to use.
The Window
is the cornerstone of the PySimpleGUI package. Learn how to make them and it's like busting out the box of color crayons instead of using a pencil. There are not that many more lines of code you need to write than you're writing calling popup
. The basic PySimpleGUI one-shot Window program consists of 4 lines of code / sections.
-
Layout definition
-
Window creation
-
Window read
-
Window close
That's it and each of those can be a single line. As you saw above, you can combine number 3 and 4 by using the close
parameter when you read. And of course they can be crunched down to 1 line of code.
PySimpleGUI 2020-03-02T14:15:15Z
Thank you all for trying so hard!!!
I'm seeing better and better PySimpleGUI windows, many of them from users that have not required assistance. That's really encouraging. Your results motivate me to keep adding, fixing and expanding so you can do more stuff. The best way you can help this project is by building stuff that uses it. Oh, and tell everyone you know about it too 😉
Twitter is abuzz from the PyCon presentation
There was a tkinter/PySimpleGUI presentation at a PyCon-Mini in Japan not long ago with the deck and other information circulating around Twitter. Several people were already posting their PySimpleGUI project info on Twitter as well.
PySimpleGUI 2020-03-03T17:56:42Z
print_to_element
Being Replaced With Multiline.print
If you're using the newly added print_to_element
function, then you'll want to change your code soon. You can do it immediately if you're running the GitHub version of PySimpleGUI. It was only released there today. I really want to get some stuff posted to PyPI soon so it shouldn't be long.
To switch over will be trivial because your current code has all of the parameters required already. You simply need to change some syntax around.
Your code may resemble this depending on what parameters you're using.
To switch to using the Multiline.print
method, change the function to use print
method for the element you specified as the first parameter.
That's it. Normally it would likely be something simpler:
The idea behind this method is that you can go through your program and simply tack on the name of a multiline element to the front of it and you'll be printing to a multiline.
This would have been your initial print using the example above:
PySimpleGUI 2020-03-04T00:36:34Z
System Tray Icons on Tkinter - Tiny Little Windows
That's what the Tkinter version of a "System Tray Icon" is... it's a tiny little window. The one I'm running that's monitoring these GitHub Issues for changes turns red when one of you leaves a,... present for me.
Here's the size of mine at the moment:
The entire window measures 22 x 21 pixels. The Trashcan icon is considerably larger at 64 pixels. I assume you could make a 1 pixel window if you really wanted it. Your window could even blend into the background of your desktop and big one big invisible hotspot that you can interact with by clicking on it, right clicking, etc.
Because it has no titlebar, windows like this one do not show up on the taskbar. You cannot tell they're even running. It's how I get away with all these cool rainmeter type things running on my desktop all the time without it impacting my taskbar with a ton of icons.
The way the Tray Icon feature works is the little window is a single Graph Element with a right click menu. That's it. Yea, I KNOW, it's STUPID easy. Here's the internal implementation of a System Tray window:
See, just an Image element.
I could have just as easily chosen a Graph
Element and placed the image on the Graph. Both accept a right click menu and both can be bound to use a double-click. A Button
may have worked as well, but I don't think you can add a right click to a button.
Lesson here is that it's possible to make some interesting, non-traditional windows using PySimpleGUI. And there are multiple ways of doing similar things.
Have fun creating and using some of these titlebar-less windows so that you can keep some interesting utilities running all the time. Try making a little icon application that sits around and monitors the clipboard or does something useful for you.
PySimpleGUI 2020-03-05T22:45:28Z
Upgrade From GitHub
Coming SOON, very soon, in release 4.17.0, is the ability to upgrade your previously pip installed version of PySimpleGUI with the version from GitHub. This will allow you to instantly be up to date when a fix is published for an Issue you've filed.
Normally when you get something fixed and uploaded to GitHub, you're instructed to download the file PySimpleGUI.py from GitHub and to place that file in your application's folder. This is the easiest way to upgrade. It's also the easiest way to get confused when you want to go back to using a pip installed version when your fix is finally uploaded to PyPI. When that happens, you need to delete the PySimpleGUI.py file you previously downloaded.
Going forward you'll be able to run the "test harness" that comes with PySimpleGUI. To "run" the PySimpleGUI test harness type:
You will see an animated window that looks like this:
Notice the nice, new, bright red button:
Click it and you'll be asked to verify you really want to upgrade. If you approve, the new PySimpleGUI.py file will be downloaded and put into your installed packages folder. You will then see a red window indicating success:
This is a rather significant improvement as it allows you to run the latest version from GitHub without having to worry about how to download the PySimpleGUI.py file, where to put it, and you won't have to remember to delete it later when a new version is released to PyPI. You will be able to do a simple pip install and it'll be upgraded.
This feature is brought to you by Ruud van der Ham
You can learn about his cool project that is also a single .py file package here -> www.salabim.org
PySimpleGUI 2020-03-06T02:11:43Z
Upgrade from GitHub Part 2
You do not have to run the test harness GUI in order to run the upgrade from GitHub utility.
In addition to performing an upgrade using the test harness, you can also perform the upgrade via the command line. You will be shown the same GUI confirmation window.
To upgrade your PySimpleGUI release to the latest on GitHub, type this on the command line (for windows... for LinuxMac the command is python3)
You will see this confirmation window:
You'll see the same red window shown in the previous post when the upgrade is successful.
This is an exciting development made possible by my friend Ruud who has quietly helped this project countless times in the past. You can thank Ruud for the entire 2.7 support for example.
Now he's bringing us an incredible capability, instant gratification. No more waiting on PyPI for your fix to be officially released. You can get the latest GitHub just as easily as running a pip install.
HUGE.... this is a HUGE thing.
PySimpleGUI 2020-03-06T02:40:55Z
PyCon miniShizuoka - Speaker Deck and Supporting Materials
PySimpleGUI has managed to slip onto a presenter's screen at a PyCon recently. In Japan a couple of weeks ago a fantastic presentation was given that discussed creating desktop applications in Python.
The presenter's deck is here:
https://speakerdeck.com/okajun35/pythondedesukutotupuapuriwojian-dan-nizuo-rufang-fa
Here is the GitHub that matches:
https://github.com/okajun35/for_pycon_shizu
@okajun35 Jun okazaki has been a huge supporter of PySimpleGUI in Japan. Jun's single-handedly responsible for introducing Japan to PySimpleGUI. There has been months of Twitter activity leading up to the PyCon, hosting evens where PySimpleGUI is being taught to Python newcomers and club members.
A HUGE THANK YOU to Jun
for all of the help, support and words of encouragement over the many months.
PySimpleGUI 2020-03-06T11:40:05Z
New Date Chooser Soon
The more compact look cuts off the text on "Wed".
Finally getting around to looking at re-implementing the Calendar Chooser window so that it's a pure PySimpleGUI implementation instead one directly coded in tkinter. This will enable it to be used on any of the ports, in theory.
It still has a ways to go. It's already taking shape pretty nicely. It should be a better chooser window since you'll be able to locate it anywhere on the screen. It uses your current theme so that it matches your other windows. And other options will be available such as being able to set which day the week begins on.
It would be nice to be able to ship it with the upcoming PyPI release, but it needs a lot of testing first.
Here is the current date chooser window for comparison
I'm sorry this has been so long in the making, but it's just how it worked out. Soon!!
PySimpleGUI 2020-03-09T17:46:47Z
PySimpleGUI-Widgets - COVID-19 Widget
A new repo was opened and a new PySimpleGUI design pattern is emerging that is for making rain-meter style Widgets using PySimpleGUI.
https://github.com/PySimpleGUI/PySimpleGUI-Widgets
The first one released today is not the most uplifting I'm afraid. Was hoping that the recent Weather Widget would have made it up there first, but I kinda got focused this morning on making this COVID-19 tracking widget.
I kinda "borrowed" a lot from the Weather Widget.
Here are a couple of older ones.
Putting together a template for you to use to make your own Widgets. The idea is to make it so that you can quickly and easily make Widgets by modifying a template. The Setup Window will be standardized and extendable. The standard settings are for things like alpha-channel. Then the user can add their own settings to that window. Hopefully you'll be able to make your own Widgets
Better Than Rainmeter?
In many ways these PySimpleGUI Widgets are (maybe) better than Rainmeter. Full disclosure, I've never written a rainmeter widget... but I have written a PySimpleGUI program or two.
With PSG Widgets each widget is completely standalone. You don't have to run a master program, although nothing stops you from writing a "Widget Launcher" that remembers the widgets you were running and starts them for you.
Another advantage is that they're written in PySimpleGUI, the easiest GUI library I know of. It took about 4 hours to get the COVID Widget written, started with a command line program that processed the Johns Hopkins data and finished with a nicely polished GUI.
PySimpleGUI 2020-03-10T02:37:47Z
COVID Widget Update
What a difference a day makes.... Started on this project this morning. By tonight it's feeling pretty stable and complete.
The latest code can be found here:
https://github.com/PySimpleGUI/PySimpleGUI-Widgets/blob/master/PSG_Widget_COVID19_Distance.py
It's got a more proper "Settings" window. As soon as it was posted this morning I knew I needed to make it more internationalized. It's great that it works for US locations, but PySimpleGUI users and COVID cases are not located in a single country. So, going worldwide was a must. That also meant displaying metric distances in addition to miles.
So the settings were extended and a more complete settings window was created in the process.
Between this widget and the weather widgets I'm hoping to be able to put together a good Widget Template that will make it trivial for anyone to make these kinds of little utility programs. The template will make things like saving settings built-in so that the programmer doesn't have to do anything to save or recall settings. If no settings file is found, one will be created by pulling up the settings window first.
Hope to have a template done in the next week.
PySimpleGUI 2020-03-13T13:29:41Z
Slow responding, releases....
Sorry things have slowed down over the past week. The C19 outbreak has had a big impact that's been disruptive to PySimpleGUI support.
The release is on the way. I'm struggling with the new documentation. There are fixes I'm adding to hopefully get the docs done soon. Until the docs are done, the release can't go out.
Widgets
Finally added to the widgets in the new Widget Repository.
CPU Cores
The CPU Dashboard that shows the CPU usage of each of your core's
Current Weather
And a weather widget based on an earlier version of this weather widget made by @israel-dryer
COVID-19 Tracker
Trying to whip this one into shape so it can perhaps be the beginning of a template that can be used by anyone to create a widget.
A little more work is needed to make things like the settings window / file be really easy to make additions to as well as supplying a standard group of settings that all widgets or certain types of widgets will have such as alpha, refresh rate, maybe theme color. The code that loads/saves a settings file is part of the widget already.
PySimpleGUI 2020-03-13T21:12:24Z
PySimpleGUI-COVID19 Repo
https://github.com/PySimpleGUI/PySimpleGUI-COVID19
A new GitHub Repository has been set up for COVID-19 tools built using PySimpleGUI. So far there are two with more on the way.
The first one you've seen already, the distance widget.
The second one is a new graphing tool that displays the most recently Johns Hopkins data
It's got a ways to go but is off to a fantastic start.
I've always wanted to make a Tableau style tool using PySimpleGUI and this is a golden opportunity to do just that.
It's important to be able to compare the different counties and regions within countries. A grid of graphs is an excellent way of doing that.
Additional options are being developed now to enable you to choose the countries, and the level of detail. For example, maybe you want to see the graphs for each of the states in the Unites States.
In case it's not apparent to your eyes, the countries that are not taking "draconian measures" all have nearly identical growth curves. They all share that mathematically beautiful, but deadly exponential growth curve. These are turning out to be near perfect curves. Data can be both beautiful and hold a terrible message.
🙏 Please stay safe everyone... these tools are being published as an attempt to help others.
😷 Take care of yourself first. Your employer comes second to you and your family. This is a great time to be reminded of that.
PySimpleGUI 2020-03-14T03:26:03Z
Crash Detection
This is one for the Cookbook or Demo Program
If you run any PySimpleGUI programs as a widget, or background task or in the system tray, you're eventually going to hit a situation where your window closes because it's crashed. These types of windows are generally launched so that they do not have a console.
So what are you supposed to do to detect when there's a crash or problem in your script? After all your stdout is missing unless you have an output element.
A Error Catch Technique
Lately I've been running the PySimpleGUI Issues Watcher system tray program and it would periodically crash with the assumption being it's from a "bad read" of the GitHub issues. A request timed out or some other networking type of error.
Place a try block around your entire Event Loop
Use a combination of the Debug Window and a popup_error
call
You need some kind of popup call in order for the Debug Window to stay open as it's a non-blocking call.
Continued use of GUI
Note that the GUI is mostly likely still fuctional and capable of showing new popup windows and even the Debug Window will work. This is because the errors are most over in the user code (sorry to make that kind of statement, but it's generally true, my user code included). Because the PySimpleGUI Package itself isn't in a bad state or injured in some way, it's perfectly save to continue on using the GUI calls to display the error information.
Here's a nice template you can follow:
import traceback
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-'), sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
try:
while True: # Event Loop
event, values = window.read()
window.bad()
print(event, values)
if event in (None, 'Exit'):
break
if event == 'Go':
window['-OUT-'].update(values['-IN-'])
window.close()
except Exception as e:
tb = traceback.format_exc()
sg.Print(f'An error happened. Here is the info:', e, tb)
sg.popup_error(f'AN EXCEPTION OCCURRED!', e, tb)
When an error occurs, in this case it'll trip up at the window.bad()
call.
These 2 windows will appear:
Debug Print Output
And the debug window in case you want to copy something from the traceback.
PySimpleGUI 2020-03-20T09:51:10Z
Back to "normal" PySimpleGUI coding soon...promise
It's been 11 days since the post of the COVID utilities started. I'm getting close to finishing up the feature set I've been working towards. It's the grid of graphs that's been the program I've been spending all my time on.
My apologies if you've been waiting on the release. Everyone is dealing with the disaster in their own way. For me I needed to get this data displayed, for my own personal consumption. When there's a lack of information that I can easily consume and a lack of where things are headed, I begin to feel really uneasy. Thus, the time spent on making tools that fill that need for me.
The last piece of the program is the "future-cast". I've been holding back a bit on releasing it or integrating it into the released code as it's speculation. But I think now it's helpful to see ONE possible path ahead, even if it's a rather grim one.
To be clear, what I'm talking about is displaying the graph of where things stand in the next 10 to 30 days. I don't know what else to use to plan than those numbers. Example... the USA graph today:
And here's what it looks like if you run things forward 20 days using a growth rate of 1.27X per day
Anyway, I'll be back on the documentation and code effort to address the issues you are facing in your code really soon. I'm sorry for the detour from the primary development.
PySimpleGUI 2020-03-21T11:15:48Z
Compressing Complex Layouts (Use Shortcuts and "User Defined Elements")
Will eventually add this to the cookbook, but for now, here's a tip.
The more PySimpleGUI application code I write, the more I learn about techniques that may be helpful to others. It's one of the reasons behind writing as many as possible.
A huge advantage that PySimpleGUI has over other GUIs is the ability to define a window's layout in a single screen of code. 1 line of code = 1 line of GUI display helps achieve that. Putting Element parameters on separate lines, adding extra whitespace to the GUI layout and repeating long lists of element parameters work against you, not for you.
Shortcuts
Once you understand your palette of Elements you can place in your layout definition you can begin to compress your layout code by using the shortened names of Elements. Less characters = more readable code = simpler code = happier developers.
The top 3 most frequently used elements are likely Text
, InputText
, Button
. These can be shorted to T
, B
, I
. There are other aliases you can use for these if you don't want to make them that short. InputText
can be written also as Input
and In
.
The most common Elements have shortcuts... use them if you can. Checkbox
can be CBox
, Check
, CB
. You get the idea.
Example - A recently coded Settings window
This "settings" window
was created using this layout definition
layout = [[sg.T('Color Theme')],
[sg.Combo(sg.theme_list(), default_value=settings.get('theme', DEFAULT_SETTINGS['theme']), size=(20,20), key='-THEME-' )],
[sg.T('Display Rows', size=(15,1), justification='r'), sg.In(settings.get('rows',''), size=(4,1), key='-ROWS-' )],
[sg.T('Display Cols', size=(15,1), justification='r'), sg.In(settings.get('cols',''), size=(4,1), key='-COLS-' )],
[sg.CBox('Autoscale Graphs', default=settings.get('autoscale',True), key='-AUTOSCALE-'), sg.T('Max Graph Value'), sg.In(settings.get('graphmax',''), size=(6,1), key='-GRAPH MAX-')],
[sg.B('Ok', border_width=0, bind_return_key=True), sg.B('Cancel', border_width=0)],]
window = sg.Window('Settings', layout, keep_on_top=True, border_depth=0)
The layout has a number of lengthy default values which makes the lines long. Using the shortcuts for the Elements helps shorten every line.
Some of the lines are long and don't wrap well on GitHub. Here's how they look in PyCharm on my system
For readability it is helpful sometimes to add a line break after elements that have a lot of parameters. This makes it easier to locate the elements since they'll be at the start of the line, but does add to the vertical length.
This row from the window is lengthy in the code:
Adding line breaks after each element helps make that row more readable in the code at the expense of a couple of extra lines.
User Defined Elements
This is covered in a number of places in the documentation and you'll find it in Demo Programs. When you find yourself copying and pasting something like a Text element that has a lot of parameters, consider creating your own element by simply using a function.
Let's say you've got a layout that uses text elements that look like this:
[sg.Text('Description', font=('Arial', 12), pad=(10, 0), background_color=BG_COLOR, text_color=TXT_COLOR, key='-DESCRIPTION-'), sg.Text('Status', font=('Arial', 12), pad=(10, 0), background_color=BG_COLOR, text_color=TXT_COLOR, key='-STATUS-')]
If you've got 20 of these in your layout it's going to quickly fill your screen with these elements alone. You can make your own Text element with these settings by creating a function.
def MyText(text, key):
return sg.Text(text, font=('Arial', 12), pad=(10, 0), background_color=BG_COLOR, text_color=TXT_COLOR, key=key)
You can then use your function in your layout in place of where you would put the Text
elements. Now the row definition that consumed a lot of space in your layout simplifies down to:
PySimpleGUI 2020-03-25T00:46:23Z
4.17.0 PySimpleGUI 24-Mar-2020
The "it's been a minute" release
Improved DocStrings and documentation!
Upgrade utility
"Printing" directly to Multiline
-
New upgrade utility to upgrade your installed package using GitHub version
-
Can invoke from command line. Run
python -m PySimpleGUI.PySimpleGUI upgrade
-
The test harness GUI has an upgrade button
-
-
Multiline.print - Add multiline element to the front of any print statement. Also supports color output
-
Debug informmation like path and version displayed in test harness GUI
-
Added back the TRANSPARENT_BUTTON variable until can find a better way to deprecate
-
All elements were losing padding when made invisible. Fixed
-
Image.update - fixed crash due to not checking for type before getting size
-
Image.update_animation_no_buffering - playback GIF animations of any length
-
Graph element - Fixed divide by zero error in convert function
-
TabGroup will now autonumber keys if none specified
-
Measuring strings more accurately during layout
-
Using specific font for measurement
-
Used to compute TTK button height
-
Used to compute Slider length
-
Used to compute header widths in Tables, Trees
-
Used to compute column widths in Tables, Trees
-
Used to compute row heights in Tables
-
-
Removed padx from row frames. Was using window's margins. Now padx & pady = 0
-
Added no_titlebar to one line progress meter
-
popup_notify - Creates a "notification window" that is like the System Tray Message window
-
shell_with_animation - launch a shell command that runs while an animated GIF is shown
-
Fixed problem with debugger not working after the recent close parameter addition to Window.read
I'm sorry this took SO long to get out. There were over 600 changes and the world has been on fire for a while, so it's taken a little longer than usual, but it's DONE.
I'll write up more info on the specifics of some of these.
A HUGE thank you is owed to @nngogol and @salabim.
@nngogol hit another homerun in the docstrings department and making the documentation look even better.
@salabim brought us the upgrade from GitHub feature that's going to REALLY help get fixed out to people in a much better way.
Now that documentation can be generated again and I'm no longer stuck working on the C19 graphing program it should break apart the logjam some and get the releases rolling out easier / faster. There have been a number of things this months that have thrown the timing off. So, I'm sorry if you're waiting on a fix or a feature. Hopefully will be able to focus back on the core code once again as well as making progress on the Cookbook update.
PySimpleGUI 2020-03-26T13:49:31Z
4.18.0 PySimpleGUI 26-Mar-2020
An "Oh F**k" Release - Table column sizes were bad
-
Fixed bug in Table Element's column size computation
-
popup_animated has new title parameter
-
Checkbox - update can change the text
I broke the column sizes for Tables. DOH!
Really needed to jam this release out so made the changes, rolled in the other 2 features and popped it up to PyPI.
Hopefully the gates are open such that lots of releases can go out as there is a lot of code that's been waiting to get posted. This has been a good start.
PySimpleGUI 2020-03-28T18:18:44Z
popup_get_date
The long awaited replacement for the date-chooser is ready for testing. For the time being it's being released as a popup. If you want to immediately put it to use, you can integrate it into your code prior to the change of the date chooser button.
I should be able to get this integrated into the code as a replacement for the date chooser soon, maybe another day tops. Certainly by the end of the weekend. In the meantime I urge you to give it a try.
Here's the call definition:
def popup_get_date(start_mon, start_day, start_year, begin_at_sunday_plus=0, location=(None, None)):
"""
Display a calendar window, get the user's choice, return as a tuple (mon, day, year)
:param start_mon: The starting month
:type start_mon: int
:param start_day: The starting day - optional. Set to 0 if no date to be chosen at start
:type start_day: int
:param start_year: The starting year
:type start_year: int
:param begin_at_sunday_plus: Determines the left-most day in the display. 0=sunday, 1=monday, etc
:type begin_at_sunday_plus: int
:return: Tuple containing (month, day, year) of chosen date or None if was cancelled
:rtype: None or (int, int, int)
"""
If the user cancels or clicks OK prior to selecting an actual date, then None
will be returned. Otherwise it returns a tuple (month, day, year).
The input parameters are the starting month, day and year. If you set the day to 0, then no specific date will be chosen. Only the month/year are shown. You can change which day of the week is shown in the left-most column by setting the parameter begin_at_sunday_plus
to a non-zero value. 0 =Sunday, 1=Monday, etc. Default is Sunday (0)
The default theme
PySimpleGUI 2020-03-28T20:31:54Z
popup_get_date
Code
A 3D printer capable of printing a 3D printer.
That's how it's felt building this new date_chooser code. At the moment it's a popup, but it'll get added into the button soon. A few more options will get added too.
I'm quite sure the code could be shorter and optimized better. I wouldn't call it one the better PySimpleGUI programs.
The important thing about this code is that anyone is capable of writing it. There are no PySimpleGUI internals being accessed. It's user-level PySimpleGUI code. When it's hooked in as the replacement for the current date chooser button, then it'll need to be tighter integrated, but at the moment, it's plain user code.
If you really really wanted or needed one of these for your application, you can write it yourself. This code would "mimic" the Data Chooser button easily. To do so all that has to happen is when the date is chosen, you call update
on your target input field.
Here's the source code. I'll make it into a demo program too.
Sorry about the lack of comments. I'm usually pretty good about that, but I guess I was too focused on getting it working on this one.
import PySimpleGUI as sg
import calendar as cal
import datetime
import itertools
def popup_get_date(start_mon, start_day, start_year, begin_at_sunday_plus):
"""
Display a calendar window, get the user's choice, return as a tuple (mon, day, year)
:param start_mon: The starting month
:type start_mon: int
:param start_day: The starting day - optional. Set to 0 if no date to be chosen at start
:type start_day: int
:param start_year: The starting year
:type start_year: int
:param begin_at_sunday_plus: Determines the left-most day in the display. 0=sunday, 1=monday, etc
:type begin_at_sunday_plus: int
:return: Tuple containing (month, day, year) of chosen date or None if was cancelled
:rtype: None or (int, int, int)
"""
day_font = 'TkFixedFont 8'
mon_year_font = 'TkFixedFont 10'
arrow_font = 'TkFixedFont 8'
def update_days(window, month, year, begin_at_sunday_plus):
[window[(week, day)].update('') for day in range(7) for week in range(6)]
weeks = cal.monthcalendar(year, month)
month_days = list(itertools.chain.from_iterable([[0 for _ in range(8 - begin_at_sunday_plus)]] + weeks))
if month_days[6] == 0:
month_days = month_days[7:]
if month_days[6] == 0:
month_days = month_days[7:]
for i, day in enumerate(month_days):
offset = i
if offset >= 6 * 7:
break
window[(offset // 7, offset % 7)].update(str(day) if day else '')
def make_days_layout():
days_layout = []
for week in range(6):
row = []
for day in range(7):
row.append(sg.T('', size=(4, 1), justification='c', font=day_font, key=(week, day), enable_events=True, pad=(0, 0)))
days_layout.append(row)
return days_layout
cur_month = start_mon
cur_year = start_year
cur_day = start_day
days_layout = make_days_layout()
layout = [[sg.B('◄', font=arrow_font, border_width=0, key='-MON-DOWN-'),
sg.Text('{} {}'.format(cal.month_name[cur_month], cur_year), size=(16,1), justification='c', font=mon_year_font, key='-MON-YEAR-'),
sg.B('►', font=arrow_font,border_width=0, key='-MON-UP-')]]
layout += [[sg.Col([[sg.T(cal.day_abbr[i - (8 - begin_at_sunday_plus) % 7], size=(4,1), font=day_font, background_color=sg.theme_text_color(), text_color=sg.theme_background_color(), pad=(0,0)) for i in range(7)]], background_color=sg.theme_text_color(), pad=(0,0))]]
layout += days_layout
layout += [[sg.Button('Ok', border_width=0,font='TkFixedFont 8'), sg.Button('Cancel',border_width=0, font='TkFixedFont 8')]]
window = sg.Window('Window Title', layout, no_titlebar=True, grab_anywhere=True, keep_on_top=True, font='TkFixedFont 12', use_default_focus=False, finalize=True)
update_days(window, cur_month, cur_year, begin_at_sunday_plus)
prev_choice = chosen_mon_day_year = None
if cur_day:
chosen_mon_day_year = cur_month, cur_day, cur_year
for week in range(6):
for day in range(7):
if window[(week,day)].DisplayText == str(cur_day):
window[(week,day)].update(background_color=sg.theme_text_color(), text_color=sg.theme_background_color())
prev_choice = (week,day)
break
while True: # Event Loop
event, values = window.read()
if event in (None, 'Cancel'):
chosen_mon_day_year = None
break
if event == 'Ok':
break
if event in ('-MON-UP-', '-MON-DOWN-'):
cur_month += 1 if event == '-MON-UP-' else -1
if cur_month > 12:
cur_month = 1
cur_year += 1
elif cur_month < 1:
cur_month = 12
cur_year -= 1
window['-MON-YEAR-'].update('{} {}'.format(cal.month_name[cur_month], cur_year))
update_days(window, cur_month, cur_year, begin_at_sunday_plus)
if prev_choice:
window[prev_choice].update(background_color=sg.theme_background_color(), text_color=sg.theme_text_color())
elif type(event) is tuple:
if window[event].DisplayText != "":
chosen_mon_day_year = cur_month, int(window[event].DisplayText), cur_year
if prev_choice:
window[prev_choice].update(background_color=sg.theme_background_color(), text_color=sg.theme_text_color())
window[event].update(background_color=sg.theme_text_color(), text_color=sg.theme_background_color())
prev_choice = event
window.close()
return chosen_mon_day_year
if __name__ == '__main__':
sg.theme('Dark Red')
now = datetime.datetime.now()
cur_month, cur_day, cur_year = now.month, now.day, now.year
print(popup_get_date(cur_month, cur_day, cur_year, 0)) # choose 0 for day to show only month and year
PySimpleGUI 2020-03-30T14:28:30Z
CalendarButton
- NEW implementation
Finally completed the first pass of the calendar chooser replacement. It's looking great. The localization stuff was more difficult than I thought and it may still have some issues.
So, please TRY it with your code to see if it still operates as expected.
After the initial test, expand to use the new features that many of your have asked for such as being able to re-locate the window and start the week on a particular day.
Here is the Test Harness that was checked in as a demo program (replaced the existing Demo_Calendar.py file)
#!/usr/bin/env python
import PySimpleGUI as sg
"""
Simple test harness to demonstate how to use the CalendarButton and the get date popup
"""
layout = [[sg.Text('Date Chooser Test Harness', key='-TXT-')],
[sg.Input(key='-IN-', size=(20,1)), sg.CalendarButton('Cal US No Buttons Location (0,0)', close_when_date_chosen=True, target='-IN-', location=(0,0))],
[sg.Input(key='-IN3-', size=(20,1)), sg.CalendarButton('Cal US Monday', close_when_date_chosen=False, target='-IN3-', begin_at_sunday_plus=1)],
[sg.Input(key='-IN2-', size=(20,1)), sg.CalendarButton('Cal German Feb 2020', target='-IN2-', default_date_m_d_y=(2,None,2020), locale='de_DE', begin_at_sunday_plus=1 )],
[sg.Input(key='-IN4-', size=(20,1)), sg.CalendarButton('Cal Format %m-%d Jan 2020', target='-IN4-', format='%m-%d', default_date_m_d_y=(1,None,2020), )],
[sg.Button('Read'), sg.Button('Date Popup'), sg.Exit()]]
window = sg.Window('window', layout)
while True:
event, values = window.read()
print(event, values)
if event in (None, 'Exit'):
break
elif event == 'Date Popup':
sg.popup('You chose:', sg.popup_get_date())
window.close()
The test creates this window:
The popup for each button will be a little different from each other.
PySimpleGUI 2020-03-31T13:44:47Z
Calendar still being worked (locale issues)
Sorry that the calendar code is still being worked on. The GitHub code is struggling with the locale settings and is causing problems on Raspberry Pi's too. It's getting there but not quite there....
PySimpleGUI 2020-04-02T17:31:49Z
Calendar Done (enough?)
Calling the new calendar (popup and button) done. (again... almost)
It's not done until the documentation is done, but the functionality is done. The doc strings are all done. It's just not released to PyPI and readme file yet.
Besides looking a LOT LOT LOT better than the old calendar chooser, it's got expanded capabilities as well over the original date chooser:
-
Can jump navigate by year in addition to by months
-
With / without titlebar
-
With / without ok/cancel buttons
-
Color theme follows user's settings
-
Can set location of the window
-
Can set title of window
-
Can start at a specific date or a specific month but no specific day
-
Locale is used only to get the day abbreviations and even then it's not always what you want... which is why there is also...
-
User can specify list of months
-
User can specify list of day abbreviations
All of these awesome things, but best feature of all... it's 100% PySimpleGUI based. It is literally a PySimpleGUI application window. Nothing special about it. Any user could have made this window. That's good news to anyone that wants to specialize it further for their specific application. It means you can run the window entirely within user code.
Will port to Qt once a little runtime is on this one in tkinter and has had no changes for a few days.
PySimpleGUI 2020-04-02T17:35:57Z
Cookbook Updates
Continuing on in the Cookbook updates. They've been lagging, like eveyine else. But happy to report making new releases of the cookbook now.
Added a few new Recipes including:
-
Highly Responsive Inputs (
enable_events
parameter to elements) -
Input validation
Upcoming section is on "printing" which will cover the new Multiline.print
and multi-colored output.
PySimpleGUI 2020-04-04T01:03:21Z
Cookbook - "Printing"
New printing section added to the Cookbook. https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-printing
It discusses the 3 different ways you can use a "print-like" function in PySimpleGUI. Everything from a plain print, re-routed to an Output
element, to the latest multi-colored text output using the Muiltiline.print
method.
http://Cookbook.PySimpleGUI.org
Note that printing to Multiline edits using 4.18.0 from PyPI does not autoscroll. When you print, it gets added to the end, but the element doesn't move cursor to the end.
The GitHub version corrects this and also adds an autoscroll parameter to the Multline.print
and the Print
calls. It defaults to True
so you shouldn't normally need to touch it.
PySimpleGUI 2020-04-04T14:48:41Z
0.32.0 PySimpleGUIQt 4-Apr-2020
The "Jesus it's been way too long since a release" release
Print to Multiline
-
Listbox.update fix
-
Added Graph.change_coordinates
-
Added Image.Widget
-
Return correct value when Comboxbox has manual data entered
-
Multiline.print - new printing capabilities
-
Multiline move cursor to end
-
Scrollable columns
-
Added Listbox.get
-
Fix for visible ignored in Text Element
-
Window.read - close parameter (YES! Single line GUIs again)
-
Multiline readonly parm on update
-
Print fixed sep char to act line normal print
-
Print (Multiline) added autoscroll parm
I'm sorry PySimpleGUIQt users that it's been so long between releases.
Trying to get out the door the code that's been sitting waiting to be shipped. The release machinery is getting cranked back up again so that I can releases out more frequently.
Next up are changes that PySimpleGUIWeb users are waiting on.... along with more Recipes.
Enjoy the printing features in this release!!!! Oh, and finally scrollable columns.
PySimpleGUI 2020-04-05T19:46:44Z
New Demo / Recipe - A Settings File
Have been making lots of Widgets including working on a generalized "Rainmeter-style" Widgets. One thing they have in common is a "settings" file.
It's been added to the Cookbook as a new Recipe:
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-save-and-load-program-settings
It may be a little large for the CookBook, but it's only 100 lines of code that's very reasonable to ssee
Seems like something a number of user programs could benefit from. So, I made a generalized demo that any program can use. It's JSON based so it doesn't require a PySimpleGUI program be used to utilize it, but if you want to use a GUI to display or edit the settings, you easily can with this short, 99-line program.
It started as a "Recipe" for the cookbook, but kinda got a little large. Got it down to 99 lines of text (63 lines of actual code). The may be on the edge of being too long for a Recipe. I'll add it and see.
The code is posted on Trinket where you can immediately run it:
https://pysimplegui.trinket.io/demo-programs#/demo-programs/settings-file
Here's the entire program in case you're wondering how it's done...
import PySimpleGUI as sg
from json import (load as jsonload, dump as jsondump)
from os import path
"""
A simple "settings" implementation. Load/Edit/Save settings for your programs
Uses json file format which makes it trivial to integrate into a Python program. If you can
put your data into a dictionary, you can save it as a settings file.
Note that it attempts to use a lookup dictionary to convert from the settings file to keys used in
your settings window. Some element's "update" methods may not work correctly for some elements.
Copyright 2020 PySimpleGUI.com
Licensed under LGPL-3
"""
SETTINGS_FILE = path.join(path.dirname(__file__), r'settings_file.cfg')
DEFAULT_SETTINGS = {'max_users': 10, 'user_data_folder': None , 'theme': sg.theme(), 'zipcode' : '94102'}
# "Map" from the settings dictionary keys to the window's element keys
SETTINGS_KEYS_TO_ELEMENT_KEYS = {'max_users': '-MAX USERS-', 'user_data_folder': '-USER FOLDER-' , 'theme': '-THEME-', 'zipcode' : '-ZIPCODE-'}
########################################## Load/Save Settings File ##########################################
def load_settings(settings_file, default_settings):
try:
with open(settings_file, 'r') as f:
settings = jsonload(f)
except Exception as e:
sg.popup_quick_message(f'exception {e}', 'No settings file found... will create one for you', keep_on_top=True, background_color='red', text_color='white')
settings = default_settings
save_settings(settings_file, settings, None)
return settings
def save_settings(settings_file, settings, values):
if values: # if there are stuff specified by another window, fill in those values
for key in SETTINGS_KEYS_TO_ELEMENT_KEYS: # update window with the values read from settings file
try:
settings[key] = values[SETTINGS_KEYS_TO_ELEMENT_KEYS[key]]
except Exception as e:
print(f'Problem updating settings from window values. Key = {key}')
with open(settings_file, 'w') as f:
jsondump(settings, f)
sg.popup('Settings saved')
########################################## Make a settings window ##########################################
def create_settings_window(settings):
sg.theme(settings['theme'])
def TextLabel(text): return sg.Text(text+':', justification='r', size=(15,1))
layout = [ [sg.Text('Settings', font='Any 15')],
[TextLabel('Max Users'), sg.Input(key='-MAX USERS-')],
[TextLabel('User Folder'),sg.Input(key='-USER FOLDER-'), sg.FolderBrowse(target='-USER FOLDER-')],
[TextLabel('Zipcode'),sg.Input(key='-ZIPCODE-')],
[TextLabel('Theme'),sg.Combo(sg.theme_list(), size=(20, 20), key='-THEME-')],
[sg.Button('Save'), sg.Button('Exit')] ]
window = sg.Window('Settings', layout, keep_on_top=True, finalize=True)
for key in SETTINGS_KEYS_TO_ELEMENT_KEYS: # update window with the values read from settings file
try:
window[SETTINGS_KEYS_TO_ELEMENT_KEYS[key]].update(value=settings[key])
except Exception as e:
print(f'Problem updating PySimpleGUI window from settings. Key = {key}')
return window
########################################## Main Program Window & Event Loop ##########################################
def create_main_window(settings):
sg.theme(settings['theme'])
layout = [[sg.T('This is my main application')],
[sg.T('Add your primary window stuff in here')],
[sg.B('Ok'), sg.B('Exit'), sg.B('Change Settings')]]
return sg.Window('Main Application', layout)
def main():
window, settings = None, load_settings(SETTINGS_FILE, DEFAULT_SETTINGS )
while True: # Event Loop
if window is None:
window = create_main_window(settings)
event, values = window.read()
if event in (None, 'Exit'):
break
if event == 'Change Settings':
event, values = create_settings_window(settings).read(close=True)
if event == 'Save':
window.close()
window = None
save_settings(SETTINGS_FILE, settings, values)
window.close()
main()
PySimpleGUI 2020-04-07T16:38:47Z
Hold off on PySimpleGUI GitHub Upgrades For a Couple Days
I blew it.
In my haste to get something released to do Scrolling Columns, a fix I've been trying to get into the code for a very very long time, I released code before thoroughly testing it.
There's been a lot of code coming my way as of late. Some of it I paid for and I let my guard down at the same time. I probably did a bad merge or who knows what happened. It actually doesn't matter in the end as the responsibility is 100% mine. I've been drowning in code lately is my only excuse and it's a poor excuse anyway. I know better. There's only so much time and I tried doing things a different way for a couple of weeks, knowing the risks. I'm sorry if you're one that's paying the cost.
I need a day or two to straighten it all out and get back onto a path that I feel comfortable with. I'm really sorry if you upgraded recently from GitHub and it's causing problems. They're the top priority to get fixed. Hopefully today the remaining problems that have popped up since the last release will stop.
PySimpleGUI 2020-04-09T15:26:00Z
GitHub seems OK now.... 4.18.0.19
I believe the current version 4.18.0.19. It literally drives me crazy when there's a serious problem with my code. Bug is filed -> 🤦♂️ first reaction sometimes.
Speaking of crazy. It's a pretty crazy time right now. There's no doubt it's had an impact. I've let that show and if it's impacted you, I'm sorry about that. Really.
This project is about helping people. Everything about it is meant to be that way. The developer is at the center of this package. It's in the documentation and it's meant in more ways than only the API calls and architecture.
To all the other human beings out there... let's build some nice things. Have some fun. It's supposed to be fun (also in the docs 😉) is it's time for me to read the docs for a change.
As for GitHub...there is still a lot of testing that needs to happen so not saying it's perfect code just yet.
PySimpleGUI 2020-04-13T14:29:20Z
4.18.1 PySimpleGUI 12-Apr-2020
Emergency patch - f-string managed to get into the code resulting crashes on 3.5 systems (Pi's for example)
4.18.2 PySimpleGUI 12-Apr-2020
The Epic Fail release.... import error on 3.5 for subprocess.
Jammed out 2 "emergency" releases to PyPI last night. It showed that I clearly did not properly regression test 4.18.0 on my Python 3.4 Raspberry Pi.
An ongoing struggle with pre-3.6 Python interpreters is that they give a syntax error if any f-string is found in the code. It doesn't have to execute the code, it just has to find an f-string anywhere in the file for it to barf. I do make liberal use of f-strings in the Demo programs as they're meant to 3.6+ machines generally speaking. But the main PySimpleGUI files cannot contain any f-strings due to these 3.4 environments.
I'm sorry if you got nailed after upgrading your Pi. It should be fine now that 4.18.2 was released.
PySimpleGUI 2020-04-13T17:26:38Z
Demo_System_Tray_Reminder.py
- A New Demo Program
A new demo program was posted that works on the tkinter, Wx and Qt ports. It shows a reminder popup window repeating every specified number of minutes. Maybe you need to get up and stretch every hour. Use this program to remind yourself to get up once an hour.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_System_Tray_Reminder.py
For the tkinter port, system tray icons appear as icons on the desktop (sorta).
PySimpleGUI 2020-04-14T08:44:25Z
Twitter Announcements
A couple of items that are not related.
There is an @PySimpleGUI account on Twitter if you care to see some of the announcements made there. It's been a good source of information about what other people are building at well. I'll add the Twitter info to the documentation as another place to get PySimpleGUI information. It's been a fun way to connect with the world of users.
Support - StackOverflow, Reddit, etc
While the official PySimpleGUI docs and the sub-Reddit sidebar have been abundantly clear that official "support" for PySimpleGUI will be provided on this GitHub only, there has been some not-so-secretly help given in other locations on the net. It's difficult to watch and hear about people struggling no matter the source, so I've tried to monitor multiple locations of problem posts.
But, time is a limited resource and the reasons behind a single location for support have not changed. You will get higher quality service here, honest. Having a record, in a single location, of bug reports and questions is a good thing too.
This project is being executed as a commercial venture. Other products don't have support engineers that hang out on StackOverflow and answer questions. They generally have a bug-tracker built into their company's site that's used exclusively.
I mistakenly thought that helping on SO while also providing guidance that additional/more thorough support was available here on GitHub would have a positive outcome and change behaviors so that more people come here instead of posting there. I was wrong. It hasn't worked, so I need to stop trying this failed experiment.
I won't bore you with the details of why it's better to get support here. You'll find it in the documentation if you're curious. I would say the biggest frustration is the guidance provided is sometimes incorrect and is often a wild-ass guess at best.
It seems like people are more interested in responding than responding with a correct answer. I can't continue to try and fix these answers by correcting mistakes. If someone's hellbent on posting on SO and going with whatever is posted as a reply, then I've got to be OK with that and move on. So, that's what's happening.
Sorry for the long post. It felt necessary to speak up/explain rather than simply disappear.
PySimpleGUI 2020-04-14T17:34:44Z
John Conway (and The Game of Life)
I hope everyone is staying safe and is not experiencing too much loss. Today COVID-19 took another large number of people from us. Among those was Mathematician John Conway, inventor of the inspiring "Game of Life".
https://www.princeton.edu/news/2020/04/14/mathematician-john-horton-conway-magical-genius-known-inventing-game-life-dies-age
If you want to play around with a PySimpleGUI implementation, you can use the program from the Demo Programs area:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Conways_Game_of_Life.py
You can also run it online using Trinket:
https://pysimplegui.trinket.io/demo-programs#/games/conways-game-of-life
Everyone has their own personal tragedies and difficult reactions to hearing of losses. This was a particularly difficult one to hear about.
Stay safe everyone! Hug your kids (despite being cooped up with them for weeks).
PySimpleGUI 2020-04-15T01:35:44Z
0.37.0 PySimpleGUIWeb 14-Apr-2020
Catching up to latest Remi releases.
-
NO LONGER ADDING \n TO MULTILINE, MULTILINE_OUTPUT UPDATES
- This may cause some of your problems. Sorry about this, but it's the right thing to do so that prints work correctly
-
Multiline.print capability
-
MultilineOutput.print capability
-
Fix for MultilineOutput not autoscrolling
-
Fix for image update flicker
-
Printing sep char fixed
-
Fix for extra Tab
-
Replaced SvgGroup with SvgSubcontainer (Requires Remi 2020.3.10)
-
BIG Thank You owed to Remi creator Davide (for this and many other releases too)
It's been a LONG time, or so it feels, since a PySimpleGUIWeb release was sent to PyPI
A word of warning on this release.... You will need to modify your call to MultilineOutput.update to add a newline as the update call will no longer add one on for you. This was a painful change to make because it breaks the backwards compatibility rules. It has been incorrectly adding a newline for a very long time. Now that a "real print" method has been added to Multiline elements, it was a required change or else there will be a blank line added after every print.
The Graph drawing is FAST! Check out the ball demo and you'll see what I mean.
There may be another Web release coming later this week.
PySimpleGUI 2020-04-15T13:02:01Z @jason990420 Please open an issue if you believe there's a problem rather than adding something in the announcements. The link I provided to Trinket works when I just tried it.
https://pysimplegui.trinket.io/demo-programs#/games/conways-game-of-life
salabim 2020-04-15T13:08:11Z I just tried it on Windows and I can confirm it works perfectly!
On Wed, 15 Apr 2020, 15:02 PySimpleGUI, notifications@github.com wrote:
@jason990420 https://github.com/jason990420 Please open an issue if you believe there's a problem rather than adding something in the announcements. The link I provided to Trinket works when I just tried it.
https://pysimplegui.trinket.io/demo-programs#/games/conways-game-of-life
[image: image] https://user-images.githubusercontent.com/46163555/79339970-afd1b700-7ef7-11ea-8d77-acd2754f84f1.png
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/PySimpleGUI/PySimpleGUI/issues/142#issuecomment-614025817, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHHWWC5BSKB2MZVSFQPCKFDRMWV5ZANCNFSM4FTWUH7A .
PySimpleGUI 2020-04-15T13:14:12Z Wow, thank you! Did not expect that verification!
Since I just released PySimpleGUIWeb last night I thought I would give that a show too. I changed the import and miracle of miracles, it ran...
There may be an issue with the slider changing the speed properly after starting up, but the basics of it worked, and it seems to be running faster than the tkinter version. When I spoke with Davide (of Remi fame) yesterday, he had said he did a lot of work to make the drawing routines fast and it really shows! I'm kinda stunned it worked without any modifications.
PySimpleGUI 2020-04-15T19:23:44Z
A"Moving Tribute" to John Conway
I want to share this amazing bit of artwork by Randall Monroe of XKCD. It's such a beautifully simple tribute. Says so much by using John's own creation. Art takes on many forms. It's a great time to appreciate simple beauty.
PySimpleGUI 2020-04-17T01:44:16Z
Sudoku - Ready for your AI algorithm
OK, so maybe my 1-line Sudoku program got a little out of hand and ballooned up to 85 lines
First you start with a board that has some % of the cells not visible.
At any point you can click the "Check" button and it'll color code things. If you've got a square bad, it's read. If you haven't filled in a number, it's yellow.
If you give up you can click "Solve" and stat a new game.
The point of building out the rest of the program is to have it ready for people ready to try out different AI algorithms.
I'll add a comment at the locations you can slip your algorithms.
You'll find this code in both the Demo Programs area
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Sudoku.py
as well as on Trinket.
https://pysimplegui.trinket.io/demo-programs#/games/sudoku
The "Published" Trinket version is here:
https://pysimplegui.trinket.io/sites/sudoku
The board creation software (that computed the numbers to place in the squares) was created by Morvan Zhou and is now a part of the demo.
https://github.com/MorvanZhou/sudoku
Thanks Morvan!!
His algorithm was one of the most compact, easy to drop in of any of them.
PySimpleGUI 2020-04-24T12:36:09Z
Recording Day - Sorry for the delays
I'm really sorry development ground to a halt over the past week as I put together another video.
This one is a comprehensive, cover it all, video. It's a lecture with 40 pages of notes. I started recording last night and realized that my idea of a 30 minute single video was not going to happen when I was at the 10 minute mark while on page 4.
I really want to get this recorded and released today. The lecture notes are more or less a mini-textbook of sorts. What I can't do is read the damned thing to you which means a different set of "speaking notes."
Anyway, soon! Promise. There's a lot to get through in order to get everything covered and it feels like it all needs covering so that the existing videos are replaced in a single shot.
I have not yet determined if it will be busted up into multiple videos or if an "index" will be supplied in the comments as I first had planned. I'm still hoping that it'll be 1 video with an index/table of contents in the description.
It's a little like teach all of tkinter in a single sitting, including the history and other non-technical aspects of the project.
I appreciate everyone's patience as I work through this. I think it's going to really help a lot of people understand the project in numerous ways, so this week-long investment is worth it.
The notes and the example code will both be released so if I don't touch on every bullet point in the notes it'll be there for you to read. I hope to have my "script notes" done early today so that recording is done today as well.
Thanks for your understanding! Being "brief" isn't my strong-suit. Simple, yes, brief, no.
PySimpleGUI 2020-04-25T02:12:03Z
PySimpleGUI 2020 - Video # 1 Uploaded!
Whew! What a day! High speed internet was installed today, just in time for the videos. My upload speed went from 700 KBits to 40 MBits. Now it won't take days per video to upload!!
The first video is rather lengthy at 48 minutes, but I want this series to cover everything, so I started from nothing. I just barely started to show code at the end.
Here is the rough list of topics in Video 1
-
The who, what, when, where, why, how, how much and how many of PySimpleGUI.
-
IDEs, PyCharm
-
Message Passing versus Event Driven architecture
-
The "PySimpleGUI System"
-
Coding Conventions
-
Coding Tips
-
Popups & One Line Progress Meter
The pace should pick up nicely now that the groundwork is laid.
The Lesson's Text and the demo programs (so far) are in the docs folder:
https://github.com/PySimpleGUI/PySimpleGUI/tree/master/docs
You'll find a PDF file and a .py file. The .py file is likely going to change one ore more times before the next lesson or as lessons are added.
A new lesson is being planned that reviews the programs released under the PySimpleGUI GitHub account such as the Rainmeter-style Widgets & Reddit scraper.
PySimpleGUI 2020-04-26T12:35:09Z
PySimpleGUI 2020 - 5 videos and counting
Today I'll tackling the main portion of the videos.
Your patience with these videos is so appreciated. I'm not good at this. I don't learn from videos so I don't have a lot of time spent looking at good videos. While I did take a week to prepare the "lecture notes" that are followed and I have re-recorded a number of them already, they are still not of high quality.
After seeing the first video stretch into 49 minutes in length, it became immediately apparent that the 2020 series must be broken into chunks like the videos before.
I'm shocked at the number of people watching them already and a little relieved that the responses have been positive. They're done for your benefit, not mine, as I would much rather be coding, but I fully realize that doing "whatever it takes" to get people educated is what has to happen. If that means making videos, then make videos is what I'll do.
Thank you again for being the awesome user community you guys and gals are. None of this would be possible without your support.,
Stay tuned.... it should be a good day for videos!
PySimpleGUI 2020-04-27T14:02:55Z
Show off your Work on GitHub! Add You GUI to Your Project's GitHub Page
Several times a week I take a look at the projects that GitHub shows at the top of this screen.
This morning I see 583 of you out there doing cool things,
One reason I request the screenshots is education. I learn something from everyone that uses PySimpleGUI. Complete beginners are sometimes the best to learn from because "they know no better" and do things differently.
I glance at the code and I can tell many of your are pouring a lot of effort into your GUIs. It's inspiring!
One trend I see is the lack of screenshots in the readme. This is a disappointing thing because you've spent all this time on your GUI and then no one sees it unless they download your project. This is backwards to what it should be. The better way is to place a screenshot in your readme so that when someone visits your page they WANT to download and try your project because it's cool or it looks like something they want to make.
Over the weekend one YouTube video I made shows you how to embed these screenshots into your readme. It's trivial to do. (Honest). I'm not going to trivialize something that's not trivial.
Watch this video:
https://youtu.be/Uby1O7vHEOA
TLDR:
To add a screenshot to your readme that will show up on your GitHub's "homepage"
-
Open and issue in your project
-
Copy and paste an image or drag and drop an image file into the issue
-
GitHub will create something that looks like this in your issue:
![SNAG-0767](https://user-images.githubusercontent.com/46163555/80380522-b2c09600-886d-11ea-92cc-e88e14e0917c.jpg)
-
Copy this above line of text that the Issue created for you
-
Edit your readme.md file in your project
-
Paste the line of text from the Issue in your readme.md
-
The image will now be embedded in your readme and will show up when someone visits your GitHub page
-
You'll look like a rock star!
No GUI is too small to show people. If you've taken the time to post it on GitHub, it's worthy of showing everyone. Trust me here... people LOVE seeing them. There are not many GUIs in the Python world and you are a part of the movement that's changing that!
PySimpleGUI 2020-04-27T14:32:48Z
YouTube Analytics
I'm both stunned and not surprised by the analytics of the YouTube videos. What's stunning and a little sad is that 97.7% of my viewers are male. 😥
It make me wonder if there's something wrong with the videos or wrong with the industry as a whole.
We need more female engineers... that's the truth.
PySimpleGUI 2020-04-27T17:25:37Z
🎵 900 Icky Bugs on the Wall... 900 Icky Bugs.... 🎵
Another numerical threshold crossed recently. 900 bugs have been closed. The project is only about 630 days old. That averages out to about 1.4 bugs a day that are closed.
I think that's a good thing. Note that they are not all bugs! It appears 101 of those are labelled as bugs. 146 were enhancement requests. Definitely happy that more enhancements were added than bug fixes.
PySimpleGUI 2020-04-27T20:17:42Z
YouTube PySimpleGUI 2020 Part 6 "Beautiful Windows"
Just finished the 9th video in the series.
This video was meant to be a "short lesson on making attractive windows". It somehow turned into a 24 minute lesson.
I'm really sorry for the length of these things. I'm doing my best to plan ahead. I've got both the text / slides that accompany the series as well as handwritten notes and yet with all that planning I still fumble around and suck badly enough that the lesson ended being 24 minutes long.
On paper they look like short little tutorials once the camera rolls before I know it 20 minutes have passed.
No one has complained... yet. If I start getting complaints I'll re-record them and try harder to make them crisper. I can't figure out where my plans go so far off course except that it seems to take longer to explain the details behind these concepts than I anticipate.
Thank you for everyone's patience through this whole mess. It's taken significantly longer to write the text and record the videos than I thought. Meanwhile the coding is taking a hit so that I'm not able work on it for a little bit. Soon! I promise.
PySimpleGUI 2020-04-27T23:49:39Z
The Sponsor Button
You may have noticed a "Sponsor" button has appeared on the GitHub page. I wanted to say a couple of words about it.
I've received a number of emails over the past couple of years from individuals and corporations asking how they make a contribution or sponsor the project. While there are recurring costs for the PySimpleGUI project (domains, Trinket, read-the-docs, etc) and consultant costs as well, I've not accepted assistance.
Another offer for financial help arrived last week and maybe it was how the message was phrased that made me realize this time that some users find enjoyment in supporting a project in this way. They experience a feeling of satisfaction at helping the project, and perhaps others may feel the same way.
So, I'm providing a mechanism for those that want to provide support to the project in this way.
It's important to me to make clear that I'm not actively seeking donations. The "Sponsor" button is not there because I expect anything nor am I asking for anything. It feels really uncomfortable that it may be sending the wrong message.
I am truly thankful for every user that shows their gratitude in whatever form that may take. A simple "thank you" message goes a very long ways. I've enjoyed your successes as much as you have.
PySimpleGUI 2020-04-28T17:29:41Z
Why I Like Writing PySimpleGUI Code
These recent videos have triggered a lot of self-reflection.
Programming previously
95% if my programming life was in building stuff, and while my stuff often included a display driver / frame buffer and the ability to draw in it, sometimes for high end graphics, the only time I put stuff on the screen was to test the display. Stuff with displays weren't on normal Operating Systems so it's not like there was a GUI.
I've written a TON of code, usually as part of startups as we built the product, I rarely built stuff for me. The times that I tried GUI programming it always sucked. I've never gotten into the pages of code usually required. I'm not knocking anything here, but damn, there's a LOT of code you need to write to make a GUI program. In short, it wasn't fun. I'm built for fast, fun & easy. It's like candy for me. Clearly I'm capable of some large sh*t too, like PySimpleGUI, but my programming drug is the fast, fun and easy projects.
Enter PySimpleGUI - This time it's personal
Utilities
I have bought a LOT of software. I'm a heavy user of utilities, most commercial or shareware. Most of them are either informative or make me more efficient. My mouse has 19 buttons. I literally move a finger to minimize a window. The mouse never moves to the little symbols on the window:
Same with moving windows or closing them. It's been years since I've grabbed a titlebar. Everything takes time, and it adds up, and heck, I would rather be making stuff than moving a mouse to minimize a window. Some call it efficient, some lazy. I'm ok with Lazy. I don't want to press control+shift+F10 to run a PyCharm program. That's 3 keys. I like just 1... maybe I should move it to my mouse!
Just for me....
There are 3 parts of writing PySimpleGUI programs that are fun.
-
The result is a tool-thingy that I can use every day to be lazier / more efficient or visualize data or ???
-
It's trivial to run rings around traditional GUI programs.
-
Fast, Fun & Easy
Hoping # 2 isn't arrogant. It's not about showing off. In a way it's why I got into and fell in love with Python. I found I could do SO much, with so much less (I NEVER have to type ; { }
to tell the parser something about the code syntax again. Decades of those symbols has left me with C-PTSD. I'm ready for a computer to work for me, damnit. "YOU figure out where a statement ends. YOU'RE supposed to be the smart one" <--- how I feel when forced to write a little C# instead of Python.
The 3rd one is my sugar high. My button that runs the PyCharm program on the screen I press like a rat does a bar to get a food pellet. Write some PySimpleGUI code, run it, see something happen, write a little more, press the food pellet bar.... It's a tad addicting and often a very fast way to work. Before I realize it, not only have I had fun, the result is some little program that I get to use over and over.
Hopefully you're having fun too!
Some of the emails I receive tell me there are lots of you out there enjoying the PySimpleGUI experience.
If you're someone learning and you're struggling to find projects to do, try making yourself some stuff. Be your own customer. Write a utility to make your life better every day on the computer. Make yourself something useful. Doesn't have to be fancy.
Maybe you've got some program that hangs on you from time to time and you're forced to launch task manager to kill it. How about writing a task-killer program that will kill it for you? No need to launch task manager. Just run your code and poof it's gone.
PySimpleGUI 2020-05-02T13:33:35Z
600 GitHub Projects Milestone!
Share your work with the world by showing them your GUI window!
One of the activities I enjoy is checking out what people are making with PySimpleGUI. It's easy to do on GitHub because there's a stat located at the top of the page:
Every couple of days I flip through the projects. MOST do not have a screenshot in their readme. This means when you visit the project, you have no idea that it's got an awesome (usually is) GUI. So few Python programs have GUIs that it's super-refreshing and motivating to see when one does. I think it also increases the odds someone is going to check out your program if they see what it does.
Many times I open an Issue and ask the person to add one, giving them instructions how to do it using GitHub issues.
Maybe I should write a program that will do this for me?? But I've already got too many PySimpleGUI programs to write. -sigh- So little time, so much PySimpleGUI code to write.
Anyway, if you're one of these people that are taking the time to post your code on GitHub, take the TWO minutes it will take you to post a screenshot.
Instructions for posting a screenshot in your readme.md (so it's shown on your homepage)
Lucky for you, I've created as part of the new PySimpleGUI 2020 YouTube series a video specifically on this topic:
https://youtu.be/Uby1O7vHEOA
If you don't want to watch the video, the just do this....
Rather than taking a screenshot and adding it to your repo's files, add it to a GitHub Issue. This is SO much easier (remember, I'm super-lazy).
-
Run your program
-
Use any "snipping" tool to take a screen shot
-
Open an "Issue" for your project
-
Paste the image from your clipboard or drag and drop the image file into the Issue you opened
-
Copy the "code" that was just added to your Issue
-
Click the "Comment" button so that your Issue is saved.
-
Paste the code into your readme.md file in your repo
Example....
I just ran a program that did a popup_get_date
and it created a little date choose window. I used a snipping program (Snagit, ShareX is a free one) and the image is now on my clip board.
Now I press Control + V right here:
I don't see the image because I've not clicked the "preview" tab in the issue, but I do see that GitHub has added this text to my issue:
![image](https://user-images.githubusercontent.com/46163555/80865395-2fc98200-8c57-11ea-988a-36640a0d3acc.png)
You take this code that GitHub made for you and you paste it into your readme.md file. It will embed the image just as it is embedded in this Issue.
PySimpleGUI 2020-05-05T13:19:05Z
4.19.0 PySimpleGUI 5-May-2020
New Date Chooser
Scrollable columns with mousewheel!! (oh please work right!)
WINDOW_CLOSE & WIN_CLOSE events
Long list of stuff!
-
Imported from typing again to get correct docstrings
-
Print and MLine.Print fixed sep char handling
-
New parameter to Muliline.print(autoscroll parameter)
-
New autoscroll parameter added to _print_to_element
-
popup_get_date
-
Complete reworking on Calendar Chooser Button
-
Has a LOT more paramteter
-
Can set location!
-
-
icon parm popup_animated
-
popup button size (6,1) for all popups
-
NEW CALENDAR chooser integrated
-
Graph.draw_lines - new method to allow for multiline lines that may not be a full polygon
-
System Tray fixed the docstrings
-
color chooser set parent window (needed for icon?)
-
scrollable column scrollwheel fixed
-
fixed TabGroup border width (wasn't getting set properly at all)
-
Fixed Debug Printing to work like a normal "print"
-
Fixed _print_to_element to work like a normal "print"
-
Fixed light green 1 theme definition - Text color wasn't being set
-
fix for install from GitHub
-
fix for Column scrolling with comboboxes
-
Added Text.get
-
Spin.update fix
-
import typing again
-
fixes for Pi
-
test for valid ttk_theme names
-
fix for Text.get docstring
-
added tuples to some docstrings
-
added code for better tag handling for Multiline elements (fixes a potential memory leak... thanks Ruud)
-
WIN_CLOSE & WINDOW_CLOSED constants added. Both are None
-
EVENT_TIMEOUT and TIMEOUT_EVENT constants added to both be the same as TIMEOUT_KEY
-
Some changes in test harness that tested recent changes (may still need shortening for trinket or others)
-
Changed the misleading TRANSPARENT_BUTTON constant with an attempt using themes calls
Delays delays delays
I'm really sorry this release got SO backed up. There are over 30 sizable changes with some that felt huge enough to keep me awake at night. I REALLY hope this goes well for everyone.
The PySimpleGUI 2020 video series also pushed out this release. Lots of long, boring, complex reasons for the delay that I'll spare everyone. I just hope that people like the release and use it.
WIN_CLOSED
and WINDOW_CLOSED
Coming soon will be rushed releases of all ports to include the WIN_CLOSED
constant along with changes EVERYWHERE to reflect this.... Main doc, cookbook and all demos will need to be modified. I will need to edit the new videos as well. It's time to stop talking about checking for the None
event and start checking for the "window closed" event.
Spelling
I also tried to fix a LOT of spelling problems in the docs. I'm sure I didn't catch them all, so my apologies if the ones that drive you crazy to see are still there. I'm trying is my only defense and I had only a little time this morning to begin chipping away.
Scrolling columns with the mouse wheel
This is the biggest thing that happened and what feels like the biggest risk. I hope it goes well and makes a lot of people happy 😀
PySimpleGUI 2020-05-06T11:53:03Z
COVID19 Graph Project Update
"I'm not jut the President of Hair-Club for Men, I'm a client too"
Isn't that how the commercial used to read?
One of the fun things about PySimpleGUI is being able to USE PySimpleGUI. That was the whole purpose of the project to begin with.... to make a GUI program that I needed. Now I do it just for fun and to get the tools I want/need.
The series of COVID19 tools have been an important thing for me personally to deal with what's happening to the world.
As time goes on, the ways of looking at the data have changed too., The cumulative numbers were initially really important. Now, it's the daily number of NEW cases that's important. It's the shapes of those graphs that matter now if you want to know who's "ready to open for business". Not trying to be political, just after the facts so I can make my own life-choices.
Yesterday's changes brought about the ability to look at the world like this:
All graphs have been "normalized" so they all look equally "bad" in terms of severity, but that's far from the truth. They simply show that county's own struggle to get through their "peak".
My "hero country" has been Vietnam for a number of weeks. These people STOMPED on this bug like a cockroach. Their cumulative graph tells the whole story:
They are not a tiny country yet they only allowed a TOTAL of 271 cases. They've been at 0 for some time. It's encouraging. I dunno about you, but I'm looking for encouraging news anywhere in the world I can find it and for me, that little country did something cool.
Anyway, the latest code has been uploaded to the PySimpleGUI-COVID19 GitHub:
https://github.com/PySimpleGUI/PySimpleGUI-COVID19
I hope that everyone is able to be and stay safe. 🙏🏻
PySimpleGUI 2020-05-06T16:07:24Z
How to make/break 500 people's day
Thought I would share the bit of anxiety I feel sometimes when posting PyPI releases. The total number of PySimpleGUI pip installs will reach 1,000,000 sometime this year which is a fun and terrifying number.
The total installs are fun to add up, but it's the daily installs, and the installs when a new release posts that cause the stomach aches. It's especially distressing when the release has a potentially large change or there are a lot of changes. Both are true with 4.19.0 that just "shipped" yesterday.
I've got no illusion that PySimpleGUI is some critical package used by millions of people and embedded in 1,000's of devices, but it's hard/impossible for me to toss aside the "weight" of releasing software. Decades of shipping commercial products coupled with the personal responsibility that goes with those releases hasn't been something I've been able to ditch even though PySimpleGUI is a free product.
Took a quick look at yesterday's installs without recalling that there was a release. This is how it appeared:
I see that chart and immediate wonder how many, if any, of the 541 people that installed 4.19.0 said "Sh*t! It used to work!"
My hope is that many of those were instead waiting on something new or a fix and were thinking "Yea! It finally works!"
Regardless, it IS nice to see computers out there running the code.
Students
Students are my biggest concern over releases that go badly. The nightmare scenario is when something that SHOULD work, DID work, but does no longer and a student spends a lot of time debugging a problem that is not their fault.
Students have been an important focus for PySimpleGUI from the start, so want to be sure and make the experience for these peeps to be nothing but fun and exciting. Frustrating computer situations are magnified when kids are involved.
Edhesive & Others
This morning I learned that a company called Edhesive has PySimpleGUI in their curriculum after a student mentioned it on Discord. EEEK! I thought I was pretty aware of when / where PySimpleGUI was used in education in a formal way.
I was recently contacted from a teacher in a South Dakota school that has been using PySimpleGUI to teach students because it allowed him to teach GUI programming in an introduction to Python class. Python GUIs are typically never taught in an intro course as they require OOP programming which is beyond the scope of most intro courses.
The point is that it's getting more difficult to know when/where PySimpleGUI is being used by students. There's no indicator on the Edhesive site that they use PySimpleGUI. It makes these releases a tad more nerve-racking not knowing who is going to be impacted.
Thank you to the early-warning-indicators
Thankfully a number of you are not shy about opening up an issue when a release is a bad one. Knowing there are people at the ready to quickly say there's a problem that enable me to send these releases out without losing too much sleep.
So, 🤞🏻 hopefully 4.19.0 is going to be a good release for everyone!
PySimpleGUI 2020-05-06T20:07:53Z
0.16.0 PySimpleGUIWx 6-May-2020
-
Added constants
-
WIN_CLOSED and WINDOW_CLOSED
-
EVENT_TIMEOUT and TIMEOUT_EVENT
-
-
Added Graph.change_coordinates method
-
Added close parameter to Window.read
0.38.0 PySimpleGUIWeb 6-May-2020
-
Added constants
-
WIN_CLOSED and WINDOW_CLOSED
-
EVENT_TIMEOUT and TIMEOUT_EVENT
0.33.0 PySimpleGUIQt 6-May-2020
-
Added constants
-
WIN_CLOSED and WINDOW_CLOSED
-
EVENT_TIMEOUT and TIMEOUT_EVENT
-
Added expansion capabilities
-
Element.row_frame - The QHBoxLayout the element is contained within
-
Column.vbox_layout - The QVBoxLayout contained in Column element
PySimpleGUI 2020-05-06T20:20:04Z
WIN_CLOSED and WINDOW_CLOSED Events
Whew! Holy-big-bag-of-releases Batman!
Was clearly motivated to begin to use the new event WIN_CLOSED
safely. The only way to do it is to make the change to all 4 ports.
While there is a constant called TIMEOUT_KEY that can be used to detect timeouts, two additional aliases exist now for it as you can see. 99.9% of the time the timeout is not tested for so in reality I expect maybe one program in 10,000 will use one of those timeout constants. It's more for clarity that we're talking about EVENTS in the documentation and elsewhere.
Soon the massive change to the Demo Programs and documentation will start to modify event loops to check for WIN_CLOSED
instead of None
. Checking for None
has kinda bugged me since the first release so this is a welcomed change despite the interruption it's causing.
PySimpleGUIQt Expansion
There was a new PySimpleGUIQt capability snuck into the release as well that is not yet documented as I'm not super-thrilled that it's added and that is the ability to add your own widgets to PySimpleGUIQt layouts. In theory you could do something similar to tkinter but it's not something I want to see happen.
I'm still on the fence as to whether to document this ability or not. Using this type of expansion would be a hack of enormous magnitude as both callbacks and the PySimpleGUI message passed architecture would be both used. It quickly turns into code that I don't want to deal with supporting. There are times when it's better to tell someone to move on to using Qt directly as they have hit the limits of what PySimpleGUI is capable of doing.
PySimpleGUI 2020-05-07T10:32:33Z
Demo programs updated - All use WIN_CLOSED
now
The main demo programs have all been changed to use the new constant WIN_CLOSED for the window closed event.
You will have to use PySimpleGUI 4.19.0 if you want to use these demos, or change the variable back to testing for None.
PySimpleGUI 2020-05-07T10:37:42Z
The Daily Japanese Tutorials
I have a habit now of checking Twitter every morning to see what new article about PySimpleGUI has been posted. For months almost every day someone overseas writes a PySimpleGUI article / blog post / tutorial. It's CRAZY. Some are really good. OK, they're all really good in their own ways.
It's puzzling why this is happening but hasn't happened in the States or English speaking countries at all.
Here's one posted last night about doing OCR using PySimpleGUI
https://qiita.com//yamacs/items/cebb34227ad7373e9e3b
It's a strange phenomena. Maybe the PySimpleGUI documentation translates easier than other GUIs? Or maybe there's a cultural thing that PySimpleGUI touches on (being simple and elegant?) that resonates with a Japanese programmer more than an English speaking one?
I'll ask the Twitterverse and see what comes back. Someone surely knows why....
PySimpleGUI 2020-05-08T10:39:58Z
No more if event in (None, 'Exit)
There are 2 changes underway. The first was done yesterday to the demo programs which was to replace None
with sg.WIN_CLOSED
.
I'm working with an author on an article now and I am cleaning up a few demos, it's made me realize that I've made a "too Pythonic" error in my design templates and demos.
I'm pretty sure that the if statement currently used to check for None and
'Exit' ` is the "preferred" Python statement to use. However, a big goal is for PySimpleGUI to be simple enough for a complete beginner to use. Ideally someone with 1 week of Python can understand a basic PySimpleGUI window.
The "problem" is that you're unlikely to see this particular pattern of if towards the start of the class.
It may not ever come up in the class in fact:
It's "Pythonic", but who knows "Pythonic" in their first month of Python?? I certainly didn't. So it was this combination of thoughts that has led to this new design pattern and new coding convention.
Yes,. it's super-overly-obvious. Yes, it's not the most "Pythonic" way. But, like everything computers, not all answers are always the right answer to the same question, even when that answer is right 99% of the time. This, BTW, I see as this and the general immaturity of Reddit readers to be the major problem there. There is no "the best" in computers.
Anyway, just a heads-up that yes, more time being wasted poking around at the deck chairs on the titanic, but refinement of the package is just as important as growing it. It's a different kind of growth.
Not sure how long it'll take to make the change nor the speed of the rollout... today will be updating the official design patterns to use so at least people will get a start in that direction.
It's also part of my standard code snippit. In PyCharm I have a Live Template that pastes a small PySimpleGUI program. Gong forward it'll use or
instead of in
.
Headsup... WIN_CLOSED requires 4.19.0 which means all demos require 4.19.0 now
As warned in the demo readme (or docs somewhere), the demo programs are not meant to be backwards compatible. They will sometimes require you to upgrade.
If you do not care to upgrade and not use the constant WIN_CLOSED
and with to use None
, then feel free to change the demo source.
PySimpleGUI 2020-05-10T16:28:54Z
0.34.0 PySimpleGUIQt 10-May-2020
This time for REAL added the constants. I don't know how to changes got lost but they did.
-
Added constants
-
WIN_CLOSED and WINDOW_CLOSED
-
EVENT_TIMEOUT and TIMEOUT_EVENT
Ooops! I don't know what happened, but the newly added constants that were added to all ports, didn't make it into the PySimpleGUIQt release. REALLY weird and kinda upsetting as I blew it in a big way and don't yet understand exactly why it happened.
PySimpleGUI 2020-05-11T00:59:30Z
Two New YouTube "PySimpleGUI 2020" Videos
All of the PySimpleGUI videos are located here:
http://YouTube.PySimpleGUI.org
The "2020 series" are here: https://www.youtube.com/playlist?list=PLl8dD0doyrvFfzzniWS7FXrZefWWExJ2e
Today were a couple of good topics. The first was "Container Elements" the second was about "Generated Layouts". I think you'll find both of them informative. While single-line Sudoku board is a neat parlor trick, it does demonstrate a very powerful difference between PySimpleGUI and the other Python GUI frameworks. Creating windows using a simple list structure enables the use of list comprehensions to make GUI windows, a crazy thing.
PySimpleGUI 2020-05-11T14:21:52Z
YouTube.... don't get it... blown away by it....
I get 80% of my TV time on YouTube. It's on my TV video FireTV. I'm too impatient to watch much normal TV, although do use YouTubeTV too.
I watch the latest about archaeology, science, stuff like "Journey to the Microcosmos", funny stuff, but rarely technical programs unless it's "2-Minute Papers".
Anyway, one reason for making the PySimpleGUI 2020s was the old ones were actively teaching to do things in and older way. There are newer and "better" ways of doing things. So I'm essentially remaking all the old ones.
Here's the part that always stuns me, and I'm TINY compared to most YouTube people. An actual nothing in the YouTube universe.
Here's what the last 48 hours look like for the PySimpleGUI videos
I highlighted the last hour. It shows TEN people watched PySimpleGUI videos in the hour. Or there were 10 videos watched. Or something like that. The fact that 24 hours a day someone, somewhere in the world is watching these and learning PySimpleGUI is WEIRD. That's the only way I can put it.
It really puts into context how many people there are in the world! I think that ten is 0.000000013 % of the world's population.
Anyway, I'm just happy people are finding use for PySimpleGUI and the videos, and are making stuff that's making them happy. See stuff being made using it is an awesome experience. Thanks to everyone that's giving it a try and are posting the results! It's fun to look at the new arrivals. GitHub makes it easy. Just click at the top of the page:
PySimpleGUI 2020-05-12T11:26:28Z
Apologies for being spread so thin - Setting expectations
Despite my best efforts, I sometimes simply come up short. There are only so many hours. Most all of them that I have in a day are given to this project and the users. But sometimes that seems like it's not enough.
I'll be adding a new "expectations" section to the Issues form that will explain how long someone should expect to wait before a support issues. I realized that I've made a mistake by not saying anything at all about turnaround time. Expectations can wildly vary between "Oh, I understand the situation and can wait" to "why am I being ignored" and that's on me for not being clear. When there's a mismatch it becomes overwhelming and bad shit happens as a result, something I certainly want to fix.
I've also made the assumption that by now everyone knows that it's one person doing everything you see. I hire help on some occasions, and there are a couple of close friends that give me a handful of lines of code from time to time, but pretty much every keystroke in the docs and code and issues and trinket and demos and YouTube and ____ came from these pair of hands.
The net is that PySimpleGUI is operated like a 1-person startup.
Anyway, I'll continue to try hard to answer Issues within 24 hours. Just know it may be longer sometimes and that you're not being ignored. I'm simply trying to task-switch among a lot of things. Or maybe I had something come up and am not able to spend any time working that day. Regardless I value all the PySimpleGUI users and the support you've all given me and I'll keep on trying to give back to you in turn.
PySimpleGUI 2020-05-12T12:09:25Z
An Async Chat Application Using PySimpleGUI
There is not currently a good place to "spotlight" achievements like this one (and others) so I'm looking into using the WIKI and other ways to do this.
Async Desktop Chat
For now, I'll post about it here. A long-time user, supporter, friend, @nngogol, has once again developed an impressive piece of work.
I'm working to get a simple sockets based chat demo complete that's "simple".
THIS chat application however is really cool and a much more difficult kind of application to write.
You'll find the code here:
https://github.com/nngogol/async-desktop-chat
It uses Websockets along with true Python async capabilities to implement a chat application with a server that is capable of handling multiple client connections and even has a private message capability between users.
Given the amount of code, it's truly a work of art. The server is 111 lines of actual code and the client 144.... and that includes the GUI.
I'll be the first to say the async/await implementation he's created is above my head at the moment, and I look forward to learning more about that for sure! In the meantime I'm simply in awe and enjoying playing with it and learning from reading the code.
Here's a video of it in action:
FYI - In case you're not familiar with the level of impact he's had on PySimpleGUI, one example is the technique of looking up elements using the notation window[key]
was his creation. It's an honor to be around brilliant computer scientists like him. Thank you to all PySimpleGUI users out there making cool stuff!!
PySimpleGUI 2020-05-17T11:54:06Z
Split Readme and Call Reference
I know this will make a number of people happier... or so I hope.
The giant readme has been split into 2 (giant) parts. The Call Reference section now has its own tab at the top of the ReadTheDocs (http://www.PySimpleGUI.org)
The Call Reference tab has signatures for all of the Elements and other Objects and all functions. This should improve the load times for everything.
The project's Readme now fits on the main github page again instead of being truncated. I still need to add a link over to the reference from the readme so that users know to go over there and search for specific call info.
It's my hope this makes the documentation even more useful / usable. I do understand the the "large file" approach is simplistic, but the package is named PySimpleGUI after all and that simplicity mantra isn't limited to the architecture.
If you care to be bored enough to read the logic...
Reason for the large files
I've navigated the tkinter, pyside2, WxPython, and Remi documentation, not to mention many other packages. I personally struggle with the ones that are split up into many separate pages. The "Search" box rarely gives me the result I'm after. Navigating takes time. I end up frustrated.
Just like you look through the docs, so do I. Using Control+F as a simple search and F3 to jump to next reference.
The scrollbar on the right is highlighted with all the locations it finds the words. AND there's a table of contents on the left that also...
Oh, look, my search for ButtonMenu has turned up the primary section it's likely discussed in.
With the new tab, it should make searching for Elements and methods even easier. It too has a table of contents, just as it did in the readme before:
PySimpleGUIQt is coming
Official work on the docstrings in PySimpleGUIQt is underway. That should really help PySimpleGUIQt users and will enable me to make another call reference doc that's Qt specific.
Thanks for the Thanks
I hear from a lot of people about the docs. I do listen to the ones that don't like them, but I also get a lot of people that contact me that do like them... a lot.... so while I am trying to improve them, it's nice to know they are really useful to some people.
"It's not done until the docs are done" has been my mantra for decades and I don't see that changing... so hopefully PySimpleGUI docs will also improve over time.
PySimpleGUI 2020-05-17T17:37:43Z
Unifying The "Element Justification" Mechanism
Big leap forward this week in the way element justification is handled.
The mechanism for the primary PySimpleGUI port is a parameter element_justification
that is on the Window, Column, Frame, and Tab elements. They all have the same parameter and it works the same for each of them.
BTW - For justification parameters I've made them in a way that you only need to use the first character.
This code produces this window:
import PySimpleGUI as sg
# import PySimpleGUIQt as sg
# import PySimpleGUIWeb as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout, element_justification='c')
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
This code produces the exact same window. It uses the trick of taking a window layout, and sticking it into a Column layout that has no padding. The windows look identical
import PySimpleGUI as sg
# import PySimpleGUIQt as sg
# import PySimpleGUIWeb as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Button('Go'), sg.Button('Exit')] ]
layout = [[sg.Column(layout, element_justification='c', pad=(0,0))]]
window = sg.Window('Window Title', layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
If you want to place your window in a Frame that centers, the same trick applies but using a Frame
element instead of a Column
Or if you prefer Qt, the same trick works now:
On PySimpleGUIWeb, if you use this track with a Column element, it will center the elements in the Column, which is LEFT justified within the window. This is the effect:
The PySimpleGUIWx port continues to be the red-headed step-child of ports. It will get it added shortly. I wanted to share the good news on the Qt and Web ports today.
I'm excited about this change and will try to get it published to PyPI as quickly as I can for Qt and Web!
PySimpleGUI 2020-05-19T23:20:55Z
Async Chat Client/Server - Part 2
Disclaimer.... allowing anything past your router / firewall is risky business. Understand what risks you're taking and exercise caution.....
Want to share a successful experiment. Maybe you wan to try something like it? I dunno... it's fun to get stuff working sometimes just to know it can be done.
Maybe you want to have a person chat connection with friends but trust no other products or services out there. If so, them maybe this async chat server is your paranoia nirvana. Or maybe it's even riskier? 🤷🏻♂️
Async Chat
A week ago I spotlighted a PySimpleGUI based async chat program.... I think it's pretty incredible what can be done with skilled Python developers. I'll be the first to admit, it's beyond my capabilities. But, like many PySimpleGUI things, it's not beyond my using it.
You'll again find the code here:
https://github.com/nngogol/async-desktop-chat
What I wanted to share was an experiment that worked out really well. I think maybe I'm easily impressed or excited, but I'm good with that. In the end I'm having fun and that's a big part of why we're all here, right?
It was fun to play around with the program on my local network, but what about the outside world? Is it possible to use this program with friends that are on the Internet.
Setting up port forwarding...
I knew that was going to require a bit of port-forwarding in my router to get from my modem to my desktop machine. If you want to provide a chat server for you and your friends, you'll need to do a few things in order to be the server.
Do a little research and poking around in your router and you'll find that you can reserve a specific port # that when the router gets packets for that port, the router is capable of sending them to a specific machine on your network. This is how you will get the chat traffic from the internet to your computer that's safely behind your firewall and all the great protections if offers.
Of course, be really careful and understand you're dropping your shields a little doing this. Choose a port that's obscure and not "dangerous" to let someone through. Something not normally connected to anything.
I managed to setup my router such that traffic on a particular port was routed to my desktop computer.
Informing your pals of where to connect
You can find your external IP address easily enough and hand that out, but it will change when you restart your modem. Some routers connect with services such as noip.com.
noip.com allows you to give out a URL that will resolve to your external ip address of your modem/internet connection. I managed to get my router to work with noip.com and when pinging my noip address, I saw it resolving to the correct address of my modem.
So, up to this point I could give out an address that's not a hard coded IP address and a port number, and my router passed traffic through to my desktop computer.
Punching through your virus protection / firewall.
This is where things really turn a bit risky in my opinion, but it was a test more than something I planned on leaving up, so I was OK with doing it. I again used the special port # that I reserved in my router. I told my computer's firewall to allow traffic into that port and to allow the server.py program to listen on that port.
Run the server and clients
The last step was to run the server on my desktop, run a client on my desktop, and get my friends to run the client and try to connect.
And.....
It worked!
I was able to run a chat server on my desktop and use the client to talk to other clients. It's like having your own discord chat server. If you want to overlay come mega-encryption onto it that exceeds what discord provides, then nothing stopping you from doing that than a bit of python programming.
Extending the capabilities
I already mentioned layering on encryption so go for it if that's your thing. It's also possible to extend the GUI in an interesting way. Because the SystemTray feature is available in PySimpleGUI, it's possible to run the server as a SystemTray program that will popup messages when events happen like people connecting.
Or maybe you want the client interface to minimize down into the system tray. Lots of ways of extending this program using PySimpleGUI that isn't beyond what an intermediate programmer, or perhaps even an advanced beginner programmer, is capable of doing. It's less than 10 lines of code to make a system tray based PySimpleGUI program, so can't be THAT difficult to add it onto the server and/or client.
Keep making stuff!
Every day I see new creations out there. It's awesome to see what people are making. The programs are getting more and more diverse and interesting. They don't have to be long to be interesting. A 25 line stock quote app was posted on Reddit today that's pretty cool.
The advice I get to beginners is to make stuff. It's a craft we're all participating in and the more you practice whatever your craft is, the better you'll get.
PySimpleGUI 2020-05-20T02:28:10Z
Splash Screens
Saw a Reddit post looking for a splash screen with a transparent background..
I could swear this already existed but I don't see anything so I made a new demo application for it
import PySimpleGUI as sg
IMAGE_FILE = r'A:\- TEMP 2019 -\PySimpleGUI_Logo.png'
DISPLAY_TIME_MILLISECONDS = 4000
sg.Window('Window Title', [[sg.Image(IMAGE_FILE)]], transparent_color=sg.theme_background_color(), no_titlebar=True, keep_on_top=True).read(timeout=DISPLAY_TIME_MILLISECONDS, close=True)
I dunno what it is about these 1-line PySimpleGUI solutions that makes them so much fin, but they're fun! It's not that they're 1 line in length, It's more the "logic puzzle" aspect of it all. It like assembling Tinkertoys from capabilities that I know exit. The close
parameter is key in these kinds of apps.
PySimpleGUI 2020-05-27T23:13:46Z
Unified Element Justification
The work is finally done on unifying how Elements are justified within Windows and "Container Elements".
All four ports, yes PySimpleGUIWx included, now use the element_justification
parameter. Add this parameter to Window
and any container (Column
, Frame
, Tab
) and the contents will arrange their elements in this manner. Valid values are 'l', 'r', 'c' or 'left', 'right', 'center'. Or 'larry', roy', 'charlie'. Pick your own element justification word as long as it begins with l, c, or r.
There is one exception. The default justification for PySimpleGUIQt Windows is.... float
. This is the justification as the way things are today. One unusual way the PySimpleGUIQt port differs from tk port is that the buttons stretch across the window. If you set the justification to 'left', then it will autosize the buttons so that it looks like you would think. I did not want to use this setting as the "new default" however as it would impact every existing application. Not gonna happen, so, 'float' is the default.
import PySimpleGUIQt as sg
layout = [ [sg.T('*'*(60))],
[sg.B('Button 1'), sg.B('Button 2')]]
window = sg.Window('Element Justification', layout).read(close=True)
layout = [ [sg.T('*'*(60))],
[sg.B('Button 1'), sg.B('Button 2')]]
window = sg.Window('Element Justification', layout, element_justification='l').read(close=True)
PySimpleGUIQt's "float" justification
PySimpleGUIQt's 'left;' justification
You can get all of the ports from GitHub. (They're being posted to PyPI tonight/tomorrow. Docs are still being updated.)
PySimpleGUI 2020-05-30T14:05:24Z
Amazing Python Cheat Sheet
I've seen countless cheat sheets. This one is truly amazing. I've created a PDF from it.
https://gto76.github.io/python-cheatsheet/
I am trying to determine if I can integrate into PyCharm somehow or make a single-button launch of a PySimpleGUI front-end to help. Maybe I just launch my PDF viewer. Don't know yet but it sure seems worth sharing. Anything to speed development for us all!
PySimpleGUI 2020-05-30T17:51:09Z
COMING PySimpleGUIQt DocStrings!!!
My hope is to get these released this weekend!
This is a HUGE thing to get done. Finally the PySimpleGUIQt users have a good set of explanations and list of all of the parameters.
I received a lot of help on these from @nngogol , who also created the readme documentation generator so I have an enormous amount of gratitude for him making this available. We are all benefiting greatly!
PySimpleGUI 2020-06-02T15:34:09Z
Running PySimpleGUI code using .pyw extension (on Windows)
I apologize for my ignorance of Python on Linux for this topic. I'm still investigating to see what the scoop is. So, for the purposes of this post, I'm assuming you're a Windows user (sorry other 50% of the PySimpleGUI users)
It dawned on me yesterday that not everyone knows about the pythonw.exe file. I believe by default if you name a program with the .pyw extension rather than .py, it will execute pythonw.exe to run the program when you double click it.
For PySimpleGUI programs, THIS is the experience you want users to have. This is sorta the holy grail of GUI development. You double click a file and up pops a "window" that looks like a "real windows application".
I'm sure you already know that double clicking a .py file results in a console application launching along with your GUI application. Using pythonw removes that pesky console and your experience becomes one much like running an EXE file.
Of course, any prints you do are going to be lost. Crash information will be lost.
This scenario is exactly why the function Print
exists. Waaayyyy back in the early days, there was this dream of using running only GUI programs using only GUIs. No consoles.
But what about "print" output? It's THE way to debug for many/most. That's where the "Debug Window" comes to the rescue. You can not only use is with the Print
function, but you can re-route stdout to use this window as well.
The "trick" is to make an initial call to Print
that using the parameter do_not_reroute_stdout
set to False
. This causes stdout to be rerouted. Normally it does not reroute stdout.
So, this code:
import PySimpleGUI as sg
sg.Print('This is the first line printed', do_not_reroute_stdout=False)
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-'), sg.Text(size=(12,1), key='-OUT-')],
[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 == 'Go':
window['-OUT-'].update(values['-IN-'])
window.close()
Creates this window. Notice how the first line is "printed" to the debug window using the sg.Print
call at the top of the program.
But, all other prints in the program, in this case print(event, values)
are also shown in that debug window.
Maybe this should be explicitly be added to the Cookbook? There was recently a large section added devoted to printing and I think this is already mentioned, but perhaps not in this manner.
Anyway, enjoy!!
PySimpleGUI 2020-06-06T14:36:01Z
0.35.0 PySimpleGUIQt 6-Jun-2020
Element justification within Window and Containers! Finally a unified justification
-
When any Radio element is updated to be False, the entire GROUP is reset so nothing is selected
-
Fixed Multiline.get so that it correctly returns the value, was always returning None
-
Fixed MultilineOutput.get so that it correctly returns the value, was always returning None
-
Notes say I fixed a Frame Element background color bug but I don't see where / how
-
element_justification added so that all elements inside these will be justified accordingly.
-
For PySimpleGUIQt only, the default is "float" which sets nothing. Buttons will stretch across the window as result
-
Valid values are 'l', 'r', 'c'. You can spell it out, but only first letter is used.
-
Window
-
Frame
-
Column
-
Tab
-
-
Table Element addition
-
Header background color
-
Header text color
-
Header Font (not yet hooked up)
-
PySimpleGUI 2020-06-06T18:38:32Z
0.17.0 PySimpleGUIWx 6-Jun-2020
Element justification within Window and Containers! Finally a unified justification
-
When any Radio element is updated to be False, the entire GROUP is reset so nothing is selected
-
element_justification added so that all elements inside these will be justified accordingly.
-
For PySimpleGUIQt only, the default is "float" which sets nothing. Buttons will stretch across the window as result
-
Valid values are 'l', 'r', 'c'. You can spell it out, but only first letter is used.
-
Window
-
Frame
-
Column
-
Tab
-
PySimpleGUI 2020-06-06T20:45:17Z
4.20.0 PySimpleGUI 6-Jun-2020
Fixes and new features... broad range
-
Fix for Typing import for Pi (3.4) users. Now "tries" to import typing
-
Tooltip fonts - can change the font for tooltips
-
Fixed tearoff for Menus. Had stoppped working
-
Radio - If element is updated to False, the entire group of radio buttons will be set to false tooltips
-
Multiline - fix for colors. Only set tags for output that has specific colors
-
Multiline - keeping track of disabled with Disabled mumber variable
-
Progress bar
-
Added class variable "uniqueness counter" so that every bar will have its own settings
-
Needed in case the same key is used in another window
-
-
Fix for stdout being reset if someone sets flush on their call to print
-
Mac special case added to tkfiledialog.askdirectory just like on askopenfilename
-
Tab - can "update" the title
-
Menu update - was not applying font when updating the menu
-
Window.set_title - allows you to change the title for a window
-
Added searching through Panes when looking for element with focus
-
Removed Python 2 Add Menu Item code
-
Added font to buttonmenu.
-
Added font to the combobox drop-down list (wow what a pain)
-
Table now uses the element's padding rather than 0,0
-
Tree now uses the element's padding rather than 0,0
-
set_options - added ability to set the tooltip font
-
Fixed a couple of docstrings
-
Reworked main() test harness to dispay DETAILED tkinter info and use bettter colors
PySimpleGUI 2020-06-06T21:14:56Z
0.39.0 PySimpleGUIWeb 6-Jun-2020
Element justification within Window and Containers! Finally a unified justification
-
Frame support, but without any labels yet.... only makes a frame... hey, it's a start
-
element_jutification added so that all elements inside these will be justified accordingly.
-
For PySimpleGUIQt only, the default is "float" which sets nothing. Buttons will stretch across the window as result
-
Valid values are 'l', 'r', 'c'. You can spell it out, but only first letter is used.
-
Window
-
Frame
-
Column
-
Tab
-
-
New main() that shows Remi version and more info
PySimpleGUI 2020-06-12T23:56:51Z
Dashboard Demo Program
I saw a nicely designed tkinter window shown on Reddit in this post:
https://www.reddit.com/r/Python/comments/gxsb8v/i_created_a_gui_that_collates_various_interests/
This is the window that the code produces:
Now THAT'S a GUI design worth grabbing and doing something with!
When someone has made tkinter look that nice, you can't let it go to waste. It's one example of how not to design ugly looking tkinter windows.
I wondered how to go about something like that using PySimpleGUI. The big question for me was "how can I make those borders"?
It turned out to be relatively straightforward. There's a new Demo Program located here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Dashboard.py
That makes this window:
Notice that it does not have a titlebar. You can add one back easily enough if you won't mind it by not setting the no_titlebar
parameter.
The messy / tricky part of the code is getting the borders to be the right size.
It should come at no great surprise that the layout is just a bunch of Column
elements with one of the Columns containing Columns.
layout = [[sg.Column(top_banner, size=(960, 60), pad=(0,0), background_color=DARK_HEADER_COLOR)],
[sg.Column(top, size=(920, 90), pad=BPAD_TOP)],
[sg.Column([[sg.Column(block_2, size=(450,150), pad=BPAD_LEFT_INSIDE)],
[sg.Column(block_3, size=(450,150), pad=BPAD_LEFT_INSIDE)]], pad=BPAD_LEFT, background_color=BORDER_COLOR),
sg.Column(block_4, size=(450, 320), pad=BPAD_RIGHT)]]
The layouts inside the blocks is really typical PySimpleGUI stuff like this:
block_2 = [[sg.Text('Block 2', font='Any 20')],
[sg.T('This is some random text')],
[sg.Image(data=sg.DEFAULT_BASE64_ICON)] ]
This is a great little Demo in search of an application. If you're looking for a clean looking Dashboard interface for a PySimpleGUI program, consider giving it a try.
PySimpleGUI 2020-06-16T16:33:23Z
Three More Widgets
In the past couple of days I have dashed out a couple of quick and easy "Rainmeter-style" Desktop Widgets.
The two that were added were a disk partition use viewer and a RAM use viewer.
Drive Usage
RAM Usage
CPU Usage
This one has been around a while, but not really posted as a widget. I'll add it to the Widget Repo that I started that only has some of these PySimpleGUI Widgets (https://github.com/PySimpleGUI/PySimpleGUI-Widgets). I also modified the top CPU usage processes widget to make the exit button into a clickable text X.
PySimpleGUI 2020-06-16T19:33:13Z
Reversing the Radio Button Mistake.....
I recently released a change Radio Button that rippled across all of the ports. The change was that clearing a single Radio button cleared the entire bank that the radio button is associated with.
I just learned 2 things today:
-
This change broke the "Load from Disk" code
-
There was already an API call
Radio.reset_group
that clears all Radio Buttons in the group
I also learned that the reset_group
code only existed for the tkinter port.
So, today I changed the tkinter, Wx and Qt ports. They all now only clear the single radio button when requested. Both the Qt and Wx ports were given a Radio.reset_group
method. This makes much more sense. Sorry for the short f-up period.
I'm going to try and push a release of all ports out the door pretty quickly, perhaps in the next 1-2 weeks. There's not a huge rush except that some people will have broken code if they upgrade, so perhaps wait if you're a user of the load from disk code and have radio buttons in your layout.
PySimpleGUI 2020-06-18T12:04:26Z
Bye bye Rainmeter
I think I've finally got a set of Widgets running on one of my monitors and can officially uninstall Rainmeter from my computer.
While this looks like a complete mess, it's on one of 4 monitors. Real estate is not an issue so I like to use the space for instrumentation.
The "Launcher" in the bottom left corner get the most interactive use. If I want to launch GitHub, or one of the test programs, or copy a release to GitHub, it's a button click away.
When I'm ready to pop a release up to GitHub, I click on which port to copy and then GitHub to launch the GitHub GUI program (yes, I use the GUI version instead of the command line one)
I think everything else is pretty self-explanatory about the screen. Most of these are posted on the PySimpleGUI-Widgets repo as well as in the Demo Programs area.
PySimpleGUI 2020-06-19T12:09:07Z
New Separator Demo
In response to the newly added Horizontal Separator Element (not yet released to PyPI however), I've created a simple demo program that shows how to use the 2 different separators.
This window is produced from the code below:
import PySimpleGUI as sg
"""
Demo - Separator Elements
Shows usage of both Horizontal and Vertical Separator Elements
Vertical Separators are placed BETWEEN 2 elements ON the same row. These work well when one
of the elements is a Column or the element spans several rows
Horizontal separators are placed BETWEEN 2 rows. They will occupy the entire span of the row they
are located on. If that row is constrained within a container, then it will spand the widget of
the container.
Copyright 2020 PySimpleGUI.org
"""
left_col = sg.Column([[sg.Listbox((1,2,3,4,5,6), size=(6,4))]])
right_col = sg.Column([[sg.Input(), sg.Input()],
[sg.HorizontalSeparator()],
[sg.Column([[sg.In()], [sg.HorizontalSeparator()]], pad=(0,0))],])
layout = [
[sg.Text('Window with some separators')],
[left_col, sg.VerticalSeparator(), right_col],
[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
window.close()
PySimpleGUI 2020-06-26T12:48:55Z
Toolsmithing your way to a happier, more productive day
One of the things that I enjoy the most about PySimpleGUI is having the ability to create my own tools. I've done this in the past of course, but never with a full-blown GUI. Now that making GUIs is pretty close to trivial, I don't hesitate to spend a few minutes making a tool to make life easier and waste less time.
There is also the immense satisfaction of using your own software. It's a great little perpetual motion machine where completing one tool leads to creating another so that each is a little more powerful than the last. The time invested (both of these took an afternoon) is usually more than worth it.
Build a PyCharm Favorites Launcher
It's been a "toolsmithing" week for me.
Here's the first one I'll be discussing:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_PyCharm_Launcher.py
I had a partial crash of my PyCharm environment and so it was an opportunity to examine how I had things setup.
Two activities in particular I find myself doing a LOT are:
-
Editing one of the PySimpleGUI ports' .py files
-
Copying Demo Programs from my local folder to GitHub
Both of these activities I was doing within PyCharm itself.
Editing - file selection within PyCharm
Normally to edit a file I use the "project file explorer" in the PyCharm window. This is a list of files in the project. Because there are a LOT of files in the project, it takes a bit of scrolling to find PySimpleGUI.py and then click on it.
An alternative is to mark these files as "Favorites"
That's fine, but it requires multiple clicks to open the favorites tab in PyCharm, open another collapsed list and finally choose the item from the list.
Editing - file selection using a desktop widget / launcher
I'm a big fan of widgets on my desktop these days. I have a massive one I use for launching programs, copying files, etc. Basically a button to do my most common activities.
This specific problem, editing the PySimpleGUI.py file, could have been added to the primary launcher.
I settled on a special smaller launcher that sits right above my system tray, like this:
It's always on top of all windows so it's always super-easy to get to.
I don't know how much time I'm saving, but it feels like a LOT
Self-editing Button
Since I've been actively working on this launcher, I decided to add it to the list of programs that I can quickly edit in PyCharm. Thus the last button in the list is "This Program". Now I don't have to remember what I called the program nor where it lives.
GitHub Demo Copier / Editor / Launcher
Another very common activity is creation and updating the demo programs. Just like editing the PySimpleGUI.py file, it required me to scroll through the many project files to find and edit them. I was also copying the file from my local folder to my GitHub folder when I was ready to check in changes.
This too seemed like a great candidate for optimizing, so I wrote this little tool. I'm not posting it as a demo as it's somewhat specialized.
With this tool I can copy demos, run them both locally and from the GitHub folder as well as edit them in PyCharm. Like the PyCharm launcher above, I added a button to edit the program in PyCharm at the click of a button. It's made life SO MUCH more efficient.
PySimpleGUI 2020-06-27T19:39:49Z
4.21.0 PySimpleGUI 27-Jun-2020
Horizontal Separator, cprint, docstrings
-
New color printing function cprint - enables easy color printing to an element
-
Tons of docstring fixups (300+ changes)
-
Removed old Python2 checks
-
Added Element.set_vscroll_position - scroll to a particular % of the way into a scrollable widget
-
Input Text - new parameters
-
border_width
-
read_only (for tkinter will have to be disabled OR readonly. Cannot be both)
-
disabled_readonly_background_color
-
disabled_readonly_text_color
-
-
Radio - Backed out the change that cleareed all buttons in group because already have that ability using reset_group
-
Graph drag mouse up events returned as either a string + "+UP" (as before) or as a tuple with "+UP" being added onto a tuple key
-
Vertical separator - added key and color - color defaults to text color
-
Horizontal separator! (FINALLY). Color defaults to text color
-
Fix for Table and Tree elements not automtically getting a key generated if one wasn't supplied
-
Made key parameter for one_line_progress_meter have a default value so don't have to specify it when you have only 1 running
-
theme_add_new - adds a new theme entry given a theme name and a dictionary entry. This way you don't have to directly modify the theme dictionary
-
Added initial_folder to popup_get_folder when there is no window
-
Added default_path to popup_get_file when there is no window
-
Fix for removing too many PySimpleGUI installs when using the GitHub upgrade tooltip
PySimpleGUI 2020-06-30T13:38:10Z
New k
parameter == key
parameter
While creating the new cprint
function it dawned on me that tkinter uses multiple keywords for the exact same parameter so I might as well do the same with PySimpleGUI, particularly for parameters that are often used, such as key
.
So, for the tkinter port, at least for now, I've created an experimental release where every element has a parameter k
. The element will use either key
or k
for the element's key. key
will take precedence should both be specified.
This will be particularly helpful for layouts that are very complex and the length of the layout lines become long. Combined with the shortened element names, you can make compact programs such as this:
import PySimpleGUI as sg
layout = [ [sg.T('My Window')],
[sg.In(k='-IN-'), sg.T(size=(12,1), k='-OUT-')],
[sg.B('Go'), sg.B('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 == 'Go':
window['-OUT-'].update(values['-IN-'])
window.close()
This is not ideal for beginners of course as it's difficult enough to initially learn the concept of a key
and seeing this k
thing all over the place isn't very descriptive. But, it's not a beginner feature. The plain key
parameter remains and always will remain there. It'll be used for most of the Demo Programs.
It it turns out well, then expect to see it ported across the other 3 ports.
PySimpleGUI 2020-07-03T13:28:08Z
4.23.0 PySimpleGUI 3-Jul-2020
Table Colors Fix - workaround for problems with tables and tree colors in Python 3.7.2 to 3.9+
Mac crash fixed - tkinter.TclError: expected boolean value but got "" (hopefully)
New shortcut "k" parameter for all elements that is the same as "key" - may be experimental / temporary if not well received
More error checks
popup extensions
-
Fix for missing Table and Tree colors created in tk 8.6.9
-
This is a problem in all versions of Python 3.7.2 - 3.9.0 with no target fix date published
-
As a result of no fixes in sight, added a fix in PySimpleGUI if the tk version is 8.6.9
-
-
New Element creation parameter "k" - exact same thing as "key" but shorter. Helps with complex layouts
-
New error reporting on all element.update calls - checks to see if element has been fully created
-
set_options - new option to supress popup_errors coming from PySimpleGUI.py
-
Mac specific crash fix - if on a Mac, no longer calling wm_overrideredirect as it crashes the Mac now
-
Additional error checking (shows error instead of asserting:
-
Check for Widget creation before widget operations like bind, unbind, expand
-
Check for window finalize / read before some window operations like maximize, hide, etc
-
-
docstrings - more added. Fixed up a number of missing / erroneous ones
-
Tree element - caches images so that will not create new ones if previously used on another Tree item
-
popup - two new options
-
any_key_closes - bool. If True, any key pressed will close the window
-
image - can be a bytes (base64) or string (filename). Image will be shown at top of the popup
-
-
all popups - new image parameter (base64 or string)
-
a few new built-in icons
PySimpleGUI 2020-07-03T19:10:25Z
4.24.0 PySimpleGUI 3-Jul-2020
Selective control over tk 8.6.9 treeview color patch
-
Disabled the code that patched the problem with background colors for Tree and Table elements
-
Can enable the patched code by calling set_options
- To enable set parameter enable_treeview_869_patch = True (defaults to false)
PySimpleGUI 2020-07-05T19:03:56Z
The Latest Status....
Milestones
There's been quite a bit happening over the past 30 days. A number of milestones reached including topping 1,000,000 pip installs, 4,000 GitHub stars, and an article written by my favorite Python author, Mike Driscoll, that was published at RealPython.com.
Next week, July 11th, marks the 2 year anniversary of the launch of PySimpleGUI. That first release didn't have all of the elements. There was only about 3/4 of them running at that point and of course it only supported tkinter.
YouTube
I just took down all of the PySimpleGUI videos except for the newest 2020 series. While the older videos all contained techniques, concepts, and syntax that continues to run, they used older calls which were not PEP8 compliant among other things. This has led to a number of posts where people are claiming that PySimpleGUI does not have PEP8 compliant interfaces (which is not true).
It's better to have less material that is more accurate than more that isn't as good. I'll go back through the ones taken down and remake those videos using the latest and greatest PySimpleGUI coding conventions.
I've also hired a professional to create a proper intro video. It uses the information presented in the "PySimpleGUI for Impatient People" video.
Cross porting of newer features
There are a number of features recently added to the tkinter port that I'm porting over to the other releases. These include:
-
The
cprint
function -
The
k
parameter for all elements (same askey
but shorter) -
The new Button Color format (single string - "white on red")
-
This format was introduced with the
cprint
features -
Decided to allow the new format to be used when creating buttons and updating buttons
-
-
Changes to popups that include the image and anykey parameters, and a newly added wrapping technique
The new button color format
Results in a GUI that has these buttons:
More Demos
There have been a number of new demo programs released. Some are tools being used to help create additional documentation. A Window screenshot tool is a good example of one of these.
Note the nicely colored multiline status area. All thanks to the new cprint function.
sg.cprint('Saving:', end='', c='white on red')
sg.cprint(' ', title, c='white on green')
# The parameter "c" can also be written as "colors". "c" is simply a short-cut/alias for colors
sg.cprint('Wrote image to file:')
sg.cprint(filename, colors='white on purple')
There was also a recent addition of a more general purpose image viewer that uses PIL. This really needs to be better promoted so that people can get JPGs into their PySimpleGUI programs easily.
More Recipes
There are a number of new areas that need to be added to the Cookbook
-
Element Justification - I've discovered much easier ways to get justification to work!!
-
Adding a "PyCharm Me" button so that programs are capable of editing themselves
-
Taking snapshots of windows
-
Using PIL to make working with images easier and enable JPG use
-
Horizontal Separator Element - pointing out that one exists and how to use it
It feels like there are a LOT of really powerful recent additions that have not been very well communicated. Sorry it's taking a while to get the documentation updated so that these features are fully explained.
Focusing on PySimpleGUIWeb This Week
The current focus is on PySimpleGUIWeb... in particular getting Matplotlib working with it as well as support for drawing images on Graph elements.
And the cross-porting already mentioned needs to happen to PySimpleGUIWeb so that the calls will be portable across all of the ports.
Special thanks to @nngogol and @jason990420
I want to send a special "thank you" message to these 2 gentlemen. They've both generously given a lot of their rime to the project and it's helped a LOT.
Jason's been on the front line fielding Issues as they come in, often solving problems before I have a chance to even look at them. It's been really nice having an extra hand dealing with incoming issues.
nngogol has continued the documentation aid. The read-the-docs documentation and the docstrings work were completed with a huge amount of help. You guys don't directly see the kind of work he's done, only the results. For example, when I'm pulling together a new release or am writing new documentation, his readme generator tool has been a massive help. It takes the PySimpleGUI source file and creates the documentation you see http://www.PySimpleGUI.org and http://Calls.PySimpleGUI.org
PySimpleGUI 2020-07-06T20:23:43Z
Finally Matplotlib on PySimpleGUIWeb
Yeah!! Matplotlib now showing in a browser near you thanks to PySimpleGUIWeb!
What's extra special about this new feature is that it doesn't require any changes to PySimpleGUIWeb. It's all accomplished with existing PySimpleGUIWeb code using an Image element.
You'll find several demo programs in the PySimpleGUIWeb specific demo programs area:
https://github.com/PySimpleGUI/PySimpleGUI/tree/master/PySimpleGUIWeb/Demo%20Programs
This is the function that made it all possible:
def draw_figure(fig, element):
"""
Draws the previously created "figure" in the supplied Image Element
:param fig: a Matplotlib figure
:param element: an Image Element
:return: The figure canvas
"""
plt.close('all') # erases previously drawn plots
canv = FigureCanvasAgg(fig)
buf = io.BytesIO()
canv.print_figure(buf, format='png')
if buf is None:
return None
buf.seek(0)
element.update(data=buf.read())
return canv
To make a matplotlib drawing in your window, create a Window with an Image Element in it. Just like all of the other matplotlib PySimpleGUI demos, you'll create a "figure" that is then displayed.
Here's a very minimal program that creates a plat and shows it in the window:
import PySimpleGUIWeb as sg
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasAgg
import matplotlib.pyplot as plt
import io
def draw_figure(fig, element):
"""
Draws the previously created "figure" in the supplied Image Element
:param fig: a Matplotlib figure
:param element: an Image Element
:return: The figure canvas
"""
plt.close('all') # erases previously drawn plots
canv = FigureCanvasAgg(fig)
buf = io.BytesIO()
canv.print_figure(buf, format='png')
if buf is None:
return None
buf.seek(0)
element.update(data=buf.read())
return canv
def main():
layout = [[sg.Text('Matplotlib Simple Plot', font='Any 20')],
[sg.Image(key='-IMAGE-')],
[sg.Button('Exit')]]
window = sg.Window('Matplotlib Example', layout, finalize=True)
fig = plt.figure()
x = np.arange(0, 5, 0.1)
y = np.sin(x)
plt.plot(x, y)
draw_figure(fig, window['-IMAGE-'])
window.read(close=True)
if __name__ == "__main__":
main()
PySimpleGUI 2020-07-09T12:04:09Z
New YouTube Introduction to PySimpleGUI Animated Video
I'm really pleased with how this professionally produced video turned out.
https://youtu.be/36BdjuNcQJ4
It explains this simple demo program which touches on all aspects of PySimpleGUI.... layout, window creation, event loop, updating things in your window. All of that in under 4 minutes of video.
If you think about the other Python GUI frameworks and what you can explain in 4 minutes, you're unlikely to be able to cover a program that do this much and is this simple/easy to understand. Hopefully it'll get the point across as to just how simple of a framework it is to use.
# http://www.PySimpleGUI.org
# import
import PySimpleGUI as sg
#layout
layout = [[sg.Text('Enter something:'), sg.Input(key='-IN-')],
[sg.Text('Out output will go here',key='-OUT-', size=(30,1) )],
[sg.Button('Ok'), sg.Button('Exit')]]
# window
window = sg.Window('Title', layout)
# event loop
while True:
event, values = window.read()
if event == 'Exit' or event == sg.WIN_CLOSED:
break
window['-OUT-'].update(values['-IN-'])
#close
window.close()
PySimpleGUI 2020-07-09T14:44:45Z
Auto-Refreshing
Coming soon to PyPI (already up on GitHub) are changes to the Output element and Multiline elements, at least on the PySimpleGUI port.
These auto-refresh capabilities will make programs that do not have a traditional event loop possible.
The idea is to move from a plain command line program to one with a window. In order to keep Windows from complaining that your application has locked up, you need to call Window.refresh
on an ongoing basis. With these new changes, the refresh will happen automatically every time you call print
for an Output element and if you update a Multiline that has the 'auto_refresh' parameter set.
This enables a migration of a command line application to a GUI application.
Re-routing
In addition to this auto-refresh capability, there was also an additional method added to Multiline
- reroute_stdout_to_here
. This method will do exactly that, re-route the stdout output to that multiline element. After making this call, all of your print calls will output to that Multiline element. This opens up the flexibility to use print immensely. You can print to any window and any Multiline element within a window.
To make it even easier to route stdout to a Multiline, there's a new cool parameter reroute_stdout
that will cause stdout to be rerouted to go to that Multiline element instead of the console.
Extending this concept further, I decided to add the ability to specify that not only stdout, stderr should go to a specific Multiline Element when it's created, but you can also specify that cprint
output should also be routed to this element. This removes the need to call the cprint setup call cprint_set_output_destination
and makes for some really clean looking code.
What This Means
The implications of all this re-routing and auto-refreshing of stuff are that existing applications can be converted to GUI based applications very easily and can be done in stages.
You can start by simply outputting your text to a window. When you're ready to begin taking in user input, then you can add new Elements to your window so that they can be read in addition to your outputting to Multiline elements.
Demos demo demo are coming
I'll be putting together a series of demos that shows how to build these migratory applications.
The idea is a series of demos the demonstrate how programs can evolve from a command line application into a GUI application in a gradual, evolutionary way rather than a big re-write revolutionary way.
PySimpleGUI 2020-07-12T18:03:15Z
HEADS-UP --- Changes coming.....
I've been checking in some changes this weekend that will impact your code. Things will either look or behave differently.
They are only on GitHub at this point, but will eventually hit PyPI of course. So, if you're concerned, you should try the GitHub version soon.
I rarely do this with the PySimpleGUI project.... but these 2 changes are good ones to have automatically added to everyone's code. If you don't like them, there are options to turn them off.
Table and Tree Row Highlight Colors
Due to the bug in tkinter for Python version 3.7.2 = 3.9+ , there needed to be changes to the Table and Tree code to work around this problem of table colors disappearing. Part of that process included choosing colors for the highlights.
I decided to make the highlight color match the theme being used. So, if you've got a red theme of some kind, then your highlight won't be the standard blue, it'll match your theme colors.
Specifically, the highlight color is the same color as the background and text color of your buttons.
It turned out to look fantastic.
There is also a new parameter added to the Table and Tree elements - selected_row_colors
(colors because there is the text and the background colors)
All Popups (blocking type) are now MODAL
I re-discovered a technique described by @SuperMechaDeathChrist that will make a Window behave like a modal window.
You can make your windows modal by calling the method Window.make_modal()
. You need to make sure your window is finalized first. I may make a parameter at some point.
As a result of this new capability, I've decided to make all popups modal by default.
This means if your popup blocks, you will not be able to interact with your other windows until you close the popup. The modal
parameter controls this. So if you want to turn it off, you can. If your popup is non-blocking, it will not be modal regardless of how you set the parameter.
Hopefully these will all be taken as upgrades!
If you have trouble with these, by all means open an Issue!
PySimpleGUI 2020-07-17T14:06:22Z
Release coming today
Heads-up that there's a more impactful than usual release coming out today for the tkinter port of PySimpleGUI.
It's unusual to make changes that impact existing applications. This release has more than 1 of those kinds of changes. Hopefully it'll work out for the best in the long run.
I usually make these kinds of releases just before or over a weekend so that I can fix any problems over the weekend when usage is likely to be lower than during the week (i.e. less people will be negatively impacted in theory).
There are over 300 changes to the code and I review each change while creating the release notes, so these tend to eat through a day pretty quickly.
If you're waiting on an Issue to be fixed, I'm sorry if it didn't make it into this release and that working on your Issue is likely being pushed out a little while this release is finished. My only defense here is that I'm honestly doing the best I can.
PySimpleGUI 2020-07-17T18:27:17Z
4.25.0 PySimpleGUI 17-Jul-2020
Biggest / most impactful set of changes in a while (fingers crossed)
Modal windows
Multithreaded Window.write_event_value method
stdout re-route to any Multiline
table/tree highlights
k element parameter
-
New "k" parameter for all elements.
-
Same as "key"
-
Created so layouts can be even more compact if desired
-
New docstring for keys (basically anything except a list)
-
-
Popups
-
New text wrap behavior. Will wrap text between \n in user's string
-
All popups are now "modal" unless they are non-blocking (can be turned off using new parameter)
-
-
New button color and table/tree highlight color format
-
Colors can still be tuple (text, background)
-
Can also be a single string with format "text on background" (e.g. "white on red")
-
-
Multiline
-
Automatically refresh window when updating multiline or output elements
-
For cprint use Multiline's autoscroll setting
-
New autoscroll parameter in Multiline.print
-
New parameters to make the print and cprint stuff much easier
-
write_only=False (so that it's not returned when read)
-
auto_refresh=False
-
reroute_stdout=False
-
reroute_stderr=False
-
reroute_cprint=False (removes need to call the cprint cprint_set_output_destination function)
-
-
-
Table / Tree Elements
-
Re-enabled the tk 8.6.9 background color fix again
-
selected_row_colors=(None, None) - tuple or string
-
Automatically sets the selected row color based on the theme colors! (uses the button color)
-
Can use 2 other constants for colors
-
OLD_TABLE_TREE_SELECTED_ROW_COLORS - ('#FFFFFF', '#4A6984') the old blueish color
-
ALTERNATE_TABLE_AND_TREE_SELECTED_ROW_COLORS - (SystemHighlightText, SystemHighlight)
-
-
Tree image caching happens at the element level now
-
-
Window
-
make_modal - new method to turn a window into a modal window
-
modal parameter when window is created. Default is False
-
write_event_value - new method that can be called by threads! This will "queue" an event and a value for the next window.read()
-
Display an error popup if read a closed window 100+ times (stops you from eating 100% of the CPU time)
-
was_closed method added - returns True if a window has been closed
-
-
Combo - don't select first entry if updated with a new set of values
-
Tooltip - fix for stuck-on tooltips
-
New theme_previewer with scrollbars. 3 new parameters
-
cprint - now has all parameters shown in docstring versus using args *kwargs
-
New global variable tclversion_detailed - string with full tkinter version (3 numbers instead of 2)
-
Warning is displayed if tcl version is found to be 8.5.
PySimpleGUI 2020-07-18T12:44:33Z
Cross-porting Ahead
I know this message is going to not be popular with a number of people that have open Issues. I'm really sorry that physics and reality have an impact on this project, but they do.
I have no more than 7 days a week that I can put into this project. They're maxed out and have been since the start 2 year ago. Despite my best efforts I don't always get resolutions to problem to a satisfactory level for the submitter, and it's certainly not done in a timely enough manner from the feedback I get, so I thought this time I should at least give a heads up to maybe try and set expectations a little.
The past several releases have had significant new additions and changes to the TKINTER PORT. For most of you, that's awesome, but for the other roughly 1/2 of the users, that's not so great, yet. They're waiting on these features be added to their PySimpleGUI port. I'm talking about the Qt, Web/Remi, and WxPython users.
Without porting these changes to the other PySimpleGUI platforms, users programs become tied to a specific GUI framework, something PySimpleGUI was developed to not have happen.
I'll be the first to admit that porting / rewriting the same code 3 more times isn't a lot of "fun". So please understand that while you're waiting on your particular Issue to be addressed, I'm not off having the time of my life at your expense. I'm simply busily doing what I think is the right thing for the project.
Last set of updates
Of course, this assumes I make it through getting all these changes moved over. My plan is on getting them done, but there's a chance that they may not all get there by the time I've finally had enough of the project.
The social media attacks on the project, and the more personal attacks have taken their toll. They started the month of the first release and have been unrelenting for 2 years. It's taken this project from something I've been proud of and turned it into a dread.
It is difficult to make conscious and personal sacrifice of ones time and resources only to have it result in being accused of intentionally harming junior engineers and those wishing to learn. I know it's not true, but no one else does. The readers that are considering using PySimpleGUI don't know this and while I hate to admit defeat to cyber bullies and people who simply like to destroy, I'm a human being too with all the difficulties that goes along with that.
It's becoming not worth the fight. I'm sorry if this will leave anyone in a difficult spot. It's not my intention. I saw a bright future ahead for PySimpleGUI, but there are more opponents with agendas that don't fit with PySimpleGUI existing, and I'm afraid they're winning the war of words and perception of what's good for programmers and what's bad, and PySimpleGUI has been deemed as being not just bad, but atrocious and harmful.
I'll do my best to get all these updates into the other ports as quickly as I can.
jhomme 2020-07-18T13:03:36Z Hi,
If you need an ear, I can listen. I just discovered this project a short time ago, and I think it’s amazing.
==========
Jim Homme
Skype: jim.homme
FreeChess: jhomme
Twitter: jimhomme https://twitter.com/jimhome
Facebook: jimhomme
Website: jimhomme.com https://www.jimhomme.com/
From: PySimpleGUI notifications@github.com Sent: Saturday, July 18, 2020 8:45 AM To: PySimpleGUI/PySimpleGUI PySimpleGUI@noreply.github.com Cc: Jim Homme jhomme1028@gmail.com; Manual manual@noreply.github.com Subject: Re: [PySimpleGUI/PySimpleGUI] Announcements (#142)
Cross-porting Ahead
I know this message is going to not be popular with a number of people that have open Issues. I'm really sorry that physics and reality have an impact on this project, but they do.
I have no more than 7 days a week that I can put into this project. They're maxed out and have been since the start 2 year ago. Despite my best efforts I don't always get resolutions to problem to a satisfactory level for the submitter, and it's certainly not done in a timely enough manner from the feedback I get, so I thought this time I should at least give a heads up to maybe try and set expectations a little.
The past several releases have had significant new additions and changes to the TKINTER PORT. For most of you, that's awesome, but for the other roughly 1/2 of the users, that's not so great, yet. They're waiting on these features be added to their PySimpleGUI port. I'm talking about the Qt, Web/Remi, and WxPython users.
Without porting these changes to the other PySimpleGUI platforms, users programs become tied to a specific GUI framework, something PySimpleGUI was developed to not have happen.
I'll be the first to admit that porting / rewriting the same code 3 more times isn't a lot of "fun". So please understand that while you're waiting on your particular Issue to be addressed, I'm not off having the time of my life at your expense. I'm simply busily doing what I think is the right thing for the project.
Last set of updates
Of course, this assumes I make it through getting all these changes moved over. My plan is on getting them done, but there's a chance that they may not all get there by the time I've finally had enough of the project.
The social media attacks on the project, and the more personal attacks have taken their toll. They started the month of the first release and have been unrelenting for 2 years. It's taken this project from something I've been proud of and turned it into a dread.
It is difficult to make conscious and personal sacrifice of ones time and resources only to have it result in being accused of intentionally harming junior engineers and those wishing to learn. I know it's not true, but no one else does. The readers that are considering using PySimpleGUI don't know this and while I hate to admit defeat to cyber bullies and people who simply like to destroy, I'm a human being too with all the difficulties that goes along with that.
It's becoming not worth the fight. I'm sorry if this will leave anyone in a difficult spot. It's not my intention. I saw a bright future ahead for PySimpleGUI, but there are more opponents with agendas that don't fit with PySimpleGUI existing, and I'm afraid they're winning the war of words and perception of what's good for programmers and what's bad, and PySimpleGUI has been deemed as being not just bad, but atrocious and harmful.
I'll do my best to get all these updates into the other ports as quickly as I can.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/PySimpleGUI/PySimpleGUI/issues/142#issuecomment-660477877 , or unsubscribe https://github.com/notifications/unsubscribe-auth/ABRUZJIT5H5367QASD5QL7DR4GKL3ANCNFSM4FTWUH7A .
PySimpleGUI 2020-07-18T19:47:05Z
4.26.0 PySimpleGUI 18-Jul-2020
-
Multi-threaded tkvar initialization location changed so that thread doesn't intialize it now
-
Removed thread key - no longer needed
-
Window.write_event_values - now requires both parms
-
Upgrade button typo
Didn't like how the initialization was happening within the thread's context. Is better to do the init from the mainthread so moved the init code over to the mainthread.
PySimpleGUI 2020-07-18T20:02:25Z
Window.write_event_value
This is likely the most impactful change of the release. While it's only 1 new API call, it causes a LOT fof things to happen in the background (the PySimpleGUI ways of doing things).
This information will be working its way into the Cookbook soon, but until then, this will have to do.
The concept is SO much simpler than before.
Previously, if you wanted a thread and a PySimpleGUI program to communicate, you needed to create a thread and a queue that can be used to exchange information through. The logic to make this happen required you to run your window.read()
call with a timeout so that you can poll for new messages from the thread. window.read(timeout=100)
This new call changes all of that and simplifies it down to where your read call remains: window.read()
. Rather than polling for a change to the queue you pend for an event via the read. A queue is automatically set up for you so that you no longer need that step either.
This leaves the question:
How can a thread signal a window that it has information?
The answer is the inverse of event, values = window.read()
Instead of reading an event and a dictionary of values, you write an event and a value that will be placed into a dicitonary of other items.
The call is defined as:
If a thread wanted to cause an event "-THREAD-"
and an associated value of 1234
to be part of the values dictionary, then the call would be:
You can see how all this works on this trinket page:
https://pysimplegui.trinket.io/demo-programs#/multi-threaded/multi-threaded-write-event-value
It has a very simple demo that allows you to create multiple threads that all communicate using this simple mechanism.
Here's a simplified version of the code (less comments):
import threading
import time
import PySimpleGUI as sg
THREAD_EVENT = '-THREAD-'
def the_thread(window):
"""
The thread that communicates with the application through the window's events.
Once a second wakes and sends a new event and associated value to the window
"""
i = 0
while True:
time.sleep(1)
window.write_event_value('-THREAD-', (threading.current_thread().name, i)) # Data sent is a tuple of thread name and counter
i += 1
def main():
"""
The demo will display in the multiline info about the event and values dictionary as it is being
returned from window.read()
Every time "Start" is clicked a new thread is started
Try clicking "Dummy" to see that the window is active while the thread stuff is happening in the background
"""
layout = [ [sg.Text('Output Area - cprint\'s route to here', font='Any 15')],
[sg.Multiline(size=(65,20), key='-ML-', autoscroll=True, reroute_stdout=True, write_only=True, reroute_cprint=True)],
[sg.T('Input so you can see data in your dictionary')],
[sg.Input(key='-IN-', size=(30,1))],
[sg.B('Start A Thread'), sg.B('Dummy'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True: # Event Loop
event, values = window.read()
sg.cprint(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event.startswith('Start'):
threading.Thread(target=the_thread, args=(window,), daemon=True).start()
if event == THREAD_EVENT:
sg.cprint(f'Data from the thread ', colors='white on purple', end='')
sg.cprint(f'{values[THREAD_EVENT]}', colors='white on red')
window.close()
if __name__ == '__main__':
main()
PySimpleGUI 2020-07-19T16:27:15Z
Headsup on print performance
Hopefully this risk will be a payout rather than a big problem. I'm giving it a try.
Normally, when you perform an update to an Element, you must wither call read or refresh for the element.
The 4.25.0 release has 2 changes.
-
The Multline has an option that controls this auto-refresh. It is DISABLED by default
-
The Output element, however has this option always turned out. Hopefully this won't cause problems. If it does, then I will add some controls over enable/disabling.
The hope is that you won't have to call .refresh anymore for these "common operations". It's common operation here is adding a new line to be output in a multiline. So, there's an option to auto-refresh and you can remove your calls to refresh as a result. This is not true for other elements, but would consider it. This is going to require some cross porting.
The short version - start using Multiline elements for your print command.
THREAD
SO FAR I've been lucky and have been able to call both print and cprint from threads without having a crash.
I've careful about the order of operations and hoping this capability remains.
You can modify the above example and end up with this code, which does function despite the cprint being called from the thread. Likely sheet luck so proceed with caution.
def the_thread(window):
"""
The thread that communicates with the application through the window's events.
Once a second wakes and sends a new event and associated value to the window
"""
i = 0
while True:
time.sleep(1)
window.write_event_value('-THREAD-', (threading.current_thread().name, i)) # Data sent is a tuple of thread name and counter
sg.cprint('This is cheating from the thread', c='white on green')
i += 1
PySimpleGUI 2020-07-19T20:39:52Z
Cookbook Main Docs Update #1
The first of some cookbook updates was started and some of it completed today.
stdout & cprint routing
The expanded cprint and stdout routing capabilities were explained further. The hope is that people will start to move to using the Multiline Element for doing text output.
Several of the sections were updated including this one:
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-printing-34-print-to-multiline-element
There were a lot of things added so hopefully enough examples were cprovided.
Threading - Long operations
A new Recipe was added that addressed the classic problem of having an operation that takes too long to do inline in your GUI. Through the magic of the Window.write_event_value
method these long-running operations are now very easy (borderline trivial) to handle.
Modal windows
Modal Windows were added to the main docs under the Window section. More info needs to be expanded throughout the documentation.
There will certainly be a number of changes in the call reference as well.
'
PySimpleGUI 2020-07-22T13:49:34Z
Welcome the New Event Loop... (for Multiple Windows)
The changes required for this were to portions of the code that are particularly tricky and not the most "fun" code to work on, but the results tend to make it worth the effort.
I think having solved the Modal problem last go-around caused me to re-examine the multi-window design patterns.
They suck.
They always kinda have because you end up implementing "Round Robin Scheduling" yourself by running multiple windows with multiple timeouts. You're "time slicing". That kinda sorta works.... sometimes...not. It usually works out OK, but depends on the type of interactions.
I've known it's klunky and difficult. That's not been the problem. It's doing something about it.
The approach, more cowbell
I looked at providing more mechanisms on the user side, but that would have been more patchwork. Stuff like new window types for multiple window handling, etc.
The answer has to be that it's Simple. Problems like these can "collapse" in on themselves and work through to a logical, simple solution. It clearly belonged inside PySimpleGUI.
This one, like the threaded, collapsed down to a single call.
We've got an event loop that gives events and values, why not keep doing the same, but just add the window and call it done?
The Multiple Window Event Loop
while True: # Event Loop
window, event, values = sg.read_all_windows()
if window is None:
print('exiting because no windows are left')
break
Simple Demo
import PySimpleGUI as sg
WIDTH = 500
LOC1 = (500,500)
LOC2 = (LOC1[0]+WIDTH, LOC1[1])
LOC3 = (LOC2[0]+WIDTH, LOC1[1])
layout1 = [ [sg.Text('My Window')],
[sg.Input(k='-IN-'), sg.Text(size=(12,1), k='-OUT-')],
[sg.CB('Check 1', k='-CB1-', enable_events=True), sg.CB('Check 2', k='-CB2-', enable_events=True), sg.CB('Mirror on Window 2', enable_events=True, k='-CB3-')],
[sg.Button('Go'), sg.B('Dummy'), sg.Button('Exit')] ]
window1 = sg.Window('Window 1 Title', layout1, finalize=True, location=LOC1)
layout2 = [ [sg.Text('My Window')],
[sg.Input(k='-IN-'), sg.Text(size=(12,1), k='-OUT-')],
[sg.CB('Check 1', k='-CB1-'), sg.CB('Check 2', k='-CB2-')],
[sg.Button('Go'), sg.B('Popup'), sg.Button('Exit')] ]
window2 = sg.Window('Window 2 Title', layout2, finalize=True, location=LOC2)
while True: # Event Loop
window, event, values = sg.read_all_windows()
if window is None and event != sg.TIMEOUT_EVENT:
print('exiting because no windows are left')
break
print(window.Title, event, values) if window is not None else None
if event == sg.WIN_CLOSED or event == 'Exit':
window.close()
if event == 'Go':
window['-OUT-'].update(values['-IN-'])
try: # try to update the other window
if window == window1:
window2['-OUT-'].update('The other window')
else:
window1['-OUT-'].update('The other window')
except:
pass
if event == 'Dummy':
sg.popup_non_blocking('Non-blocking popup')
if event == 'Popup':
sg.popup('plain popup')
try:
if window == window1 and values['-CB3-']:
window2['-CB1-'].update(values['-CB1-'])
window2['-CB2-'].update(values['-CB2-'])
except:
pass
How read_all_windows()
works
If it's not simple, it's not going into PySimpleGUI.
It returns events for each of the windows you have "open". You must finalize or read the windows that you want included.
The function returns simply a series of events, stuff that happens. When it does, then you are given the Window that had the event and the event & values variables as you're used to getting.
Adding Window Specific Code
An if statement... one more level of check, will be added to your loop, or more likely, in a function:
Async too
You can still run your reads with timeout values so that you can async capabilities. Add a timeout to your read_all just like read:
Not fully checked in.. only in the Development Branch on GitHub
If you want it, go here:
https://raw.githubusercontent.com/PySimpleGUI/PySimpleGUI/Dev-latest/PySimpleGUI.py
Version 4.26.0.2
PySimpleGUI 2020-07-22T17:37:52Z
The Easter Egg Icons
In case you've not yet had an error like created a bad layout, or tried to lookup a badly spelled key, then you've not hit a random icon from a selection of several that were recently part of the release.
They all begin with ICON_BASE64_
Example:
ICON_BASE64_PALM
In case you missed the new image parameter for popups, you can test these by using the image parameter to popup
.
PySimpleGUI 2020-07-22T18:31:21Z
read_all_windows
Merged on GitHub
OK, if you use the newest PySimpleGUI.py from GitHub it will be 4.26.0.2 and has the new function read_all_windows.
Hoping it's all going to work out ok!
PySimpleGUI 2020-07-23T22:03:23Z
The sg.main()
"Test Harness" / Control Center
If you are troubleshooting a problem, then you've probably already called sg.main()
in order to collect version numbers of things like tkinter.
This little program within the package is your gateway to a number of features that you may find handy beyond grabbing version numbers.
Launching
There are a number of ways of starting up this control center. You can directly call it by calling sg.main()
. You can simply "run" the PySimpleGUI.py file if you have one locally. And you can run it if you've installed it using pip by typing (on a Windows machine):
python -m PySimpleGUI.PySimpleGUI
Here's what you're typically greeted with at the moment:
The Theme Previewer
The previewer button was just added. It gives you a very fast way to see several themes that may fit your vision. What's different about this theme previewer is that a search string has been added.
Here is a screencapture of a session that shows searching for "Green" themes and also all of the "Dark" themes.
Upgrade to the Latest From GitHub
The red button with the clever name:
will upgrade your pip installed version with the version of PySimpleGUI located in the Master Branch on GitHub. It seems to work well. I'm nervous about the feature, but given how often new features and bug fixes are posted to GitHub that users need to try prior to releasing to PyPI, it seems like one of the easiest ways to get people to do an upgrade from GitHub.
PySimpleGUI 2020-07-24T12:11:10Z
Cookbook Updates
There have been a number of Cookbook additions over the past week. Included were:
-
More cprint capabilities with the new Multiline parameters (tkinter only currently)
-
Multi-threaded Recipe for "Long Operations" that shows usage of the new
write_event_value
function call -
convert_to_bytes
PIL-based function
One of the most important ones I think was the last one, the addition of the conversion function. This one function can unlock all sorts of amazing capabilities from displaying nearly any image format to making thumbnails to resizing images to use on buttons.
Justification - the glaring omission (coming soon... honest)
I'm still not where I want to be with the Cookbook updates. There's an important update that needs to happen in the Cookbook as well as the YouTube video needs to be remade on the tropic of element justification. This is particularly important since the mechanism has been standardized across all of the ports.
PySimpleGUI 2020-07-26T18:33:08Z
Multi-window Demo of Colorization Demo
[EDIT] This multi-window demo was released to the Colorization Repo - https://github.com/PySimpleGUI/PySimpleGUI-Photo-Colorizer
It shows 4 windows. One is the main control window the other 3 are video windows.
There is no direct relationship between these windows. No one is the master, although I've written this specific application to close the entire program when the smallest "control window" is closed. This is the window that is first shown.
My overall all goal with this design is to leave the capabilities as open and available to the user as possible. This means that if you want a multi-window program with a 'master' window behavior, you can have that, but you don't have to.
Considering everything it does, this seems like one of the most efficient ways to accomplish something like this.
def make_video_window(title, location):
return sg.Window(title, [[sg.Image(key='-IMAGE-')]], finalize=True, margins=(0,0), element_padding=(0,0), location=location)
def convert_cvt_to_data(cv2_frame):
return cv2.imencode('.png', cv2_frame)[1].tobytes()
def main():
# --------------------------------- The GUI ---------------------------------
layout = [ [sg.Text('Colorized Webcam Demo', font='Any 18')],
[sg.Button('Start Webcam', key='-WEBCAM-'), sg.Button('Exit')]]
# ----- Make the starting window -----
window_start = sg.Window('Webcam Colorizer', layout, grab_anywhere=True, finalize=True)
# ----- Run the Event Loop -----
cap, playback_active = None, False
while True:
window, event, values = sg.read_all_windows(timeout=10)
if event == 'Exit' or (window == window_start and event is None):
break
elif event == '-WEBCAM-': # Webcam button clicked
if not playback_active:
sg.popup_quick_message('Starting up your Webcam... this takes a moment....', auto_close_duration=1, background_color='red', text_color='white', font='Any 16')
window_start['-WEBCAM-'].update('Stop Webcam', button_color=('white','red'))
cap = cv2.VideoCapture(0) if not cap else cap
window_raw_camera = make_video_window('Your Webcam Raw Video', (300,200))
window_gray_camera = make_video_window('Video as Grayscale', (1000,200))
window_colorized_camera = make_video_window('Your Colorized Video', (1700,200))
playback_active = True
else:
playback_active = False
window['-WEBCAM-'].update('Start Webcam', button_color=sg.theme_button_color())
window_raw_camera.close()
window_gray_camera.close()
window_colorized_camera.close()
elif event == sg.TIMEOUT_EVENT and playback_active:
ret, frame = cap.read() # Read a webcam frame
# display raw image
if window_raw_camera:
window_raw_camera['-IMAGE-'].update(data=convert_cvt_to_data(frame))
# display gray image
gray_3_channels = convert_to_grayscale(frame)
if window_gray_camera:
window_gray_camera['-IMAGE-'].update(data=convert_cvt_to_data(gray_3_channels))
# display colorized image
if window_colorized_camera:
window_colorized_camera['-IMAGE-'].update(data=convert_cvt_to_data(colorize_image(cv2_frame=gray_3_channels)))
# if a window closed
if event is None:
if window == window_raw_camera:
window_raw_camera.close()
window_raw_camera = None
elif window == window_gray_camera:
window_gray_camera.close()
window_gray_camera = None
elif window == window_colorized_camera:
window_colorized_camera.close()
window_colorized_camera = None
# If playback is active, but all camera windows closed, indicate not longer playing and change button color
if playback_active and window_colorized_camera is None and window_gray_camera is None and window_raw_camera is None:
playback_active = False
window_start['-WEBCAM-'].update('Start Webcam', button_color=sg.theme_button_color())
# ----- Exit program -----
window.close()
if __name__ == '__main__':
main()
When run, you'll see 3 video windows and a startup window. You can close any of them that you won't want. I could have simply started all 3 video windows and not had a startup window at all, but I wanted a way to "restart".
Notice how the blackboard in the background became a red-board following the colorization. Enjoy my "Daily Affirmation"....
PySimpleGUI 2020-07-27T19:20:33Z
Multi-Monitor Window Locations
This is something I'll be adding to the docs and Cookbook.
I can only test this on Windows, so I'm not sure how it'll work out on Linux / Mac.
I've discovered on my system that if I want to locate windows on displays other than my primary window, then I can do that by "simply" setting the location parameter to be at the location using a delta from the (0,0) coordinate being on my primary monitor's upper left corner.
I run this CPU Core Usage widget on the monitor to the left of my primary monitor. To create the window in the location on my left monitor, I set the location parameter in my Window
creation to be:
Similarly, if I want to locate a window on the monitor to the right of my main monitor, I set a location that is beyond the coordinates of my primary monitor.
In this case, a location of (2565,800) placed the window on the monitor to my right, near the bottom edge.
PySimpleGUI 2020-07-28T08:25:49Z
New Versions of Rainmeter Style Widgets
In the demo folder you'll find a number of the desktop widgets have been changed to accept a parameter that determines where on the screen to location the widget.
Previously when I performed a "start all widgets", I had to always manually move 10 widgets onto 3 different monitors.
Now with this parameter, the widgets are placed exactly on the correct monitor in the correct location. (See the tip in the previous announcements post on how to do this)
My code simply changed by adding this:
if __name__ == '__main__':
if len(sys.argv) > 1:
location = sys.argv[1].split(',')
location = (int(location[0]), int(location[1]))
else:
location = (None, None)
main(location)
When I involve / start the widget, I add on the command line the location I would like it to be placed. My "Launcher" application (also placed automatically in the right location) now starts them with specific locations in mind:
run_py( r'C:\Python\PycharmProjects\GooeyGUI\DemoPrograms\Demo_Desktop_Widget_CPU_Top_Processes.py', '2967,43')
At some point, if a "Rainmeter" style app was made, there could be a settings file for the locations, but for me, this hardcoded location is great.
PySimpleGUI 2020-07-30T12:24:10Z
Multi-window Design Patterns Updated
All 4 of the Multi-window demo programs have been modified to use the new read_all_windows()
architecture.
The results were astonishing. They each were significantly shorter, less complex, more readable, and more efficient as there is no longer ANY polling involved.
The combination of this read_all_windows
call and the write_event_value
call for threads means that both of the architectural situations where polling was involved have now turned into purely event driven. This means the code is the most efficient it could possibly be. It was greatly fortuitous that both of these architectures were cleaned up at the same time. While not related in their purpose, these were the two areas that were the least efficient due to the polling.
I'm now pondering if the system tray stuff can/should also be included in a read-all situation. This would make their code efficient too.
I simultaneously dread and look forward to getting this capability cross-ported. This multi-window architecture was non-trivial to implement and there is no guarantee that it will work on the other ports of PySimpleGUI the same way. I'm REALLY hoping it will though. If it does, party time! If not, well, the primary port using tkinter will rock while the others struggle a tad in this area.
Time will tell, but for now, enjoy the new capabilities. I can't wait to see what people come up with.
PySimpleGUI 2020-08-02T13:24:35Z
Possible Release Today.....
There has been a lot of new features piling up again in the tkinter port. The GitHub version 4.26.0.18 means there's been at least 18 changes of decent size.
read_all_windows
with timeout=0
With timeout=0 you can do more of these "realtime" kinds of applications such as this screensaver type of application.
Was finally able to get the special case of timeout=0 done for the multi-window reads. This was an important addition as it's one of the last pieces needed prior to releasing to PyPI.
read_all_windows
Supports Keyboard and Mouse-wheel Events
Also added this weekend was support for the return_keyboard_events
in a multi-window environment. These needed to be added in addition to the already functional enable_events
parameters specified at the element level.
Converting single to multi-window
One of the reasons that I write so many of these Demo Applications is because it's the only way to get a feel for what it's like to use the APIs. First it has to work on paper, then it has to work, and finally it has to be simple to deploy. The demos are an important step in this process.
So, you're seeing lots of these mutli-window programs being added or others converted for this reason.
Floating Palettes
One excellent example use of multiple windows is in drawing programs. In particular things like the drawing palette like you see in Photoshop.
There is a drawing kind of demo today that looks like this:
It's an ideal candidate to transform into a more traditional drawing type of application that uses multiple windows. The radio buttons on the right side of the window were split out into a second window. The result is this 2-window solution.
The nice thing about the read_all_windows()
interface is that it allows you to keep your existing event loop in place and requires very little modifications. Rather than getting events from a specific window, now you get events from your entire application. You don't care what window they come from, but if you do need to interact with the window, you can because you're given the window that caused the event.
Cross-porting ahead
Unfortunately there's going to have to be a bit of work to get the other ports of PySimpleGUI working with this same architecture. I assume I can use a similar underlying architecture that I did with tkinter for Qt, Wx, Remi, but there are no guarantees. I just hope that they don't soak up weeks of time.
Not only does the multi-window support need to be ported, but so does the new multi-threaded write_event_value
call.
It's been a pretty crazy couple of weeks with the new features.
Funding
[edit]
I'm sure regular readers already understand that the PySimpleGUI project is struggling financially. While what I wrote earlier today I wouldn't call just complaining, but more of a display of disappointment in the situation, I still don't want negative junk being attached to these otherwise positive messages and activities. So, I'm making an edit.
I think the better approach is going to be to be more up front and concrete about the situation in the documentation with concrete suggestions. I want PySimpleGUI to be as free as it can be, especially for individuals. Maybe corporate users need guidelines. Complaining isn't the answer, that I'm sure of. So, my apologies for anything I've posted that comes across that way. It's just challenging and at times frustrating, and being a human being the frustration comes through sometimes. So, my apologies on this Sunday if I brought anything negative to your inbox. It wasn't meant that way.
Thank you for the emails and messages!
Thanks to everyone that's sent the thank you messages and shows of appreciation. I do not in any way want to diminish the "value" those have. They have been sustaining on the emotional side and without them, I wouldn't be able to endure the financial challenges.
Take care everyone
PySimpleGUI 2020-08-03T10:04:30Z
4.27.4 PySimpleGUI 3-Aug-2020
Multi-window support done right!
New capabilities for printing, Multiline
Main app additions
Theme searching
-
read_all_windows - function that reads all currently open windows.
-
Finally the efficient multi-window solution
-
No longer need to do round-robin type scheduling
-
Easily convert existing programs from single to multi-windows
-
Demo programs with multi-window design patterns all updated
-
Ideal for "floating palette / toolbar" window adds-ons
-
Can read with timeout including timeout=0
-
-
theme_previewer
-
search option
-
button in main app
-
reset to previous theme following preview
-
-
Sponsor button in main app
-
Theme previewer in main app
-
Progress bar
-
colors can use the single string "foreground on background" color format
-
update_bar combined with update for a single update interface
-
-
Better element key error handling
-
3 options to control how lookup errors are handled
-
popup now shows
-
file, function, line #, actual line of code with error
-
erroneous key provided
-
best matching key
-
-
will automatically try to continue with best matching key
-
can assert with key error if desired (true by default)
-
-
fix for get item
-
Up/down arrow bindings for spinner if enabling events
-
Multiline
-
new justification parameter on creation and update
-
print - justification parameter added
-
-
cprint - justification parameter added - note tricky to set color of single word but possible
-
Added mousewheel for Linux return_keyboard_events enabled
-
Added get_globals function for extending easier
-
Refactored callbacks
-
Image element - can clear image by not setting any parameters when calling update
-
Column Element's Widget member variable now being set
-
Window's starting window location saved
-
Early experimental "Move all windows in sync" when using grab_anywhere (coming soon)
-
Fixes for Python 3.4 (no f-strings! UGH... damned Pi's)
PySimpleGUI 2020-08-03T10:07:09Z
Release 4.27.4
Sorry that it took 5 releases to get this one right.
You would think I would get the whole Raspberry Pi on Python version 3.4 down by now, but sometimes an f-string slips through. After catching it, there was a whole string of errors. When you work on releases at 5 AM this stuff happens. Hopefully the release will be a smashing success!
I'm more excited about this one than any in a long while due to the correct handling of multi-windows. Relieved was able to pull it off using tkinter. The cross-porting mess is ahead, but hopefully it'll go smoothly.
PySimpleGUI 2020-08-03T19:54:35Z
4.28.0 PySimpleGUI 3-Aug-2020
Element pinning for invisibility!
-
Better visible/invisible handling
-
pin - new function to place an element in a layout that will hold its position
-
border_width added to Canvas and Graph (so that they will default to 0)
-
-
Combobox
-
button color will match theme's button color
-
background color set correctly when readonly indicated
-
-
Spin element
-
spin button color set to background color of spinner
-
spin arrow color automatically set to text color
-
-
Bad element key popup - fix for displaying correct line info in some situations
PySimpleGUI 2020-08-03T20:06:05Z
Element Pinning - Visibility finally nailed... err..... pinned
Why 6 PyPI releases today?
Well, the first 5 were due to it being o-dark-thirty and lots of mistakes were made
The 6th was to get the new "pin" function released quickly.
This "pin" function will reserve the spot that an element has in a layout. This is done by using 2 extra elements. One is a Column element with (0,0) padding so that no extra space is used. The other is a tiny dot, 1 pixel, that is a Canvas. This little dot will remain after you make your element invisible. It's not visible, but it's there and will take up room in your window. It's a very small price to pay for sanity.
This demo program was updated as well to include the pin function. Previously the pin function was in the demo but now it's part of PySimpleGUI itself.
import PySimpleGUI as sg
"""
Demo - "Pinning" an element into a location in a layout
Requires PySimpleGUI version 4.28.0 and greater
When using the tkinter port of PySimpleGUI, if you make an element invisible and then visible again,
rather than the element appearing where it was originally located, it will be moved to the bottom
of whatever it was contained within (a window or a container element (column, frame, tab))
This demo uses a new "pin" function which will place the element inside of a Column element. This will
reserve a location for the element to be returned.
Additionally, there will be a 1 pixel Canvas element inside the "pin".
This will cause the area to shrink when the element is made invisible. It's a weird tkinter thing. Not sure
exactly why it works, but it works.
For other ports of PySimpleGUI such as the Qt port, the position is remembered by Qt and as a
result this technique using "pin" is not needed.
Copyright 2020 PySimpleGUI.org
"""
layout = [ [sg.Text('Hide Button or Input. Button3 hides Input. Buttons 1 & 2 hide Button 2')],
[sg.pin(sg.Input(key='-IN-'))],
[sg.pin(sg.Button('Button1')), sg.pin(sg.Button('Button2')), sg.B('Button3')],
]
window = sg.Window('Visible / Invisible Element Demo', layout)
toggle = toggle_in = False
while True: # Event Loop
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event in ('Button1', 'Button2'):
window['Button2'].update(visible=toggle)
toggle = not toggle
if event == 'Button3':
window['-IN-'].update(visible=toggle_in)
toggle_in = not toggle_in
window.close()
PySimpleGUI 2020-08-03T21:58:56Z
PySimpleGUI 2020-08-05T21:03:04Z
Collapsible Sections Demo and Recipe
Added both a demo program and a Recipe so that the pin
function is documented / demonstrated.
import PySimpleGUI as sg
"""
Demo - "Collapsible" sections of windows
This demo shows one techinique for creating a collapsible section (Column) within your window.
It uses the "pin" function so you'll need version 4.28.0+
A number of "shortcut aliases" are used in the layouts to compact things a bit.
In case you've not encountered these shortcuts, the meaning are:
B = Button, T = Text, I = Input = InputText, k = key
Also, both methods for specifying Button colors were used (tuple / single string)
Section #2 uses them the most to show you what it's like to use more compact names.
To open/close a section, click on the arrow or name of the section.
Section 2 can also be controlled using the checkbox at the top of the window just to
show that there are multiple way to trigger events such as these.
Copyright 2020 PySimpleGUI.org
"""
SYMBOL_UP = '▲'
SYMBOL_DOWN = '▼'
def collapse(layout, key):
"""
Helper function that creates a Column that can be later made hidden, thus appearing "collapsed"
:param layout: The layout for the section
:param key: Key used to make this seciton visible / invisible
:return: A pinned column that can be placed directly into your layout
:rtype: sg.pin
"""
return sg.pin(sg.Column(layout, key=key))
section1 = [[sg.Input('Input sec 1', key='-IN1-')],
[sg.Input(key='-IN11-')],
[sg.Button('Button section 1', button_color='yellow on green'),
sg.Button('Button2 section 1', button_color='yellow on green'),
sg.Button('Button3 section 1', button_color='yellow on green')]]
section2 = [[sg.I('Input sec 2', k='-IN2-')],
[sg.I(k='-IN21-')],
[sg.B('Button section 2', button_color=('yellow', 'purple')),
sg.B('Button2 section 2', button_color=('yellow', 'purple')),
sg.B('Button3 section 2', button_color=('yellow', 'purple'))]]
layout = [[sg.Text('Window with 2 collapsible sections')],
[sg.Checkbox('Blank checkbox'), sg.Checkbox('Hide Section 2', enable_events=True, key='-OPEN SEC2-CHECKBOX')],
#### Section 1 part ####
[sg.T(SYMBOL_DOWN, enable_events=True, k='-OPEN SEC1-', text_color='yellow'), sg.T('Section 1', enable_events=True, text_color='yellow', k='-OPEN SEC1-TEXT')],
[collapse(section1, '-SEC1-')],
#### Section 2 part ####
[sg.T(SYMBOL_DOWN, enable_events=True, k='-OPEN SEC2-', text_color='purple'),
sg.T('Section 2', enable_events=True, text_color='purple', k='-OPEN SEC2-TEXT')],
[collapse(section2, '-SEC2-')],
#### Buttons at bottom ####
[sg.Button('Button1'),sg.Button('Button2'), sg.Button('Exit')]]
window = sg.Window('Visible / Invisible Element Demo', layout)
opened1, opened2 = True, True
while True: # Event Loop
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event.startswith('-OPEN SEC1-'):
opened1 = not opened1
window['-OPEN SEC1-'].update(SYMBOL_DOWN if opened1 else SYMBOL_UP)
window['-SEC1-'].update(visible=opened1)
if event.startswith('-OPEN SEC2-'):
opened2 = not opened2
window['-OPEN SEC2-'].update(SYMBOL_DOWN if opened2 else SYMBOL_UP)
window['-OPEN SEC2-CHECKBOX'].update(not opened2)
window['-SEC2-'].update(visible=opened2)
window.close()
PySimpleGUI 2020-08-06T11:45:49Z
Favorite GUI Framework Survey on Reddit
https://www.reddit.com/r/Python/comments/i4k7aw/whats_your_favourite_gui_framework/
It's unusual for someone to use Reddit's voting feature for this purpose. I've never seen an actual survey like this on GUI Frameworks.
If you're a fan and want to represent PySimpleGUI, this is your opportunity!
PySimpleGUI 2020-08-07T11:39:46Z
Recipe for read_all_windows
Added a new recipe that will show you how to use the new read_all_windows
capability. It demonstrates a couple of important capabilities including having 1 window update the other as well as re-opening a window that was previously closed.
You'll find program used in the Recipe in the demo program area.
Here's the location of the Recipe:
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-multiple-windows-read_all_windows
This demo has been posted on Trinket was well:
https://pysimplegui.trinket.io/demo-programs#/multiple-windows/two-windows-with-re-open
PySimpleGUI 2020-08-12T11:14:07Z
Support - Why StackOverflow isn't the place to go......
There are at least 3 important reasons that posting an Issue here is a better idea than StackOverflow:
-
The project no longer checks it. It's hard enough supplying support here. Monitoring a list of sites for problems isn't sustainable anymore.
-
The advice might not be the best - Let's assume that it is the best for argument sake. It's the best right now...PySimpleGUI is a newer, active, dynamic, living package. Things change, techniques change, sometimes radically. What used to be appropriate to do is no longer how it's done. Picking up really old answers isn't the best way to go and could be making more difficult on yourself.
-
Support IS available right here on the GitHub, by people that probably know it better than anyone else. Maybe StackOverflow is the place to go for some computing things, but it's not for this package.
Additionally, with the "stupid form", you get a checklist of things you can do, right now, to help yourself. There are materials meant to help you through problems. They're not super-difficult to find and use, and more is being put into that right now.
PySimpleGUI 2020-08-12T12:00:47Z
Dark Grey 9 Theme & Customized Titlebar
A new theme has been added and this demo of a custom titlebar shows using it.
I've been wanting to add something like this to the Cookbook. This is a good first step as the code is at least here and ready to use.
You'll find the demo here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Titlebar_Custom_Dark_Theme.py
I'll save you the trouble of going there and paste the code directly below:
import PySimpleGUI as sg
"""
Demo showing how to remove the titlebar and replace with your own
Note that you cannot minimize these kinds of windows because they do not
have an icon representing them on the taskbar
Copyright 2020 PySimpleGUI.org
"""
# If not running 4.28.0.4+ that has the DarkGrey8 theme, then uncomment to get it added.
# DarkGrey8 = {'BACKGROUND': '#19232D',
# 'TEXT': '#ffffff',
# 'INPUT': '#32414B',
# 'TEXT_INPUT': '#ffffff',
# 'SCROLL': '#505F69',
# 'BUTTON': ('#ffffff', '#32414B'),
# 'PROGRESS': ('#505F69', '#32414B'),
# 'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0,
# }
#
# sg.theme_add_new('DarkGrey8', DarkGrey8)
def title_bar(title):
bg = sg.theme_input_background_color()
return [sg.Col([[sg.T(title, background_color=bg )]], pad=(0, 0), background_color=bg),
sg.Col([[sg.Text('❎', background_color=bg, enable_events=True, key='Exit')]], element_justification='r', k='-C-', pad=(0, 0), background_color=bg)]
def main():
sg.theme('DarkGrey8') # Requires 4.28.0.4 or the code at the tiop
layout = [
title_bar('Window Title'),
[sg.T('This is normal window text. The above is the fake "titlebar"')],
[sg.T('Input something:')],
[sg.Input(key='-IN-'), sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Go')] ]
window = sg.Window('Window Title', layout, no_titlebar=True, grab_anywhere=True, keep_on_top=True, margins=(0,0), finalize=True)
window['-C-'].expand(True, False, False)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Go':
window['-OUT-'].update(values['-IN-'])
window.close()
if __name__ == '__main__':
main()
PySimpleGUI 2020-08-12T14:31:25Z
Custom titlebar WITH MINIMIZE
If you liked the previous post that has a window with a custom titlebar, then you'll really like this one as you can minimize this window... or at least it appears like it's been minimized. I'll add a proper "title" capability shortly.
This version - if you request the custom-titlebar window be minimize, it cleverly hides the window and creates another hidden window, minimizes the hidden window so that something shows up on the taskbar. When that hidden window is restored, then the custom title-bar window is restored and the hidden window is destroyed.
import PySimpleGUI as sg
"""
Demo showing how to remove the titlebar and replace with your own
You CAN minimize this version as it uses a dummy window that appears on the taskbar
Copyright 2020 PySimpleGUI.org
"""
# If not running 4.28.0.4+ that has the DarkGrey8 theme, then uncomment to get it added.
# DarkGrey8 = {'BACKGROUND': '#19232D',
# 'TEXT': '#ffffff',
# 'INPUT': '#32414B',
# 'TEXT_INPUT': '#ffffff',
# 'SCROLL': '#505F69',
# 'BUTTON': ('#ffffff', '#32414B'),
# 'PROGRESS': ('#505F69', '#32414B'),
# 'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0,
# }
#
# sg.theme_add_new('DarkGrey8', DarkGrey8)
def dummy_window():
"""
Creates an invisible window that is minimized to the taskbar
As soon as something happens to the window, it is closed and the function
returns.
The FocusIn event is set so that if the user restores the window from the taskbar, then the read
wille return, the window will be closed, and the function will return
"""
layout = [[sg.T('You will not see this')]]
window = sg.Window('Window Title', layout, finalize=True, alpha_channel=0)
window.minimize()
window.bind('<FocusIn>', '-FOCUS-')
window.read(close=True)
def title_bar(title):
bg = sg.theme_input_background_color()
return [sg.Col([[sg.T(title, background_color=bg )]], pad=(0, 0), background_color=bg),
sg.Col([[sg.T('_', background_color=bg, enable_events=True, key='-MINIMIZE-'),sg.Text('❎', background_color=bg, enable_events=True, key='Exit')]], element_justification='r', k='-C-', pad=(0, 0), background_color=bg)]
def main():
sg.theme('DarkGrey8')
layout = [ title_bar('Window Title'),
[sg.T('This is normal window text. The above is the fake "titlebar"')],
[sg.T('Input something:')],
[sg.Input(key='-IN-'), sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Go')] ]
window = sg.Window('Window Title', layout, resizable=True, no_titlebar=True, grab_anywhere=True, keep_on_top=True, margins=(0,0), finalize=True)
window['-C-'].expand(True, False, False)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == '-MINIMIZE-':
window.hide()
dummy_window()
window.un_hide()
if event == 'Go':
window['-OUT-'].update(values['-IN-'])
window.close()
if __name__ == '__main__':
main()
PySimpleGUI 2020-08-13T12:43:34Z
Custom Titlebar WITH Minimize
This is pretty cool! It took some tricks, but it works. I've never seen a titlebar on Windows, particularly with tkinter, that entirely matched the window. The code uses themes so that the titlebar will match the theme. It doesn't have to be the dark theme that was custom defined in the demo.
Maybe dark red is your thing:
Or light green 5
You don't even need to choose the same pieces of the color theme for the bar. Experiment. Maybe make it the same as the button colors. Lots of possibilties.
PySimpleGUI 2020-08-14T12:07:24Z
Two new themes
Recently added these 2 new themes to the official list of PySimpleGUI themes. Will be in the next PyPI release. You can use the code below in the meantime to define them yourself.
# If not running 4.28.0.4+ that has the DarkGrey8 theme, then uncomment to get it added.
DarkGrey8 = {'BACKGROUND': '#19232D',
'TEXT': '#ffffff',
'INPUT': '#32414B',
'TEXT_INPUT': '#ffffff',
'SCROLL': '#505F69',
'BUTTON': ('#ffffff', '#32414B'),
'PROGRESS': ('#505F69', '#32414B'),
'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0,
}
sg.theme_add_new('DarkGrey8', DarkGrey8)
sg.theme('DarkGrey8')
DarkGrey9 (Based on Discord)
# If not running 4.28.0.4+ that has the DarkGrey8 theme, then uncomment to get it added.
DarkGrey9 = {'BACKGROUND': '#36393F',
'TEXT': '#DCDDDE',
'INPUT': '#40444B',
'TEXT_INPUT': '#ffffff',
'SCROLL': '#202225',
'BUTTON': ('#202225', '#B9BBBE'),
'PROGRESS': ('#202225', '#40444B'),
'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0,
}
sg.theme_add_new('DarkGrey9', DarkGrey9)
sg.theme('DarkGrey9')
PySimpleGUI 2020-08-17T09:24:58Z
Please Test Your Fixes - would like to release soon
If you've filed an Issue and see a note that it's been fixed, then please test the GitHub version. I would like to get a release out soon as there are a number of bugs that I'm not happy being up on PyPI, especially the Mac titlebar issue.
New Vertical Alignment
It's possible now to control vertically align elements on a row. Rather than add alignment to each element, it's done using a Column or a Frame (Column if you want to encase a few elements silently).
The default is still that elements are all center-aligned. If you want them aligned differently, put into a Column with pad=(0,0) so it'll have no visible impact, and set the vertical_alignment parameter to top, center, or bottom (t, c, b).
Note that this aligns the Column, not the individual elements in a Column. If you have only 1 element in a column, then it's like having the setting available on a single element
Fixed element_justification
One of the bigger problems that I wanted fixed was element_justification in columns. I don't know exactly when this got broken, but it has been. Now you should be able to control justification in a way that you have a column that's contents are left justified, that are as a group, centered. Along with justifying the contents of elements in a Column, Frame, Window, you can justify a single Column. Note that this will justify the entire row that contains the Column, so keep this in mind.
Working on new docs
I've been spending time working on a new homepage and a new overall doc look. Hopefully coming soon. A new Gallery is one important aspect of this. There needs to be a place people can go to easily see a bunch of nice looking windows. Kinda getting tired of hearing the tkinter is entirely incapable of making nice looking windows when that's not true.
Some of the newer demos, like the custom titlebar, make it possible to make some very attractive windows with a little bit of effort. PySimpleGUI makes is MUCH easier to do this than if done directly in tkinter which is why you may not see some of these techniques used much by typical tkinter programs.
The "themes" alone was a huge step forward some time back. There's no easy way to "apply" a set of colors to a tkinter window.
Thank you for the recent patience and support
The pace has slowed from an external point. Work is done daily, but it's not always immediately visible. There are some things that simply take time that don't pop up for some time. Reworking the docs is an example.
PySimpleGUI 2020-08-17T11:03:28Z
New Vertical Alignment Layout Helper Functions
While working on a problem with Column element justification, I added the ability to vertically align Column elements. The result is that if you want to vertically align a particular element, you can place it inside of a Column, and then vertically align the Column. It's not the most compact way of doing things, but it gets the designed result nicely. As long as you set the pad=(0,0) on the Column, you won't know it's there.
Additionally, to make it even easier to use on a single element basis, 3 new layout helper functions were added vtop
, vcenter
and vtop
. Use these like the pin
helpful function today.
By default, layouts CENTER the elements on a row. This is how the tkinter port has always worked. Until now it's not been possible to vertically align.
Example layout using the new calls:
import PySimpleGUI as sg
def main():
layout = [[sg.Text('Text'), sg.Button('Button')],
[sg.vtop(sg.Text('On row with listbox')), sg.LB(list(range(6)), size=(5,4)), sg.vbottom(sg.Text('On row with listbox')),],
[sg.Button('Ok'), sg.B('Quit')]]
window = sg.Window('Vertical Layout Example', layout, )
while True:
event, values = window.read()
if event in (None, 'Quit'): # if user closes window or clicks Quit
break
main()
It produces this window
PySimpleGUI 2020-08-17T11:22:24Z
Vertical Aligning a Row Using a List Comprehension
Because you can use list comprehensions directly in your layouts, it's possible to do interesting things like aligning all elements in a row to the top of the row. Rather than wrap each individual element, you can do it with a comprehension.
All that's required is to add onto the front of the row the comprehension info, and an extra ] at the end of the row.
This layout shows this concept. The "Row" definition we're working with is:
[sg.Text('On row with listbox'), sg.LB(list(range(6)), size=(5,4)), sg.Text('On row with listbox')],
To align all of those elements at the top of the row, then the line is modified like this:
[sg.vtop(e) for e in [sg.Text('On row with listbox'), sg.LB(list(range(6)), size=(5,4)), sg.Text('On row with listbox')]],
Notice hos the code for the row itself has not changed. You can copy and paste your row into the comprehension meaning the only new code that you're adding is this little bit:
Here it is in a complete program:
import PySimpleGUI as sg
def main():
layout = [[sg.Text('Text'), sg.Button('Button')],
[sg.Text('On row with listbox'), sg.LB(list(range(6)), size=(5,4)), sg.Text('On row with listbox')],
[sg.vtop(e) for e in [sg.Text('On row with listbox'), sg.LB(list(range(6)), size=(5,4)), sg.Text('On row with listbox')]],
[sg.Button('Ok'), sg.B('Quit')]]
window = sg.Window('Vertical Layout Example', layout, )
while True:
event, values = window.read()
if event in (None, 'Quit'): # if user closes window or clicks Quit
break
main()
PySimpleGUI 2020-08-18T14:04:44Z
Calendar Button Deprecation - HEADS UP
The improved Calendar Chooser window that was released works wonderfully and looks fantastic. The problem is that it's PySimpleGUI based (which is why it looks good).
The issue is that I'm unable to create and execute PySimpleGUI windows within a tkinter callback. The Browse Files, Browse Folder, etc, are done using tkinter's dialog windows. The old calendar chooser was written directly in tkinter and thus could be called via the callback. PySimpleGUI is architected in such a way that I'm not able to run popups from these button callbacks.
The way around this is actually very simply for your code. You add your own "calendar chooser button" (which is a plain button). In your event loop when that button is returned as an event, you call popup_get_date
and then update the input field with the return value. It's 2 or 3 lines of code.
I'm sorry that this change is needed. It's really rare for PySimpleGUI features to go backwards in this kind of way. I've got programs written in July 2018 that still run without problems. Being backwards compatible is SUPER important, so it's really painful to make this kind of change. I spent several days trying to find a way to call popups from callbacks, but I wasn't able to do it.
I'm unsure exactly what to do when someone adds one of these buttons to their layout. I can popup a message with instructions on how to add new code, or return an event with a message printed on the console about this change. This will make the window appear to do nothing versus having a popup show up. I think the return an event is better than a popup.
salabim 2020-08-20T09:42:28Z Mike,
I saw your method to use a list comprehension to align all elements in a
row.
With something like:
*[sg.vtop(e) for e in [sg.Text('On row with listbox'),
sg.LB(list(range(6)), size=(5,4)), sg.Text('On row with listbox')]],*
I just want to mention that there is an even easier way to realize this:
*map(vtop,[sg.Text('On row with listbox'), sg.LB(list(range(6)),
size=(5,4)), sg.Text('On row with listbox')]),*
Definitely more compact, and arguably easier to understand.
/Ruud
On Mon, 17 Aug 2020 at 13:22, PySimpleGUI notifications@github.com wrote:
Vertical Aligning a Row Using a List Comprehension
Because you can use list comprehensions directly in your layouts, it's
possible to do interesting things like aligning all elements in a row to
the top of the row. Rather than wrap each individual element, you can do it
with a comprehension.
All that's required is to add onto the front of the row the comprehension
info, and an extra ] at the end of the row.
This layout shows this concept. The "Row" definition we're working with is:
[sg.Text('On row with listbox'), sg.LB(list(range(6)), size=(5,4)), sg.Text('On row with listbox')],
To align all of those elements at the top of the row, then the line is
modified like this:
[sg.vtop(e) for e in [sg.Text('On row with listbox'), sg.LB(list(range(6)), size=(5,4)), sg.Text('On row with listbox')]],
Notice hos the code for the row itself has not changed. You can copy and
paste your row into the comprehension meaning the only new code that you're
adding is this little bit:
[sg.vtop(e) for e in ___ ]
Here it is in a complete program:
[image: image]
https://user-images.githubusercontent.com/46163555/90390938-42c35f00-e05a-11ea-8cff-9d391dd1dd54.png
import PySimpleGUI as sg
def main():
layout = [[sg.Text('Text'), sg.Button('Button')], [sg.Text('On row with listbox'), sg.LB(list(range(6)), size=(5,4)), sg.Text('On row with listbox')], [sg.vtop(e) for e in [sg.Text('On row with listbox'), sg.LB(list(range(6)), size=(5,4)), sg.Text('On row with listbox')]], [sg.Button('Ok'), sg.B('Quit')]] window = sg.Window('Vertical Layout Example', layout, ) while True: event, values = window.read() if event in (None, 'Quit'): # if user closes window or clicks Quit break
main()
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/PySimpleGUI/PySimpleGUI/issues/142#issuecomment-674823550,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AHHWWC3DRFFXXQUCAVBX3SDSBEHIDANCNFSM4FTWUH7A
.
PySimpleGUI 2020-08-20T19:08:17Z
New Custom Titlebar Demo
A new demo was posted today that demonstrates how you can use a theme's color components to build a custom titlebar that will match your program's theme. This demo is a "browser" of themes that then shows you a series of windows based on that theme.
Clicking "Next" will show a new window with the color combinations displayed as the title of the window.
I think these custom titlebars may become popular with users that want to have more control over all aspects of the application's colors.
NOTE - there is an extremely important limitation to keep in mind. These windows are all "grab anywhere" Windows. There is not yet a "Grab Row" capability which is what you would want in this situation. This limitation makes windows with scrollbars difficult because you won't be able to drag to position scrollbar and sliders. You'll have to click on the arrows or on the scrollbar itself to scroll.
PySimpleGUI 2020-08-21T01:09:12Z
Coming Soon.... grab
A new grab
parameter has been added to the Text and Column elements.
This enables the new customer titlebar to be grabbed only by the titlebar itself.
In other words, the previous post that has the
"NOTE - there is an extremely important limitation to keep in mind. "
is no longer a thing you need to keep in mind. You'll be able to grab using the titlebar and move the window while leaving the rest of the window to act like it normally would.
PySimpleGUI 2020-08-21T11:37:09Z
Calendar Button Deprecation Not Needed.....
Earlier this week I gave a heads-up that the calendar chooser button may be going away. I've figured out a design where it will work correctly with the popup. This is a high priority item at this point as it's a broken feature that worked quite well previously. It's just taken me some time to try lots of different approaches in order to get this particular design. Sorry for it being broken for a while. Hoping to get it complete over the weekend.
In the meantime, the work-around provided in the Issue, where your event loop handles calling the popup, should get you by. It's not ideal but it's also quite easy to implement and works well.
Anyway, it's finally getting to the front burner.
PySimpleGUI 2020-08-21T17:10:38Z
tkinter Window with Background Image
Since I managed to get the custom titlebar working this opened up the potential for a feature I've dreamed of making available somehow.... a tkinter window with a background image.
This is a feature that's been asked about on the Internet countless number of times. Stackoverflow has tons of posts on the topic. It's not been solved that I'm aware of.
I showed this same window before, but there was a limitation that it had to be a "grab anywhere" kind of window. With the ability to make Text and Columns "grabbable", it's now possible to make a custom titlebar that the user can use to grab this window and move it around.
Windows Only
Because the transparency is achieved using tkinter's transparent color feature, that means this capability is limited to Windows programs. If someone knows how to achieve the transparent color on Linux / Mac then it may be possible to extend this capability to those environments as well.
May not work out in the long run
Can't really say that this WILL be available to all applications in the future. It's a proof of concept to some extent that is combining a number of new features including the multi-window support and custom titlebar support with the grab parameter.
The "trick" behind all of this is that there are 2 windows. Getting the stacking of the windows correct so that the background window stays in the background is one of many things that has to work right in order to pull this off.
Let's keep our fingers cross that this will work out well in the long run!
PySimpleGUI 2020-08-22T19:48:58Z
Calendar Chooser Button Works!
OK, finally got that damned button working correctly. Took quite a bit more than I thought.
It has not yet been added to the multi-window code... that's next. For most of you this temporary limitation isn't going to be an issue. It's only if you call sg.read_all_windows()
that you'll have a problem.
Here is a test harness that demonstrates 4 different use cases:
import PySimpleGUI as sg
layout = [ [sg.Text('My Window', tooltip='in')],
[sg.Input(key='-IN2-', enable_events=True)],
[sg.Input(key='-CAL1-', enable_events=True), sg.CalendarButton('Cal', tooltip='Will generate an event')],
[sg.Input(key='-CAL2-'), sg.CalendarButton('Cal')],
[sg.CalendarButton('Calendar', target='-CAL3-', key='-CAL3-' )],
[sg.CalendarButton('Calendar', target='-CAL4-', key='-CAL4-', enable_events=True, tooltip='Will generate an event' )],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout, keep_on_top=True)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
PySimpleGUI 2020-08-22T20:20:40Z
More Stuff In Upcoming Release
The list keeps growing.... sorry it's taking a bit to get this stuff out the door, but I want to close out a couple of critical bugs (the date chooser one in particular) before releasing to PyPI.
Two New Themes
Dark themes seem to be popular with users, so two new ones added this week.
Dark Purple 7
Dark Green 7
Theme Previewer Reminder
A reminder that sg.main()
has a built-in theme previewer. Just click the "Themes" button. You can then enter a search string or leave blank to get them all. Entering "dark" showed me these dark themes that are available:
Entering "dark green" produced this preview:
Themes Heads-up
There was a bug in the way theme progress bars was being created. It was a problem if you changed themes. The previous theme's progress bar would interfere with getting the correct new progress bar colors.
The fix introduced a new constant DEFAULT_PROGRESS_BAR_COMPUTE
. If you're a theme designer and you don't specify specific colors for your progress bars, then this value is what you'll want to put into your theme if you want the progress bar colors to be created using the other colors in the theme.
I don't THINK this change will cause problems for most people, but heads-up just in case.
New tkinter
Version Number Variable
The variable sg.tclversion_detailed
now contains the detailed version number for tkinter. This is going to be information requested on the Forms in the future. It's already shown when you call sg.main()
. It'll be added to the list of stuff you print. There are currently 2 values. Here's the info you'll be ask to collect:
For Mac users in particular this is going to be important to check. It's also helpful to know if version 8.6.9 is being used because that's the one where table/tree colors stopped working.
New Grab Capabilities
The parameter name at the moment is grab
, but it'll be change to something more like grab_moves_window
so that it's clearer what it does. This parameter has been added to the Text and Column elements. It's needed in order for the "custom titlebar" demo to work correctly.
This capability makes it possible to use sliders and scrollbars in a window that you can "grab" to move. You can remove the titlebar and grab using Text or a Column (there are some limitations that will be detailed later).
Expand Added to Column
Previously there was a second call required in order to make a Column Element expand. Most layouts don't need this kind of expansion, but for those that do, you'll be able to specify the expand in the Column Element in the layout rather than doing it after the window is finalized. It helps with things like the custom titlebar.
Custom Titlebars....
These expand and grab features all help to make these custom titlebar windows.
Here's a nice little window using the new Dark Green 7 theme
I think this may end up really helping out users that want a more "modern" look and feel. I'll admit that tkinter windows don't look incredibly modern, but at least now PySimpleGUI users will be able to replace the titlebar with a custom one that is capable of having colors that match the window. Normally you're stuck with whatever Windows gives you for a titlebar. I haven't seen a way using tkinter to change the normal Windows titlebar.
Plus more....
I'm sure there's stuff I've forgotten as there are a lot of changes in this release (I say that every time but it's true).
Aligning is a good example
The element justification stuff is working now. Vertical aligning is one of the bigger new features. You'll be able to do things like have buttons aligned to the left and right sides of a window if you want.
Let's just hope that these changes don't cause regression of the other features!
PySimpleGUI 2020-08-23T12:38:09Z
Pi Tutorial Video....
Just found this great little tutorial on using PySimpleGUI to control a Raspberry Pi.
https://youtu.be/9_VEoU3rjDE
Awesome to see stuff being built!
PySimpleGUI 2020-08-23T19:54:49Z
From the "It Still Works" Bin.....
I ran across an old Reddit post for 2 years ago. Things were different back then.... Windows weren't Windows yet... they were called FlexForm
. A lot has changed, but not the layout in this case.
I needed to change the last line of the code that was posted in order to create and read the window. Other than that, it runs just the way it was posted.
It's super basic, but demonstrates that things have remained backwards compatible as much as possible. Just a plain, basic window, but it gets the job done. I think it looks a bit better with the default theme applied.
import PySimpleGUI as g
form = g.FlexForm('Registration form', auto_size_text=True)
layout = [ [g.Text('Registration Form', size=(20,1), font=('Helvitica', 20))],
[g.Text('Full name', size=(15,1)), g.InputText()],
[g.Text('Email', size=(15,1)), g.InputText()],
[g.Text('Gender', size=(15,1)), g.Radio('Male', group_id=1), g.Radio('Female', group_id=1)],
[g.Text('Country', size=(15,1)), g.Combo(values=('select your country', 'USA', 'Other'))],
[g.Text('Programming', size=(15,1)), g.Checkbox('Java'), g.Checkbox('Python')],
[g.Submit(button_color=('white', 'red'))]
]
event, values = form.layout(layout).read()
Here's the window that's created:
This is the way the window looked when originally posted:
PySimpleGUI 2020-08-24T13:58:39Z
Release Coming Along.... Pi Problem...
While testing the upcoming release on the Pi, I found a problem when running the new custom titlebar demo. It had to do with getting focus to happen on an Input Element when no titlebar exists. On Windows this hasn't been an issue, but on the Pi it is. Not sure if it's the older tkinter version or 3.4 or both, but there was definitely a problem. Clicking on the window wasn't enough. The behavior was if the missing icon on the taskbar was stopping the window from getting focus.
The fix is to force focus onto the window when a window is created without a titlebar. This code is added and hopefully will not have a negative side effect to existing applications. There is also a new Window.force_focus
method added should you find the need to force focus onto a window.
In the end, the result is nice. The customer titlebar looks great and works great on the Pi.
More testing today on Linux. Hoping to get this release finally out shortly.
There were also changes to the main()
test harness. A button was added to hide the tabs area so that the window will shrink enough to fit on the Pi's screen. It's possible to change themes as well as a way to quickly preview themes. This required a bit of reworking of the code as the window needs to be restarted in these cases.
PySimpleGUI 2020-08-25T10:51:12Z
Multiple-window application change (apps the have windows that come and go)
I've made a pretty fundamental change that I hope has a positive impact. There is a "hidden master window" that is created when you create your first window. In the past, this windows has been destroyed when the last window is closed. It will then be re-created if you open another window.
I noticed a memory leak that happens when closing and re-opening the hidden window. Not closing the hidden window fixes this problem. It might also fix problems where windows are closed and then more opened later such as the popups and one_line_progress_meter.
I'm still testing this new change. Overall, I like it. Anything that reduces risk of a memory leak is good and it also provides a more stable environment. The only downside I can think of is that when the application exits, there is this one window still "open" but not visible. tkinter should take care of this window when the program exits however.
I want to continue getting some runtime on this change before pushing the release up to PyPI. So far the testing has been going great on the Pi, Linux and Windows. I want to do some additional 3.8 testing today. The focus has been on earlier releases to make sure everything remains backwards compatible with version 3.4 and older versions of tkinter.
This change was checked in with version 4.28.0.22 on GitHub. You can check it out by downloading the file PySimpleGUI.py and placing it in your applications folder along with your other .py files. This will override the pip installed version as the local PySimpleGUI.py file will be imported instead of the pip installed. You can check which is being imported by printing the import name (usually sg) which will tell you where Python is picking up the release from.
elguaxo 2020-08-25T19:27:32Z
Input Element when no titlebar exists
I was having the same issue on macOS and Tkinter 8.6.10! Great to hear this is bein addressed. Thanks!
PySimpleGUI 2020-08-25T21:03:29Z
4.29.0 PySimpleGUI 25-Aug-2020
Custom titlebar capabilities (several new features required)
Better Alignment
Calendar button works again
-
Window.visiblity_changed now refreshes the window
-
Added Column.contents_changed which will update the scrollbar so corrently match the contents
-
Separators expand only in 1 direction now
-
Added 8 SYMBOLS:
SYMBOL_SQUARE = '█'
SYMBOL_CIRCLE = '⚫'
SYMBOL_CIRCLE_OUTLINE = '◯'
SYMBOL_UP = '▲'
SYMBOL_RIGHT = '►'
SYMBOL_LEFT = '◄'
SYMBOL_DOWN = '▼'
SYMBOL_X = '❎'
-
New dark themes - dark grey 8, dark grey 9, dark green 9, dark purple 7
-
When closing window no longer deletes the tkroot variable and rows but instead set to None
-
Changd no-titlebar code to use try/except. Previously removed for Mac due to tk 8.6.10 errors calling wm_overrideredirect
-
Fix for Column/window element justification
-
New vertical_alignment parm for Column, Frame, pin
-
New layout helper functions - vtop/vcenter/vbottom - Can pass an element or a row of elements
-
Fixed statusbar expansion
-
Added disabled button to theme previewer
-
Fixed grab anywhere stop motion bug - was setting position to None and causing error changed to event.x
-
Expanded main to include popup tests, theme tests, ability to hide tabs
-
Grab parameter for Text Element, Column Element
-
Added tclversion_detailed to get the detailed tkinter version
-
All themes changed the progress bar definition that had a "DEFAULT" indicator. New constant DEFAULT_PROGRESS_BAR_COMPUTE indicates the other theme colors should be used to create the progess bar colors.
-
Added expand_x and expand_y parameters to Columns
-
Fix for Calendar Button. Still needs to be fixed for read_all_windows
-
Force focus when no-titlebar window. Needed for Raspberry Pi
-
Added Window.force_focus
-
No longer closes the hidden master window. Closing it caused a memory leak within tkinter
-
Disable close on one_line_progress_meter. There is a cancel button that will close the window
-
Changed back toplevel to no parent - was causing problems with timeout=0 windows
PySimpleGUI 2020-08-26T21:30:09Z
key='-KEY-'
but why?
If you've spent any time looking at the demo code or reading the Cookbook, then you've run across the naming convention used for most keys that are strings.... the format is '-KEY-'
.
So, why this format?
The reason is visibility and uniqueness. Keys can be pretty much anything except a List. If they're a string, then I find it's easier for me to spot a key in the middle of a bunch of code if it's named like this. There are 2 attributes to this text that help.
1 - It's all upper case. Like constants, all upper case made sense to me. Since they take up more room than lower case, they stand out a little bit more.
2 - The dashes make it unique. There are no valid variable names that that that format, so I know right away if something is a key.
It makes "parsing" in my head easy / immediate. If I see something that's named '-CHECKBOX-'
then I'm 100% confident that I'm looking at a key. Variables aren't going to be named with that format. So I know I won't be confusing the key with a variable name. Why is it important to be able to pick out keys? They drive all of the lookups. If you want to find an element, you use the key. When accessing the values
dictionary, you use the key. So, they're kinda key to the architecture.
Of course you're free to name/number your keys however you want.
PySimpleGUI 2020-08-27T22:25:17Z
A "PyCharm Me" Button
Lately I've been making a lot of utilities that continue to be expanded on a constant basis. To make it really easy to edit a program that's running, I've begun to add an "Edit" button. All this button does is run a PyCharm batch file and passes in the filename of the .py file being executed.
A new little demo has been created to show this called Demo_PyCharm_Self_Edit.py
Here's the entire demo:
import PySimpleGUI as sg
import subprocess
"""
Demo PyCharm Launch - Edit this file button
Quick demo to show you how to add a button to your code that when pressed will open the file
in PyCharm for editing.
Note that this is a Windows version. You'll need a slightly different path for Linux.
Copyright 2020 PySimpleGUI.org
"""
# Change this variable to match the location of your PyCharm folder. It should already have the batch file.
PYCHARM = r"C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.1\bin\pycharm.bat"
layout = [ [sg.Text('Edit Window Using PyCharm')],
[sg.Button('PyCharm Me'), sg.Button('Exit')] ]
window = sg.Window('PyCharm Launch Demo', layout)
while True: # Event Loop
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'PyCharm Me':
subprocess.Popen([PYCHARM, __file__], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
window.close()
The important parts
There are only 2 important lines of code.
-
The definition of the batch file used to launch PyCharm (you'll need to edit to match your configuration)
-
The
subprocess.Popen
call that runs the batch file.
In this case those 2 lines are:
PYCHARM = r"C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.1\bin\pycharm.bat"
subprocess.Popen([PYCHARM, __file__], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
When the Popen
call is made, PyCharm will either launch, or if already running it will open a new tab with the contents of the current file.
Zain-Bin-Arshad 2020-08-29T10:02:51Z
4.29.0 PySimpleGUI 25-Aug-2020
Custom titlebar capabilities (several new features required)
Better Alignment
Calendar button works again
Window.visiblity_changed now refreshes the window
Added Column.contents_changed which will update the scrollbar so corrently match the contents
Separators expand only in 1 direction now
Added 8 SYMBOLS:
SYMBOL_SQUARE = '█'
SYMBOL_CIRCLE = '⚫'
SYMBOL_CIRCLE_OUTLINE = '◯'
SYMBOL_UP = '▲'
SYMBOL_RIGHT = '►'
SYMBOL_LEFT = '◄'
SYMBOL_DOWN = '▼'
SYMBOL_X = '❎'
New dark themes - dark grey 8, dark grey 9, dark green 9, dark purple 7
When closing window no longer deletes the tkroot variable and rows but instead set to None
Changd no-titlebar code to use try/except. Previously removed for Mac due to tk 8.6.10 errors calling wm_overrideredirect
Fix for Column/window element justification
New vertical_alignment parm for Column, Frame, pin
New layout helper functions - vtop/vcenter/vbottom - Can pass an element or a row of elements
Fixed statusbar expansion
Added disabled button to theme previewer
Fixed grab anywhere stop motion bug - was setting position to None and causing error changed to event.x
Expanded main to include popup tests, theme tests, ability to hide tabs
Grab parameter for Text Element, Column Element
Added tclversion_detailed to get the detailed tkinter version
All themes changed the progress bar definition that had a "DEFAULT" indicator. New constant DEFAULT_PROGRESS_BAR_COMPUTE indicates the other theme colors should be used to create the progess bar colors.
Added expand_x and expand_y parameters to Columns
Fix for Calendar Button. Still needs to be fixed for read_all_windows
Force focus when no-titlebar window. Needed for Raspberry Pi
Added Window.force_focus
No longer closes the hidden master window. Closing it caused a memory leak within tkinter
Disable close on one_line_progress_meter. There is a cancel button that will close the window
Changed back toplevel to no parent - was causing problems with timeout=0 windows
I am not sure what fixed the issue, not closing top level window or what. I used multi-threading with write_event_value()
. When I used threading for searching and closes the window it throw some exceptions like this (!toplevel.frame!window), but when I don't use this function window closes as it is intended.
I have used some popups as well, write_event_value
affects them too, they stop showing texts afterwards. Just letting you know that you have fixed a lot of problems in this release, that you are unaware of. Thanks !
PySimpleGUI 2020-08-29T20:12:33Z
Python, tkinter, Pi Cheat Sheets
While initially writing PySimpleGUI I ran across this site and the cheat sheets it contained:
https://www.wikipython.com/
They're AMAZING works of art. What's even more amazing is that they're kept up to date and improved. It seems like no one keeps tkinter documentation up to date, but John does. You'll find his sheets also posted in his GitHub repos
https://github.com/GitHubJohn2
I printed and laminated them all. They're fantastic for looking up Python information, format strings, std lib calls, tkinter stuff. They too good to be free, but they are. If you like PySimpleGUI, I think you're likely a candidate for liking these summary pages.
Enjoy!
PySimpleGUI 2020-08-31T12:49:16Z
Overly Simple Example
Here's my "Scratch Template" using the shortest names possible. When I'm debugging a problem, this is often the starting point as the code creates a simple Window, look for a button click and uses the Input dictionary as well as updating an element. This window is created:
Those operations represent large portion of PySimpleGUI operations. It's a little extreme to shorten everything, including the variable names down, but the layout is actually kinda nice being more compact.
import PySimpleGUI as g
l = [[g.T('My window')],
[g.I(k='-IN-'), g.T(size=(12, 1), k='-OUT-')],
[g.B('Go'), g.B('Exit')]]
w = g.Window('Window Title', l)
while True:
e, v = w.read()
print(e, v)
if e in (g.WIN_CLOSED, 'Exit'):
break
if e == 'Go':
w['-OUT-'].update(v['-IN-'])
w.close()
[EDIT - I should clarify.... The above simplified code is based on the template I use. My actual template is more verbose ]
This is the starting template that I modified to use shortened names:
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-'), sg.Text(size=(12,1), key='-OUT-')],
[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 == 'Go':
window['-OUT-'].update(values['-IN-'])
window.close()
PySimpleGUI 2020-09-03T12:36:24Z
Issue Break Week
If you've filed an issue this week and not received a response from me, it's not because I'm ignoring you.... I'm taking a break from user support this week. In order to get to some of the other items that need attention, I need a break from the daily incoming requests. Back next week to work on your issues again. Thanks for your support and patience.
PySimpleGUI 2020-09-08T18:18:34Z
Back To Issues & New Interface For Settings....
It was nice to get a little recharging time. I think it's the first week away from supporting users since being hospitalized in 2019.
There remains a lot of work to do with the documentation / readme which is underway. More on that soon-ish.
In the meantime....
Settings APIs
I've noticed a number of users that are enabling people to "skin" their applications according to the user's theme choice. Saving this information requires the user to know something about JSON or one of the other INI file libraries. There is one demo currently that shows how to do about using JSON files to create a "settings"file.
The "rainmeter" style desktop widgets are an excellent example where you may want to store some settings. Things like keys for online services that require an "API Key" like the Reddit APIs or any number of the weather APIs out there. All of them require needing a long "key" string. The Reddit package praw
requires several pieces of information that you do not want to place in your source code.
So, I thought that helping users manage these little bits of information would be a good thing to have as part of the PySimpleGUI base APIs calls. The result is a series of API calls that start with user_settings_
that helps you manage this information. These calls will help you name your file, locate it on your hard drive in an appropriate location (e.g. at a recognized "settings files" location or in your application's folder).
Here is a list of the new functions:
user_settings_filename
user_settings_set_entry
user_settings_get_entry
user_settings_save
user_settings_load
user_settings_write_new_dictionary
user_settings
Tutorials / demo programs / Cookbook is on the way.
It can be as simple as this to get your program's theme:
This call will not only return the current value, but will also give you back a default value in case it's not yet present and will add the value into your current settings. Then it's a matter of saving your theme to disk
You don't even need to specify a filename. The file will be located in your OS's typical settings location and the filename will be named from the source code file's name. If your program is called test.py, then your settings file will be test.json.
If you don't want to save in the OS folder and instead save locally to your application, then you can add a path when you save:
A more typical way of doing it is to first indicate what the correct path / location / filename is. Then do your operations, then save it.
This code is in a file names scratch_1043.py. After running this code:
sg.user_settings_filename(path='.')
sg.user_settings_set_entry('theme', 'Dark Grey 11')
sg.user_settings_save()
there is a file created named scratch_1043.json and has the contents:
Anyway, that's a super-quick introduction to an exciting new capability. Well, it's exciting for me.... maybe it'll be exciting for you too.
PySimpleGUI 2020-09-08T18:58:24Z
Five NEW Dark Grey Themes
I'm getting the message that the Dark Themes are popular so I've been adding new ones from time to time. This next release has these 5 new ones.
If you have some particularly attractive dark themes, I'm interested in seeing what you've got!! You can post screenshots in the User Applications Screen Shots Issue here: https://github.com/PySimpleGUI/PySimpleGUI/issues/10
It would be great if you have them in the PySimpleGUI color theme format already. If you've only get an example window from another application, that would be good to see as well. Just remember that the PySimpleGUI themes are simplistic in terms of the number of colors involved.
Dark Grey 10
Dark Grey 11
Dark Grey 12
Dark Grey 13
Dark Grey 14
PySimpleGUI 2020-09-08T19:10:59Z
New main()
Test Harness Capabilities
The main()
program is being expanded.
This is how it looks at the moment:
Not long ago a button was added to hide the tabs so that it could be run on the Raspberry Pi. The window is rather large and collapsing the tabs makes it possible to reach the bottom buttons on a Pi. If you click the arrow on the left, it collapses down to:
One recent addition is the ability to now only preview themes but switch the theme that the test window is using. This will give you a more extensive example of the theme.
Here's what DarkGrey11 looks like:
One new feature is the "SDK Reference" button. You can click this button to pull up a quick reference guide window. You can also open this window directly from your application by calling main_sdk_help()
It will continue to use the newly chosen theme when you open additional windows including the SDK Reference window:
This SDK Reference Windows is simply using the Python help system to show you the docstrings that are in PySimpleGUI. You're able to see all of the methods available for each element and a definition of their parameters. So, if you're even in a pinch where PyCharm isn't available to give you the parameters and you're not able to access the normal documentation, then you can call this function to look through the docstrings for each element.
PySimpleGUI 2020-09-09T13:53:59Z
GitKraken
It should come as no surprise that I'm partial to GUI interfaces. Doesn't have anything to do with PySimpleGUI... I've just been a fan of GUIs over command line interfaces, having spent decades using both environments.
The path that I follow when making and checking in changes is very narrow. I tend to do the same activities over and over, so once I have a well-worn path to success, I tend to stay on it.
Normally I use the program "GitHub Desktop":
However, being completely honest, I use the light skin:
I recently stumbled onto KitKraken's GUI program for Windows and I kinda like it. I haven't used it for checking in code. It's been more of a "browser" of the GitHub. It's got a nice interface for the Issues:
You might notice that color scheme if you're been paying attention to the release announcements about newly added themes. It looks much like the new DarkGrey10
or DarkGrey12
themes. The purple and some of the greys for sure match :-)
If you're looking for a GitHub GUI interface, then it may be worth your time to check out the GitKraken program. There is a free version of it.
PySimpleGUI 2020-09-12T10:53:19Z
New Versions of YouTube Videos
A new playing is being filled:
https://www.youtube.com/playlist?list=PLl8dD0doyrvF1nLakJJ7sl8OX2YSHclqn
Last week I discovered a tool on YouTube called "jumpcutter" in this video by Carykh:
https://youtu.be/DQ8orIurGxw
I put together a GUI front-end to make it much easier to work with and uploaded it to GitHub:
Note that I'm not done with it by any means. I want to make it more table driven and generalized so that it can become a demo program that is an improvement of other "command line front-ends". There's one bug in Cary's program, but if you don't specify the sound parameter you won't hit it.
I tend to run it with no parameters set at all:
I need to work on the input / output filenames so that spaces are allowed and I also want to work on the URL as YouTube videos weren't downloading for me. At the moment, I'm only using folders and filenames without any spaces just to keep things super simple. My focus is on getting these videos converted, not getting the GUI polished.
The Process is Lengthy
It's taking me a while to process all of my video because:
-
There are a lot of videos
-
I'm correcting the volume levels on the early videos
-
They need to be converted to 30 fps or maybe I can get away with 25 fps in some of the later ones
-
It takes a while to process every individual frame of video on a 40 minute video
-
All videos have to be re-uploaded, the descriptions, tags, etc, must be copied
So it's a little bit of a pain in the ass, but I think the results are amazing, especially for "tutorial videos that have typing". I find it difficult to concentrate on typing very accurately while also speaking. There are too many things for my brain to juggle. The result are videos that I'm not happy with despite, shockingly, the viewers seem to be happy. I've been stunned by how kind and appreciative the YouTube commenters have been.
It's for the viewers that I'm investing this time. Every person that watches one of these videos will get back about 20% of their time. That's a significant savings and I think the quality of the videos is higher too.
Feedback Welcomed
Drop a comment on YouTube if you have comments on the results. I'm doing this for the viewers after all and if the experience sucks, it would be nice to hear about it.
I could see these kinds of tools eventually being adopted by YouTube as "pre-processors" that can be run on a video when it's uploaded.
Credit to Carykh
All credit deserves to go to Carykh for coming up with the idea, and then having the drive to to a lot of testing and tuning to get it right, and finally making a GitHub and sharing the code using an MIT license. It's a self-less and generous thing to have done. I find people like Cary to be motivating. He seems to have good intentions.... like honestly good intentions. Combined with being extremely bright and clever he's setting a great example of goals to aspire to.
pamoroso 2020-09-12T11:04:29Z @PySimpleGUI You may have a look at Narakeet, a tool that can largely automate the video production process. It can automatically generate visuals, add background music, narrate with high-quality voice synthesis systems like Amazon Polly, and make a video entirely from a script file in a Markdown dialect. But the tool also supports adding your own video clips and audio recordings.
Creating instructional and demostration videos is one on Narakeet's main use cases, see this example and the rendered video (under Techies > Demo 2 Code Tutorial
).
PySimpleGUI 2020-09-12T12:02:45Z
18%... my latency
It's odd that the first few videos I've shortened have all decreased by about 18%. If I can consistently squeeze 20% of the time my viewers are watching the video, without compromising anything but instead enhancing, then this is a huge winner for everyone!
Thanks for the tip @pamoroso . I've not needed a full-on toolchain yet as I've pretty much settled on Filmora for everything. This jumpcut utility has been the first addition of something that bumped me from a tool to a pipeline.
I'll check out Narakeet. I've wondered about tools that can do text to speech for videos for a while now. Sound like a fascinating suite of capabilities.
I'm working on a complete course, but I'm outsourcing the production. I can't get the quality level required for the high-end educational platforms by doing them myself. I also don't have the patience to do them myself. I got my enjoyment out of writing the GUI front-end for jumpcutter than I did making the videos, although I'm really pleased/excited at the results I'm getting. I hope viewers like them better than before too! That's the whole purpose behind this after all....a more enjoyable and efficient experience for users.
I'm excited to finally see some female and older viewers watching the videos!!
FASCINATING that the feedback I get is that it's the younger users that prefer to learn via video instruction, it's the older viewers that are watching the longest.
PySimpleGUI 2020-09-13T14:23:20Z
YouTube Faster Videos - A dozen done!
Been working hard at getting all of the 2020 series of videos processed. Each of the 12 videos completed so far have had their volume levels increased and the magic jump-cutting tool run on them.
I really hope all this effort is worth it. I clearly think it will be or I wouldn't be investing my weekend in this.
Here's a link to the new playlist with 12 of the 18 videos completed:
https://www.youtube.com/playlist?list=PLl8dD0doyrvF1nLakJJ7sl8OX2YSHclqn
Feel free to post a comment on any video you find particularly useful or notice a problem on. Or post a recommendation there for other video you would like to see.
PySimpleGUI 2020-09-13T14:57:43Z
Lambda Keys
Don't forget that keys can be anything.... (except a list)...
Here's an example of how versatile this kind of flexibility provides.
Let's assume you're hung-up on wanting the tkinter style "command" parameter for your buttons. In tkinter and other GUI frameworks, the command
parameter is typically filled in with a callback function, often using a lambda expression.
Here are a couple of lines of tkinter code I got from a tkinter project that implements a basic media player
play_button = Button(controls_frame, image=play_btn_img, borderwidth=0, command=play)
pause_button = Button(controls_frame, image=pause_btn_img, borderwidth=0, command=lambda: pause(paused))
In tkinter's Button widget, the command
parameter indicates a function that will be called when the button is clicked.. If you want to pass parameters to the function, then a lambda is used. The example I've shown has both a plain function and one with parameters.
There are a few demo programs that demonstrate ways of re-creating this callback type of dispatching, usually done though a dictionary, but you can also be much more direct in the approach. Instead of using a string or number for the key that is then used to look up a function to call in a dictionary, you can specify the function to call as the key itself.
Here's a little program that demonstrates this technique:
import PySimpleGUI as sg
def func(x, window):
window['-OUT-'].update(f'Func x = {x}')
layout = [ [sg.Text('My Window')],
[sg.Text(size=(20,1), key='-OUT-')],
[sg.Button('Popup', key=lambda: sg.popup('Popup pressed')),
sg.Button('Call the func', key=lambda: func('Called the func', window)),
sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True: # Event Loop
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
if callable(event):
event()
window.close()
There are 2 things to notice:
-
The keys for the buttons are lambda expressions
-
The call happens from your event loop
The specifying the key as a lambda isn't anything special. It's the same format as what you would use with tkinter.
The 2 lines in your event loop that make it all possible are the most important bit:
These 2 lines do all the work. They check to see if your event is callable (a function or something else that's callable) and if so, then make the call. It enables you to mix and match strings and functions in the same event loop.
So play around with your keys. Use them in ways that fit your application. If you're working with a grid of buttons, use tuples. If you want to call functions, use functions/lambdas. If you want to index directly into a list, use ints. The point here is that you're not limited to only strings despite most of the demo programs showing a string as the key.
[EDIT] --- oops.. forgot to show the screenshot of running the program...
salabim 2020-09-13T17:27:10Z Using a callable (function or lambda) is indeed a very clever usage of a key. I am sure that advanced users will find several nice applications for that concept.
The statement "Don't forget that keys can be anything.... (except a list)..." is not exactly right. It should be "Don't forget that keys can be anything.... (except a non-hashable)...". For instance, dicts and sets are also unhashable.
But that made think: why? And then I found out that it's because you want to address it in window[key] and values[key].
Wait ... there are cases when that's absolutely not necessary. If someone just wants to check that the event (key) has a certain value, and not access it as either window[key] or values[key], then unhashables should be perfectly acceptable.
It is easy to accept unhashables as keys in PySimpleGUI, by adding just two minimal changes:
In _BuildKeyDictForWindow
change
into
and in AddToReturnDictionary
into
if isinstance(element.Key, collections.abc.Hashable):
form.ReturnValuesDictionary[element.Key] = value
And then the requirement that a key should be hashable doesn't; exits anymore! Of course, you can't use that key in window[] or values[], but users that can understand lambdas will certainly understand that ...
PySimpleGUI 2020-09-13T18:56:13Z
Finishing Up YouTube Tomorrow....
Looks like tomorrow will be the complete date for the YouTube update. I've managed to get 15 of the 18 processed and 12 of them posted. It's been a pretty consistent 18 - 20% reduction in wall-time for each video. A few of the later ones I must have gotten my act together a little better as there's not as much silence.
PySimpleGUI 2020-09-13T20:05:41Z
Jumpcutter Repo Forked...
I decided to fork Carykh's repo in order to add the GUI. The change I made to the original jumpcutter.py file has nothing to do with the GUI, but instead a problem with the sample rate argument being defined as a float when one of the underlying packages expected an int. This problem must have crept in after Cary's initial release.
This is the location of the Repo:
https://github.com/PySimpleGUI/jumpcutter
Like everything, it's a work in progress. I'll be taking bits of this GUI and adding it to the Cookbook most likely. It's a bit more general than the other front ends that have been released as demos.
(Theme is now Dark Grey 9 so that you'll have a valid theme when using the released 4.29.0 version of PySimpleGUI. If using the GitHub version, then try Dark Grey 11 for this darker look)
Here's what Dark Grey 9 looks like:
And these are Dark Grey 11... I'll switch once 4.30.0 is out:
PySimpleGUI 2020-09-14T20:18:10Z
YouTube Conversion Complete
Wow that was a lot of work, but I'm sure it's worth every moment.
Here's the experimental "faster playlist":
https://www.youtube.com/playlist?list=PLl8dD0doyrvF1nLakJJ7sl8OX2YSHclqn
I've started to experiment more with the settings and found I can compress some of them even further. If you give it a try, then try modifying two of the parameters, the Silent Threshold and the Silent Speed. They normally default to 0.03 and 5.0. When I changed them to 0.05 and 20, then some of the videos compressed that were stubbornly not compressing very much using the default values.
It may seem silly to some people to shave a minute here and there from these videos, but given the number of people now watching them, it adds up! If that time can be used actually writing PySimpleGUI programs instead of listening to me drone on about how to write them, then I consider that a success worthy of putting in the effort for.
While editing the videos, I also adjusted the volume on all of them.
I'll update the documentation next to reflect the new playlist and videos.
If you're making tutorial videos, particularly ones where you're talking and coding at the same time, I urge you to give this utility a try. Here's the repo for the version with the GUI as well as fixes so that filenames can contain spaces.
https://github.com/PySimpleGUI/jumpcutter
I experimented on some other YouTube creator's videos and the results were dramatic. Some shrank by more than 25%.
Sorry this little project has been a bit of a tangent away from dealing with the Issues and working on the releases. Really wanted to get this completed while I'm focused on it.
Enjoy!
PySimpleGUI 2020-09-17T12:12:43Z
ver
- The Shortened Version String
Recently added to GitHub is the officially added new version string. It's only in the tkinter port at the moment. If you've written up an Issue you've likely printed sg.version and pasted the value into the issue. That string tends to be rather long because it contains a running summary of the changes made from the previous released version.
ver
is simply the numerical portion of the version string.
For example
The current version (short) is 4.29.0.12. The above code prints these lines of text:
4.29.0.12 Unreleased
Added shink parameter to pin, added variable Window.maximized, added main_sdk_help_window function, theme DarkGrey10 added, no longer setting highlight thickness to 0 for buttons so that focus can be seen, new themes DarkGrey11 DarkGrey12 DarkGrey13 DarkGrey14, new user_settings APIs, added text parameter to Radio.update, echo_stdout_stderr parm added to Multiline and Output elements, added DarkBrown7 theme, user settings delete function, ver shortened version string, modal docstring fix in some popups, image parameter implemented in popup_scrolled, added Radio background & text colors to update
4.29.0.12
Once rolled into the other ports, I'll update the Issue Template to use sg.ver
. Or I may update it to use include the code that will print the shortened version instead of printing version. It's a simple split operation that's used to get the first part of the version string.
This will lop off the date of the release for a released version and the long description for an unreleased version.
PySimpleGUI 2020-09-17T23:42:51Z
Like Dark Themes?
The Dark Grey's have been growing on me lately.
The latest batch was Dark Grey 9 through 14. I've nearly released several demos / applications using these new ones, but I caught myself at the last moment having realized they are not yet released to PyPI (are only on GitHub at the moment). The only one that's on PyPI of these is Dark Grey 9 which is why it's the one used in the Jump Cutter demo instead of Dark Grey 11.... except the screen shots are of Dark Grey 11. It'll all get sorted out when 4.30.0 is released.
Dark Grey 11
is my favorite out of the batch and is likely what I'll use for a number of upcoming demos and applications. I think it's based on Discord's colors. One of these news ones is... just don't remember if that's the one at the moment. GitKraken's colors were used for a number of the new ones too.
I would like to get a couple more together before the next PyPI post so I've been keeping my eyes peeled for nice looking dark GUIs lately.
PySimpleGUI 2020-09-22T15:53:17Z
Short-term Roadmap - Qt help is coming... hang in there.....
I know there are a number of outstanding Qt issues and questions. For those of you waiting, I feel your pain.
I thought it would be good to give a little visibility into my near-term priorities and upcoming work.
Summary of what's happening
-
I'm working on the new readme now. This will be an ongoing process and starts with a new, short primary readme.
-
Next up is full attention to PySimpleGUIQt.
-
There are a number of fixes on GitHub that haven't released to PyPI
-
There are definitely Issues filed that are getting dedicated attention
-
Docstring work will continue resulting in another call reference document specifically for Qt
-
-
No new features planned for the tkinter port. Am finishing up the "user settings" APIs, but nothing else new planned
-
A new System Tray implementation has been in the works for some time, but unsure when we'll get it done so no announcements just yet
-
Education - The next "big thing" I'm working on
-
High-quality video production is next big item
-
More written documentation
-
More demos, better organization of existing demos
-
Separate call reference for Qt
-
Docstrings for the other ports
-
Cleaning up what's already posted
-
-
"Button Graphics" - The closest thing to "new features" in the near-term
-
Being worked in the background - hiring some graphic design help
-
Have some in progress, not yet posted, and not the best by any means but it's a start and will give you a pattern to make your own
-
Will be usable on at least tkinter and Qt ports
-
PySimpleGUI 2020-09-26T17:18:10Z
New Matplotlib Demo / Updated Matplotlib Template
While putting together some screenshots for the new readme it dawned on me that I've not done anything to make Matplotlib plots look different than the default grey color scheme. After a quick bit of research, I discovered the "Style" setting for plots. This resulted in 2 changes.
-
Addition of a Style combobox to the original Matplotlib Template
-
A new Matplotlib Styles Demo that includes setting the PySimpleGUI Theme
The reason for 2 demos is that the template is designed to run on tkinter, Qt, and Remi with no changes other than the import statement. It's a "template" meant to be run anywhere. Changing themes requires restarting a window and this isn't currently possible with the Remi port. So, the demo that has the ability to change both the PySimpleGUI Theme and the Matplotlib Style was created and is targeted to the tkinter port.
Here is what the new demo looks like in action:
There are a lot of these Matplotlib Styles available and you can try all of the ones installed on your system because the combobox is populated with the values returned by Matplotlib.
There was more styles available than I expected! Here's what I get when asked Matplotlib which are available:
bmh
classic
dark_background
fast
fivethirtyeight
ggplot
grayscale
seaborn-bright
seaborn-colorblind
seaborn-dark-palette
seaborn-dark
seaborn-darkgrid
seaborn-deep
seaborn-muted
seaborn-notebook
seaborn-paper
seaborn-pastel
seaborn-poster
seaborn-talk
seaborn-ticks
seaborn-white
seaborn-whitegrid
seaborn
Solarize_Light2
tableau-colorblind10
_classic_test
The Matplotlib Style "dark_background" looks pretty good when paired with the new Dark Grey 11 theme.
PySimpleGUI 2020-09-28T11:18:20Z
Apologies for the slow progress
This readme rework has been ongoing for over 1 1/2 weeks. It's causing everything else listed earlier for the short-term to get pushed out. Progress is being made, every day, just at a much slower pace than expected. Lots of restarts and re-writes. There have been a number of medical issues that have complicated things considerably, but that's no excuse.
Even when the shortened readme is completed, there are still a number of parts of it that I want to complete like a much better "user spotlight" where you can submit images and info about your applications in a better / more visible way than the current primitive User Screenshot issue.
While some of the nicer screenshots are being pulled out for this condensed document, there is also a massive scrapped set of images from the over 1,000 GitHub repositories that GitHub lists as using the tkinter port of PySimpleGUI. So, these images don't include any of the other ports. Perhaps I'll get those scrapped soon too.
The images, all 3,200 of them, can be viewed here:
https://www.dropbox.com/sh/g67ms0darox0i2p/AAAMrkIM6C64nwHLDkboCWnaa?dl=0
Some may not be of PySimpleGUI windows themselves and are instead supporting documents or other images in the repo. Apologies for you having to endure those.
I've not been able to weed them out, so expect a fair number of them to be my early test images and other images that were used to create the documentation. My hope is that because they are really simple to scroll through, you'll be able to quickly scan and pick out a few that you may draw inspiration from.
There are a lot of good things right on the horizon for PySimpleGUI in 2020. The user support has been fantastic and I'm really grateful for everyone's support and patience. I've got a couple of difficult days ahead in my non-online / real world, so I might not be online as often as usual. Just know it's not because I'm ignoring your requests or don't want to help. Back soon and hopefully will be able to wrap up this current set of distractions.
Thank you all again. You're the BEST user community on the net!
PySimpleGUI 2020-10-03T23:48:45Z
Readme
The new readme is posted!
It doesn't LOOK like 2 weeks of work, but somehow that's what it took. There is some follow-in documentation work that now needs to happen to the primary documentation a well as a new education tab to the main docs.
Hopefully it will provide new visitors a little more compact overview than the massive 100's of pages the first readme has.
Thanks to everyone that's been patient while I've stepped away for several days at a time.
PySimpleGUI 2020-10-07T18:52:18Z
4.30.0 Right Around the Corner....
Working hard on getting the 4.30.0 release out the door so that I can then (finally) get back on the Qt release.
The 4.30.0 release has the new "User Settings" API so there's been work to get that tested and finished up. No official demo has been made yet, but it won't take long to make one. I want to make one that shows realistic use such as saving/loading the program's theme.
The most recent hold-up however has been button focus indicators. It's only been today that I discovered what I think will be the right way of dealing with the focus indicators. If left to default values, the buttons and other elements always looked terrible. It's why the "highlight thickness" was set to 0 several releases back. What I didn't realize at that time was that it removed the focus indicators entirely.
Linux and Windows differ in focus indicators
Here are the buttons on the latest test harness when running on Windows. The button with the label "Button" has the focus.
Sorry about both a "Sponsor" button and a Buy Me a Coffee. I'll be removing the sponsor one for 4.30.0. :-) Anyway, back to the focus....
Windows
Linux
As you can easily see, there's a big difference in how focus is communicated. It's only been today that I pieced together that a good approach to use is to use the button colors to color the focus.
Linux - new method
If I use the theme's button colors then the highlights look nice. There's another addition to the test harness that enables you to try out the different themes so that testing these kinds of things is easier. Here's how the highlights look with the Dark Red theme. Notice how the highlight matches the buttons better.
The only problem with this color algorithm is that some themes have button text that matches the background color, which will make the highlighting disappear. So, as you can see, I got hung up a little bit while testing the release and as a result have been doing a little more development when I was supposed to just be testing.
PySimpleGUI 2020-10-09T18:25:34Z
Thank You Japanese Users!
Not sure how many users follow Twitter. Almost daily someone from Japan posts a comment about PySimpleGUI, or a new tutorial is posted that's written in Japanese. They're really kind posts and I find them personally uplifting to read. As a way to say "thank you" to these awesome users, I thought perhaps translating the readme file into Japanese using a human being to translate would be a nice gesture.
You'll find a Japanese version of the readme located here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/readme.ja.md
There is some question as to how well the translation was done with some people commenting that some of the nuances are not quite right. I'm getting some help from a Twitter user so hopefully, it'll be a bit better soon.
I was able to get the code translated at well so that the screenshots look correct.
Here's a short potion with a code example:
PySimpleGUI 2020-10-10T17:00:36Z
New Demos - User Settings & Vertical Adjustments
Two new demos have been published this week. The vertical alignment demo can be used with the already published 4.29.0 release. The User Settings APIs demo is best used with the upcoming 4.30.0 release or by running the 4.29.0.17 version that's on GitHub. The documentation for the User Settings APIs will be in the documentation included with the release. It's already written and will be posted with the PyPI release.
Vertical Alignment Demo:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Layout_Vertical.py
User Settings Demo:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_User_Settings.py
While waiting for the documentation and release to be published, you can use these demos as a design pattern that you can copy and modify.
Note that one of the layouts in the Vertical Alignment Demo uses unpacking within a list. Support for unpacking inside of a list was added in 3.5. Because PySimpleGUI is compatible with Python 3.4 I placed that particular example inside of a Try/Except block so that it did not generate a syntax error. Otherwise, you would not be able to run the file at all on a 3.4 system.
PySimpleGUI 2020-10-11T19:39:15Z
The Joys of Linux
So the 4.30.0 release was going really well! I've been testing it for the past week on Windows and Linux. Yesterday I was running with the latest Python version 3.9.0 when disaster struck. My PyCharm settings were overwritten on my Linux system. I didn't think it would be the disaster that it's been, but it's been a disaster. Running multiple versions of Python on Linux with PyCharm wasn't a very easy thing to set up initially and I'm struggling to get things going again.
The good news is that the new highlighting for Linux buttons, checkboxes, and radio buttons worked great. 3.9.0 worked fine with PySimpleGUI as the tkinter version didn't change on Linux and I've been testing it on Windows where it has a tkinter version of 8.6.9.
OK, well, back to rebuilding my environment. I really hoped to get the release out this weekend, but it's not looking good now. Maybe I'll come out of this with a more robust Linux setup, or maybe it'll just be a lost weekend.... hoping for the more robust option....
Back Up & Running
Thankfully adding the interpreters back worked out OK when I added them as virtual environments.
I recently started to use pyenv
to manage multiple installs of Python on my Linux setup. I'm running Mint.
I was able to add back the 3.6.9 and 3.9.0 interpreters and am back to testing the release!
PyCharm makes it easy to switch around the versions of the interpreter to use.
Focus Outlines
Part of the delay of 4.30.0 was due to the last-minute addition of the focus outline was what started this mess.
I wanted to get focus indicators working correctly on Linux. They're done entirely different than on Windows. On Linux, there is a "highlight" that is used to show focus. This setting is not used on Windows.... thus the need to do more testing this time around on Linux than usual.
The default colors are derived from the Theme's colors.
I know someone's going to want to set it to some other color than what PySimpleGUI sets, so a new paramter was added to Button elements.... highlight_colors
:param highlight_colors: colors to use when button has focus (highlight, background). None will use computed colors. Only used by Linux and only for non-TTK button
:type highlight_colors: Tuple[str, str]
PySimpleGUI 2020-10-12T21:36:53Z
New Demo - GitHub File Copier
I decided to post a utility I use every day. I wasn't sure if others would find it to be of value, but maybe someone will. Minimally it shows another example GUI and how to implement it using PySimpleGUI.
I think these are the highlights of features you may be interested in:
-
Opening a file for editing in PyCharm from your program
-
Multi-colored output using Multiline element
-
Filtering Listbox entries based on an input element
Uses
The Demo Programs area is getting to be pretty big and I'm constantly modifying existing demos or creating a new one. I was using PyCharm to browse these files, choose to edit, and also to copy from my working folder to the GitHub folder. It has been much easier using this little application than using PyCharm.
If you're managing a list of files that you modify often and copy to a GitHub folder, then perhaps it'll be of interest to you. I run the GUI version of GitHub, not the command line version. As a result, I have a button that launches GitHub. This makes for a smooth overall process. I select the files I want to check into GitHub, click the copy button, then click the Launch GitHub button where I can then add a comment, etc, and check the files into GitHub.
Oveall it's less than 100 lines of code. It's made for a very efficient process for dealing with these Demo Programs. By having a filter I'm able to quickly locate one or more Demo Programs. I can then run, edit or copy them. It's a lot quicker than browsing via PyCharm.
PySimpleGUI 2020-10-14T11:40:47Z
It Could Be So Much Better
I'm pretty sure a number of users have thought that, a number of times. Parts of the documentation are too long, too old, or suck. There are piles of problems in some releases. And, the 2020 pace has not been as productive as 2019.
In some ways, opening up the project to pull requests would help the project from a workload perspective. What it would do for me personally is change the amount of time I spend on each activity. I try and give everything I have to this project. Adding something doesn't mean I can work harder and add it for free. Something else has to be done less. The amount of time is constant. The % of each activity is what changes.
I enjoy this project. There are a number of you that enjoy it too. I get some really heartwarming emails that tell me I'm on the right track, even if a speeding train isn't on that track at the moment. I enjoy the mix of activities. What I don't enjoy is merging in other's code and then being responsible for it using it. I don't want to do code reviews. I don't want to be responsible for someone else's code or documentation. So, I'm choosing not to do that. I would be unhappy and as a result, the project would ultimately suffer.
I basically work for free and as a result, it seems like I should have a pretty big influence on how my time on this project is spent. There are a select few that do help, some paid, others not. I hired a translator to create the Japanese version of the readme this past week. There are some times where I do get some help, but it's unusual, and I like it that way.
I'm going to do the best I can for the project. You've got my promise on that one. I'm dedicated to making it a great experience for everyone. I hope you're satisfied with the results you've achieved so far and I'm looking forward to a bright future ahead. Thank you to everyone for your support, in whatever form that takes.
Could PySimpleGUI be better? Of course, it can be a lot better. And, maybe I'll be able to do enough for everyone to be happy and successful. If I'm not able to get it and keep it at "good enough", then, well, it's been a lot of fun and I hope people have had a grand time. I sure have.
PySimpleGUI 2020-10-14T13:28:32Z
Theme Color Swathes Demo
Posted another theme-related demo. There are some image editing / paint programs with an eye-dropper tool to grab colors from another part of the screen. To make it easier to grab colors from PySimpleGUI themes, I made this program that displays the colors found in each theme as a series of smudges of each color. It enables easily sampling of colors by a dropper.
Interactivity
You can interact with the window in these ways:
-
Left-click one of the colors and it will be copied to the clipboard if you have
pyperclip
installed (python pip install pyperclip
). * Hovering over a color with your cursor will display the hex value as a tooltip -
Right-click a color to see a popup menu with the hex value. Choose that menu item with a left click and it too will be copied to the clipboard
While only 54 lines of code, there's a lot happening in this demo, including a couple of clever uses for PySimpleGUI components.
Tuple Keys to Achieve Unique Keys
For example, when you click on a color, it will return an event. Because we want the color when a left click is made, there are a lot of ways of making this happen. You could put it into the metadata
. I chose to put it into the key and thus will be returned as part of the event. Since some colors are used in many themes (e.g. black and white) the color alone can't be the key as they need to be unique. The solution was to use a tuple for the key.
A tuple is used so that the first value in the tuple is unique in the layout. A sequential counter is all that's needed. The second value in the tuple is the color code itself. So, if an event is a tuple, we know that the color is in the second position of the tuple.
PySimpleGUI 2020-10-15T00:19:38Z
4.30 Likely Tomorrow....
Still working on the documentation. Added the swatches demo above to the code as another theme previewer option. You can get to it from the test harness or can call it directly.
Getting the release notes together now. Have a few more doc changes to make and then will be good to go. It's all tested on multiple versions of Python, multiple operating systems and the Pi too.
Looking forward to getting it out, and onto Qt.
PySimpleGUI 2020-10-15T18:37:49Z
GitHub Stars - Nominate Your Favorite GitHub Users
I just learned about a program that GitHub has called "GitHub Stars".
You can nominate up to 3 developers. I had no trouble listing 3 people that I found particularly helpful that I thought were also impactful to the community at large.
Take a moment from your busy day to say "thank you" to some of your favorite developers by nominating them. Science has shown a direct link between gratitude and happiness. Seriously....... being thankful can make you feel happier. Do it for yourself if not for someone else. 😀 Perhaps be "selfishly thankful".
PySimpleGUI 2020-10-15T20:45:47Z
4.30.0 PySimpleGUI 14-Oct-2020
User Settings APIs, lots more themes, theme swatch previewer, test harness additions,
focus indicators
-
Added shrink parameter to pin,
-
added variable Window.maximized,
-
added main_sdk_help_window function,
-
New themes - DarkGrey10,DarkGrey11 DarkGrey12 DarkGrey13 DarkGrey14, Python, DarkBrown7
-
Highlight Thickness for Button, Radio, Input elements
-
Set to 1 now instead of 0 so that focus can be seen
-
Color is automatically set for buttons, checkboxes, radio buttons
-
Color can be manually set for Buttons using
highlight_colors
parameter -
Only used by Linux
-
-
user_settings APIs
-
Whole new set of API calls for handling "user settings"
-
Settings are saved to json file
-
For more info, see the documentation
-
-
Radio.update - added text, background & text colors parameters
-
Multiline & Output Elements:
-
added parameter echo_stdout_stderr
-
if True then stdout & stderr will go to the console AND to the Multiline
-
-
"ver" is shortened version string
-
modal docstring fix in some popups
-
image parameter implemented in popup_scrolled
-
Graph.draw_image - removed color, font, angle parameters
-
fixed blank entry with main program's theme previewer
-
added Window.set_min_size
-
error message function for soft errors
-
focus indicator for Button Checkbox Radio using highlights
-
added main_sdk_help Window
-
added theme_previewer_swatches function
-
added "Buy Me A Coffee" button
-
updated
pin
layout helper function - addedshrink
parameter -
Main debugger window set to keep on top
PySimpleGUI 2020-10-16T18:27:38Z
User Settings - A New Era (for my programs)
I'm starting to really see the power these user settings things can have. They essentially add "history" or state that lasts for, forever, essentially.
This is a fun new demo program.
import PySimpleGUI as sg
"""
Demo - Save previously entered strings as a Combobox entry by using user_settings calls
It's literally 1 parameter in the layout to get the list of previously used entries shown.
Then, when the OK button is clicked, it's 4 more lines of code to save the newly added
name into the saved list.
Copyright 2020 PySimpleGUI.org
"""
def main():
layout = [[sg.T('This is your layout')],
[sg.T('Enter or choose name'), sg.Combo(sorted(sg.user_settings_get_entry('names', [])), size=(20,1), k='-COMBO-')],
[sg.OK(), sg.Button('Exit')]]
event, values = sg.Window('Pattern for saving with Combobox', layout).read(close=True)
if event == 'OK':
sg.user_settings_set_entry('names', list(set(sg.user_settings_get_entry('names', []) + [values['-COMBO-'],])))
print(f"You chose {values['-COMBO-']}")
if __name__ == '__main__':
main()
The cool thing about combo boxes is that they are actually a normal text input widget, except they have a drop-down list portion too.
Let's say you have a program where you enter some value and maybe it's something you enter the same value for often. Maybe it's your login ID. In this demo, I simply called it "name".
When you run the program, this is the window that's shown.
You can directly type into the blank area shown for the Combobox. You can also click the down-arrow and see the previously entered values, sorted:
A Small Amount of Work for a Better User Experience
If you look at what it took to provide this interface to a user, it required a single parameter in your Combo call
and a single line of code to add a newly entered value to the history of values.
sg.user_settings_set_entry('names', list(set(sg.user_settings_get_entry('names', []) + [values['-COMBO-'],])))
PySimpleGUI 2020-10-17T01:29:08Z
A "Better" File Browse
Here's a sneak peek at an upcoming demo program. The idea is to improve the standard file browsing experience by recalling not only the last entry made but also retaining/using a history of previous entries.
If you only want to use the previously entered value, then you don't need a Combo element for that. You can continue to use an Input element. But if you want to retain and use historical values, you'll want to use a Combo. Here's a rough prototype for an upcoming Demo Program using this technique
import PySimpleGUI as sg
"""
Soon-to-be Demo of a Better File / Folder Input Window
This construct is very common in PySimpleGUI.
[sg.InputText(size=(50,1), key='-FILENAME-'), sg.FileBrowse()],
The new user settings APIs can significantly improve the experience.
Two new capabilities are presented in this demo
1. Recalling the last entry
2. Recalling a history of all of the previous entries as a Combo instead of Input Element
"""
# ------------------- The Old Way -------------------
layout = [ [sg.Text('My Window')],
[sg.InputText(size=(50,1), key='-FILENAME-'), sg.FileBrowse()],
[sg.Button('Go'), sg.Button('Exit')] ]
event1, values1 = sg.Window('Window Title', layout).read(close=True)
# ------------------- The New Way -------------------
layout = [ [sg.Text('My Window')],
[sg.Combo(sg.user_settings_get_entry('filenames', []), default_value=sg.user_settings_get_entry('last filename', ''), size=(50,1), key='-FILENAME-'), sg.FileBrowse()],
[sg.Button('Go'), sg.Button('Exit')] ]
event, values = sg.Window('Window Title', layout).read(close=True)
if event == 'Go':
sg.user_settings_set_entry('filenames', list(set(sg.user_settings_get_entry('filenames', []) + [values['-FILENAME-'], ])))
sg.user_settings_set_entry('last filename', values['-FILENAME-'])
The first window you'll see is the standard get a filename window.
The second window is the one with historical values and looks something like this:
PySimpleGUI 2020-10-20T13:47:13Z
Hooked on history
I'm officially hooked on the user experience of having a history for elements.
My GitHub copy program, that I run all day every day, now has a single-file launch added at the bottom
A Shorter Way Coming (I hope)
While it's literally one or two lines of code to get this feature, they're a little bit tricky to add.
I want to design some "user defined elements" or something along that line of thinking to make these kinds of entry elements easy to make.
The Last Entry
Having only the last entry entered into a field is the easiest for a user to implement. When you're testing a piece of code and re-using the same file/entry over and over, having the program remember that value and fill it in automatically is GOLDEN. WOW, what a time saver.
Replaced Combo Demo
I've replaced the demo that showed only a combobox with history with a demo that shows an Input element that recalls the last entry and a combobox that recalls the entire history.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_User_Settings_Remember_Input_and_Combo.py
Here's the entire program minus the header comment:
import PySimpleGUI as sg
def main():
layout = [[sg.T('This is your layout')],
[sg.T('Enter or choose name'), sg.Combo(sorted(sg.user_settings_get_entry('names', [])), size=(20,1), k='-COMBO-')],
[sg.T('Remembers last value'), sg.In(sg.user_settings_get_entry('input', ''), k='-INPUT-')],
[sg.OK(), sg.Button('Exit')]]
event, values = sg.Window('Pattern for saving with Combobox', layout).read(close=True)
if event == 'OK':
sg.user_settings_set_entry('names', list(set(sg.user_settings_get_entry('names', []) + [values['-COMBO-'],])))
sg.user_settings_set_entry('input', values['-INPUT-'])
print(f"You chose {values['-COMBO-']}")
if __name__ == '__main__':
sg.user_settings_filename(path='.')
main()
A User Settings Coding Convention
I'm on the verge of creating a new coding convention for my demos. I'm sure some don't agree with my coding conventions, but, I can't please everyone and I like having a convention that I follow for consistency.
I really like being able to scan the code and if I run across a string, anywhere in the code, that looks like this -SOMETHING-
, you can bet your ass it's a key from a layout.
As I scan through the code that uses user settings, I'm faced a similar challenge. Sooooo......
Here's the convention. Still going to place the dashes at the begging and end, but rather than being upper case, user settings will be lower case.
Here's the demo code again, using the new user_settings coding convention:
import PySimpleGUI as sg
"""
Demo - Save previously entered strings for Input and Combo elements by using user_settings calls
It's literally 1 parameter in the layout to get the list of previously used entries shown.
Then, when the OK button is clicked, it's one line of code to save the newly added
name into the saved list.
Copyright 2020 PySimpleGUI.org
"""
def main():
layout = [[sg.T('This is your layout')],
[sg.T('Enter or choose name'), sg.Combo(sorted(sg.user_settings_get_entry('-names-', [])), size=(20,1), k='-COMBO-')],
[sg.T('Remembers last value'), sg.In(sg.user_settings_get_entry('-input-', ''), k='-INPUT-')],
[sg.OK(), sg.Button('Exit')]]
event, values = sg.Window('Pattern for saving with Combobox', layout).read(close=True)
if event == 'OK':
sg.user_settings_set_entry('-names-', list(set(sg.user_settings_get_entry('-names-', []) + [values['-COMBO-'],])))
sg.user_settings_set_entry('-input-', values['-INPUT-'])
print(f"You chose {values['-COMBO-']}")
if __name__ == '__main__':
sg.user_settings_filename(path='.')
main()
PySimpleGUI 2020-10-25T18:04:02Z
GitHub File Manager Demo Update
Over the past few days, a number of changes have been made to the GitHub file manager demo.
Most of the changes were the addition of user_settings and the Settings Window.
There was also a "grep" feature added. If you type into the "Find" input
then the list of files will be narrowed to be only those files that have the string you've entered. The case is ignored so you don't have to worry about getting the case correct.
For example, if I want to find all of the demos that make calls to the user_settings API, I can enter "user_settings" into the find input and the file list is shortened to only those files that contain the string entered.
Since the constants defined previously are now user settable, you can specify any code editor you want. You're not limited to PyCharm. The assumption is that invoking your program with the file to edit on the command line is all that's required to open it. I tested this with NotePage++ and PyCharm.
More User Settings
The demo program in the last post has continued to get some attention.
Decided that it's time for this program to have a real "settings window". This removes the need for constants at the top of the program that provides the location for your GitHub program or your editor.
The code had 4 constants at the top.
DEMO_PATH = r'C:\Python\PycharmProjects\PSG\DemoPrograms'
GIT_DEMO_PATH = r'C:\Python\PycharmProjects\GitHub\PySimpleGUI\DemoPrograms'
GITHUB_PROGRAM = r'C:/Users/mike/AppData/Local/GitHubDesktop/GitHubDesktop.exe'
PYCHARM_BATCHFILE = r"C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.1\bin\pycharm.bat"
These are easy enough for someone to change, but since we're designing GUI programs, why not make our programs in a way that doesn't require them to be edited when switching to a new environment?
Those 4 lines of constants have been replaced by this window:
I had an epiphany when writing this settings window.
"User Settings" are like persistent global variables.
That's exactly what they are in this program. If a function wants to know the name of the GitHub program, it can get this value by making this call:
Instead of using a global variable, user settings becomes a place where global information is stored and shared.
Defaults
If you use the default path and filename for your settings file, then you only need the calls to get and set. It's really safe to use the default values for the path and filename because doing so will place them in a known location for settings files and the name will be unique to the filename. As long as you don't name your .py files the same name, then your settings for that file will be unique.
It's made for a very pleasant experience to code in this way.
The downside of no longer using constants is that you need a "Settings Window".
Settings Window
They're not as bad to make as you may initially think. We're writing GUI programs so why not toss in a settings window to be kind to your user?
This added window is quite simple in reality. It has a layout, a one-shot read, and a block of code to save the settings if the OK button is clicked. There's not even an event loop since it's a one-shot window.
The result is that in about 15 lines of code, your user has complete control over their program's settings without needing to modify the source file. That's really great for such a short bit of code!
Here is the code for the "Settings Window" shown above.
def settings_window():
"""
Show the settings window.
This is where the folder paths and program paths are set.
Returns True if settings were changed
:return: True if settings were changed
:rtype: (bool)
"""
layout = [[sg.T('Program Settings', font='DEFAIULT 18')],
[sg.T('Path to Demos', size=(20,1)), sg.In(sg.user_settings_get_entry('-demos folder-', ''), k='-DEMOS-'), sg.FolderBrowse()],
[sg.T('Path to GitHub Folder', size=(20,1)), sg.In(sg.user_settings_get_entry('-github folder-', ''),k='-GITHUB-'), sg.FolderBrowse()],
[sg.T('Github Program', size=(20,1)), sg.In(sg.user_settings_get_entry('-GitHub Program-', ''),k='-GITHUB PROGRAM-'), sg.FileBrowse()],
[sg.T('Editor Program', size=(20,1)), sg.In(sg.user_settings_get_entry('-Editor Program-', ''),k='-EDITOR PROGRAM-'), sg.FileBrowse()],
[sg.Combo(sg.theme_list(), sg.user_settings_get_entry('-theme-', None), k='-THEME-')],
[sg.B('Ok'), sg.B('Cancel')],
]
window = sg.Window('Settings', layout)
event, values = window.read(close=True)
if event == 'Ok':
sg.user_settings_set_entry('-demos folder-', values['-DEMOS-'])
sg.user_settings_set_entry('-github folder-', values['-GITHUB-'])
sg.user_settings_set_entry('-GitHub Program-', values['-GITHUB PROGRAM-'])
sg.user_settings_set_entry('-Editor Program-', values['-EDITOR PROGRAM-'])
sg.user_settings_set_entry('-theme-', values['-THEME-'])
return True
return False
They tend to follow this pattern:
-
Your layout contains calls to
user_settings_get_entry
to fill in the current values -
After the window is closed,
user_settings_set_entry
is called for each setting your window changes
By embedding the get_entry
call into your layout itself means that your code isn't increased in terms of adding new lines of code. Also, it's clear when you see a call to get_settings that the default value for the element is coming from your settings file.
Let's look at one of those lines from the layout
[sg.T('Path to Demos', size=(20,1)), sg.In(sg.user_settings_get_entry('-demos folder-', ''), k='-DEMOS-'), sg.FolderBrowse()],
The Input
element is initialized to the setting -demos folder-
or ''
if no setting is found.
If the OK button is clicked, then all of the values from the window are saved as user settings. They are simply a series of calls to user_settings_set_entry
and thus easy to spot.
Since we were looking at the Demos Folder a moment ago, let's find the matching settings save for that value:
Yes, it's that easy! You simply save the value found in the input element.
More Ahead
It's safe to assume that in future demos you can expect to see more of these Settings Windows. They make for a much more pleasant user experience than requiring the user to edit the code. It also makes distributing programs that require an API key much more uniform. Your end-user doesn't need to edit the code to input their API key. They can do that by entering the key in a settings window.
PySimpleGUI 2020-10-25T20:48:21Z
A MIDI Player Demo
I'm a user of PySimpleGUI just like you guys. I write quite a bit of code that no one sees or uses. One such program is this "MIDI Looper" program.
I thought I would take a moment and share it since it's a unique use of PySimpleGUI and maybe it'll inspire you to write something for use in music.
It's best heard rather than seen.
https://www.youtube.com/watch?v=auv_DbSQuD8
This program is great for learning songs on a piano, assuming you've got a piano that is capable of being controlled by MIDI. Yamaha makes a piano series called the Disklavier that is controllable via MIDI and is what is shown in the video. There are other manufacturers that make similar pianos including Steinway. Yamaha is probably the best of anything available since they've been doing it longer than everyone else.
The GUI could use a bit more work, but since it works "good enough", I'm plenty happy. The 2 areas it could benefit from some work the most are in positioning within a song and the "section looping" specification.
PySimpleGUI 2020-10-26T09:33:32Z
The Black Code Formatter
Black is all the rage at the moment in Python, particularly in the publishing world. Some tutorial sites require that code be run through Black prior to publication.
Formatting is a personal preference, to some degree. There are some things about PySimpleGUI application code that I believe make it a poor candidate for being Black-formatted.
Horizontal Code Layout vs. Vertical
One of the primary benefits of PySimpleGUI over the other GUI packages is that the amount of code is greatly reduced. One of the primary ways this is achieved is through the liberal use of parameters. Instead of writing several lines of Python code, the same information is contained in a single parameter passed to a PySimpleGUI call.
The result is that code that was many pages vertically now occupies a single page of code that is more horizontal in nature, due to a large number of parameters.
An Example
Let's look at a program that was mentioned a couple of posts back, the GitHub file manager and the new "Settings Window". Here is how that window appears:
The code, as written, for the layout of this window is:
We all know the way layouts work, they are lists of lists, with each list representing a single "row" of the GUI.
Our Window has 7 rows of GUI elements, and it's no mistake nor surprise that the layout is 7 lines of Python code. Yes, these are long lines of Python code, but they're meant to be. If you want to modify something in your layout, you know which line to "dig into". Normally you're not interested in the specifics of the code on each row.
Quickly locating code in a source file is an important capability. I'm suggesting that more lines, that are easier to read in a vertical direction, is a bad thing in this situation.
Lets's look at how Black reformatted these 7 lines.
Our 7-line layout is now 34 lines long.
Of course, not only did the layout lengthen, the entire file increased in size. The original was 275 lines in length. The Black formatted version is 406 lines. It's a more than 50% increase in length.
The main window's layout also increased to 82 lines from an original 22 lines.
It's Not All Bad
One thing that having every parameter on a single line does, is give you the option to comment out individual parameters as you're writing code. This can be a powerful format when used judiciously. It's the Window
obejct that I find myself using single-line parameters on the most.
This bit of code is part of the PySimpleGUI Test Harness. I can quickly turn on and off options using this format.
It's Subjective
Of course, many of you may prefer the more vertically oriented code and that's great. In my opinion, it's better to have these long horizontal lines so that the layouts match the rows of the GUI window and to make navigating the file easier. The tradeoff is that the code may appear more complex because multiple parameters are on a single line.
Compactness is near the top of the list for things that I love about Python that was missing in programming languages I used for decades prior to Python. A single-line loop achieved using a list comprehension was an exciting find. Black shatters that compactness.
When this:
becomes this:
It stops feeling like Python code to me.
PyCharm Is One Alternative
PyCharm's code formatter tends to be much more gentle. There are others out there as well that you might want to try. Your favorite editor may have one built-in as well. Give them a try. See what works best for you.
PySimpleGUI 2020-10-26T18:57:18Z
THANK YOU FOR THE SUPPORT!!!
Over the past couple of weeks, since adding the BuyMeACoffee and a proper Sponsor Button, there have been a lot of generous people pitching in to help. It's SO SO appreciated. It's expensive just keeping the project going with all of the recurring costs. I'm also making a Udemy course so income is helping that effort. All of the help provided goes back into this project, this I can assure you.
Best user community on the net! You guys and gals have been so supportive in many ways. I love the emails that you've been sending. Keep them coming, they're really helpful to read. I think the part I like the most about this project is the visual impact I can see that it's having. I literally get to see my work being used to create the things you are dreaming up. It's really motivating to see what you're building, so please keep showing everyone what you're making.
If you've got an application to share, post a screenshot here:
https://github.com/PySimpleGUI/PySimpleGUI/issues/10
I'm working on a better way for PySimpleGUI users to share their projects, but I'm not done with it yet. In the meantime, drop your images into the User Screenshots Issue with a link to your Repo. And, don't forget to add screenshots to your readme!!!!! It WILL get more attention, this I can promise you.
PySimpleGUI 2020-10-27T18:04:40Z
Your Issue Form Just Got Easier.... sg.main_get_debug_data()
Filing an Issue here on GitHub just got a lot easier if you're running the tkinter version (and have the version from GitHub)
Not long ago a new function was added to PySimpleGUI. It's posted to GitHub but not yet on PyPI.
When you call this function, you'll see a window like this one:
If you leave the window open then you can paste directly into your issue the version data. The data is placed on the clipboard for you, but because of a problem with tkinter, if you close the window, the information on the clipboard is deleted. -sigh-
With the window open, I pasted into this issue, and here is what was pasted:
Python version: 3.6.2 |Anaconda, Inc.| (default, Sep 19 2017, 08:03:39) [MSC v.1900 64 bit (AMD64)]
port: tkinter
tkinter version: 8.6.6
PySimpleGUI version: 4.30.0.12
PySimpleGUI filename: C:\Python\PycharmProjects\PSG\PySimpleGUI.py
It seems like I need to jam out a new release this week to get this and a few other recent additions out. I wanted to get the Qt release out first, but these tkinter features would really be handy to have available as a PyPI release. So, perhaps watch for version 4.31.0 this weekend.
I've been starting the functions with main_
that have a GUI interface that applications may call. Another one is the main_sdk_help()
which will show you the SDK help window.
PySimpleGUI 2020-10-28T12:55:51Z
Launching PyCharm on Mint Linux
I've been testing the GitHub File Manager demo. One of the "settings" is the command to launch PyCharm to edit a file. This is the value that works on my Mint distribution:
If you don't find the file there, search your system for pycharm.sh
. It should be somewhere. Paste that value into the "Editor Program" field in the Program Settings window.
PySimpleGUI 2020-10-31T17:09:12Z
Have been out.... back this weekend....
I'm sorry that I've been away for a couple of days. I've had some pet emergencies happening and it's caused a delay across the board. That means answering the Issues has been delayed, getting the Qt changes tested and posted were delayed. I'm hoping to get caught up this weekend and get a release of PySimpleGUIQt posted for people to try the new Styles code.
HUGE thank you to @jason990420 for providing amazing Issue support. And a big thank you to everyone's that's helping by filling in the Issue form, providing test code, etc. It really really helps make the process move smoother when the information is posted and doesn't need to be asked for.
PySimpleGUI 2020-10-31T19:38:59Z
Qt port update
Here is a before and after shot of the test harness for PySimpleGUIQt.
I'm really happy with how close they are and with the changes to the way Stylesheets are being created.
There is still a lot of work to go, but am checking in what I've got so far. Hopefully not very many things are broken. I've not dug into the "Update" code very much yet, so give me a little time to get that part right.
A huge huge thank you to @nngogol for his expert help. He's got a ton of Qt experience that has been invaluable. He wrote the PySimpleGUI Qt Designer code a couple years back, so he's uniquely qualified and has a great understanding of both PySimpleGUI and Qt.
Posted 0.35.0.15. Please let me know if I've broken your app!
PySimpleGUI 2020-11-01T17:06:30Z
Some Qt Enhancements Posted in Last Update
As part of the Styles update, not only did some problems like padding get correctly fixed, a number of new features were added. The biggest welcome may be in setting the Table and Tree headers. You can now set the font and colors for the headers, just like you can in the tkinter port.
Both Table and Tree elements got these new parameters:
:param header_text_color: sets the text color for the header
:type header_text_color: (str)
:param header_background_color: sets the background color for the header
:type header_background_color: (str)
:param header_font: specifies the font family, size, etc
:type header_font: Union[str, Tuple[str, int]]
Menubar elements are also styled now according to the background color of the window and the text color. However, these have not been turned into formal parameters that can be changed... yet. They are simply set to the window's defaults for the time being. It's still quite a bit improved over the previous default.
I'm still pondering over how style sheets should be exposed to user code. I definitely want to open up the style sheets for users to modify directly if they so choose. This can already be done by accessing the Element.Widget
member variable, but with the new Styles code, I want to make it a bit easier to get the current style sheet set by PySimpleGUI and to update it. It should at least be possible to get the last style sheet set.
PySimpleGUI 2020-11-02T21:22:00Z
Qt Stylesheets
OK, I've been in Stylesheet hell for the day. Pretty much blew most of the day trying to get padding to work correctly with Frames. I'm at a not-so-great point. At the moment Frames have a pad=(0,0). What's worse is that if they are placed inside of a Column element, then the frame loses the border. I've clearly got a bunch of work/learning to do with these stylesheets and with how I'm making Column and Frame elements. Qt seems to be treating stylesheets in a more global way than I expected. The styles are propagating downward, overriding settings made in nested layouts.
Not giving up.... but, damn, the going is slow....
Also, added Element.set_stylesheet
and Element.get_stylesheet
to get and set the stylesheet within Qt. I've not yet published info about the internal QtStyle
object that is used to create stylesheets within PySimpleGUI. It's a really cool class that works well.
Edit Nov 3.....
Last night I realized that I wasn't setting the border correctly on Frames. As a result, it would inherit the setting from the parent. Basically, by not specifically setting the border on the Frame, the Column's border setting (width=0) was getting picked up by the Frame and thus losing its border. The fix was straightforward.... set the border on the Frame. Works great. Back to forward progress.
PySimpleGUI 2020-11-03T16:21:08Z
Center A Layout In A Window
I was asked (by long-term supporter @M4cs), how to center something in a window. Seeing how the majority of 2020 was spent getting the Tkinter port of PySimpleGUI polished up so that vertical alignment was "finally done right", it seemed like something that should be possible using only PySimpleGUI call... no calls to Tkinter directly allowed.,
It turned out to be trickier than I thought. As a result, there's a new demo program posted:
Demo_Layout_Vertical_Centered.py
Here is the code for the demo:
import PySimpleGUI as sg
"""
Center a column in a window
Solves a very specific kind of layout.
If you want to have something centered in a Window, this is a good way to do it
The "trick" here is:
* the first row of the layout has a Text element that expands vertically
* the row with the Column has a text element that expands horizontally
This expanding Text element is what will cause the Column element to be centered
Copyright 2020 PySimpleGUI.org
"""
def main():
column_to_be_centered = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Text(size=(30,1), key='-OUT-')],
[sg.Button('Go'), sg.Button('Exit')] ]
layout = [[sg.Text(key='-EXPAND-', font='ANY 1', pad=(0, 0))], # the thing that expands from top
[sg.Text('', pad=(0,0),key='-EXPAND2-'), # the thing that expands from left
sg.Column(column_to_be_centered, vertical_alignment='center', justification='center', k='-C-')]]
window = sg.Window('Window Title', layout, resizable=True,finalize=True)
window['-C-'].expand(True, True, True)
window['-EXPAND-'].expand(True, True, True)
window['-EXPAND2-'].expand(True, False, True)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Go':
window['-OUT-'].update(values['-IN-'])
window.close()
if __name__ == '__main__':
main()
The thing you want to center is first placed in a Column element. It can be 1 element, like a Button, or an entire layout, as shown in the demo.
As mentioned in the comments, the mechanism that makes all this work are 2 elements that will expand as the window is changed. You need something above the Column element and you need something to the left of the Column.
Here's the demo in action
PySimpleGUI 2020-11-08T14:47:15Z
User Settings Gets Object Interface
The recent User Settings feature for the tkinter port was released as a series of function calls. The recent addition of QtStyles interface for the Qt port has been a fantastic addition to the Qt port and has made working with StyleSheets a lot easier. It's the [ ] dictionary style coding patterns that made the style sheet interface much easier to work with. It became clear that because the User Settings are basically a "persistent dictionary" that they too could benefit from this design pattern. So, I've opened up the UserSettings
class so that you can reference the settings using the dictionary style [ ].
You can continue to use the function interface if you're more comfortable working with those. But, if you're OK with using a class for your settings and want to use this [ ] interface, then consider using the UserSettings
class. Of course, the documentation for the class isn't completed... but the docstrings are.
If you want to get the same default path and filename as the function interface, then create a UserSettings
object with no parameters.
For example, if you want to get the value of the setting 'test'
, then you would write it this way currently:
You can now achieve the same thing by first creating a UserSettings
object, and then looking up the 'test'
setting
Setting the value is a similar translation. Using functions it would be:
Once the object is created, to set the same setting can be written as:
If a setting doesn't exist, then None
will be returned. With the function calls, you can specify the default value you would like returned if the setting doesn't exist. Using the [ ] interface, you obviously can't indicate the default value. You can, however, change the None
setting to a different default by calling set_default_value
.
Another way of dealing with a non-existing entry / default value is by calling get_entry
. You can think of it much like the dictionary get
call. Continuing on with the example, above, this is how you can get an entry with a specific default value:
When using the function calls, it would be written:
Debating Deprecating User Settings Function Interface.....
Now that there's a "simpler" interface, I'm debating deprecating the User Settings functions. It's a really new set of APIs and I thought the chances are small anyone is using them yet.... but, surprise surprise, there is already code posted on GitHub by at least one user that's using the functions. You folks move quickly!
As long as I can properly document both, and they're not getting confused by users, then I guess it's not a big deal to have both. You can mix and match using both of them to manipulate the same settings file. By not specifying a filename or a path, both the function calls and the object will map to the exact same json file. As a result, they both will update the file and can safely be used at the same time.
I'm kinda in new territory here as I don't think any of the other PySimpleGUI API calls have made this kind of transition before.
PySimpleGUI 2020-11-13T17:00:59Z
4.31.0 PySimpleGUI 13-Nov-2020
User Settings class, write_event_value fixes, Menus get colors, Mac no_titlebar patch
-
InputText element - Now treating None as '' for default
-
Combo - handling update calls with both disabled and readonly set
-
Spin - readonly
-
Added parameter added when creating
-
Added parameter to update
-
-
Spin.get() now returns value rather than string version of value
-
Multiline print now autoscrolls by default
-
FileSaveAs and SaveAs now has default_extension parameter like the popup_get_file has
-
Button Menu - Color and font changes
-
New create parameters - background color, text color, disabled text color, item font
-
Fixed problem with button always being flat
-
-
Menu (Menubar) - Color changes
-
New create paramters - text color, disabled text color.
-
Hooked up background color parameter that was already there but not functional
-
-
write_event_value - fixed race conditions
- Window.read() and read_all_windows() now checks the thread queue for events before starting tkinter's mainloop in case events are queued
-
Window.set_cursor added so that window's cursor can be set just like can be set for individual elements
-
Icon is now set when no_window option used on popup_get_file or popup_get_folder
-
Reformatted the theme definitions to save a LOT of lines of code
-
UserSettings class
-
Added a class interface for User Settings
-
Can still use the function interface if desired
-
One advantage of class is that [ ] can be used to get and set entries
-
Looks and acts much like a "persistent global dictionary"
-
The User Settings function interfaces now use the class
-
-
main_get_debug_data()
-
Function added that will display a popup and add to the clipboard data needed for GitHub Issues
-
Added button to Test Harness to display the popup with version data
-
-
Mac - Added parm enable_mac_notitlebar_patch to set_options to enable apply a "patch" if the Window has no_titlebar set.
PySimpleGUI 2020-11-13T17:27:51Z
Qt is still the highest priority...
Even though 4.31.0 got out the door and posted to PyPI today, PySimpleGUIQt remains the top priority.
I have been struggling with getting the padding to work correctly for Frames which ate up several days.
Why 4.31.0 went out now.
A problem with write_event_values was found that was serious enough to warrant an immediate release. Losing events is not an acceptable bug to linger on posting the solution for. So, out the door it went.
Testing Windows, Linux and the Pi, but not the Mac
It's been tested on Windows, Linux, and the Raspberry Pi. I was unable to get the Mac patch tested so code was added to enable the patch should a Mac user wish to give it a try. Mac owners have an opportunity to help other Mac owners with this fix for no-titlebar windows.
New features
There were quite a number of new features that ended up in this release as well. The biggest were the Menu styling and the new UserSettings class interface. You can use both the previously released function calls to work with User Settings and the UserSettings
class. There was additional documentation added that describes the class interface and it's in the call reference of course too. One additional Demo Program was created that demonstrates using the UserSettings
class that duplicates a previous demo that uses the function interface so that you can easily compare the two.
Help with filing Issues
There's now a single button you can click and a function you can call from your code that will give you text that you can easily paste into any Issues you may file.
main_get_debug_data()
will display a popup message, place the text onto the clipboard and also return the text as a string. It's really easy now to collect the version information needed when posting issues. If you run the PySimpleGUI Test Harness (call sg.main()), and click this button:
Then you will see this window. The text in the window is automatically copied to the clipboard. HOWEVER, you must leave the window open until you paste the contents of the clipboard. Tkinter has a weird clipboard behavior in that it clears the clipboard when you close the window.
Here is the text that resulted from pasting after opening the window.
Python version: 3.6.2 |Anaconda, Inc.| (default, Sep 19 2017, 08:03:39) [MSC v.1900 64 bit (AMD64)]
port: tkinter
tkinter version: 8.6.6
PySimpleGUI version: 4.31.0
PySimpleGUI filename: C:/Python/PycharmProjects/PSG/PySimpleGUI.py
PySimpleGUI 2020-11-13T21:42:04Z
Reddit Searcher Program Updated
The PySimpleGUI Reddit Search program has been updated. You'll find the repo here:
https://github.com/PySimpleGUI/PySimpleGUI-Reddit-Searcher
It was changed to use the User Settings to store the Reddit credentials. The same settings file is used to store the history of your search terms. This will allow you to select them from a list instead of typing them in every time.
PySimpleGUI 2020-11-14T23:58:29Z
Menu Colors
Release 4.31.0 included a nice upgrade for Menu colors and text. What I didn't realize happened was that it picked up the colors from the theme. I would have chosen slightly different colors had I known that it was going to go that.
The color choices I recommend are using the colors for the Input element background and Input element text. At the moment, it is using the background color and text color for the text element. That means your menu will match the window and there won't be much contrast as a result.
Here's what the current window looks like with the "Python" theme:
Changing the colors to be the ones I'm suggesting can be done using an element defintion like this:
sg.Menu(menu_def, tearoff=True, background_color=sg.theme_input_background_color(), text_color=sg.theme_input_text_color())
Here is the window that code produces:
As you can see, the menu's colors don't blend in with the background and still match the overall window colors.
I'll open an Issue to deal with this and will either change the colors to be the Input background and text colors, or set it so that no colors are used and the generic gray color will be used like they were prior to the release.
This is what the colors were prior to the release:
PySimpleGUI 2020-11-17T18:50:14Z
4.32.0 PySimpleGUI 17-Nov-2020
Menu colors and font, fixes
-
Menu, ButtonMenu, and right-click menu now default to theme colors and Window font
-
The background color for menus is the InputText background color
-
The text color for menus is the InputText text color
-
The font defaults to the Window font
-
These theme colors have worked well in the past as they are the settings used for Table and Tree headers
-
All settings can be changed
-
-
Added ability to set the right-click menu colors and font
- New parameters added to Window to control right click look
-
Fixed problem with Button.update.
- Was crashing if button color changed to COLOR_SYSTEM_DEFAULT
-
Fixed problem with right-click menus introduced in the previous release
-
Auto-close windows can now be finalized (previously could not do this)
-
Window.read with timeout is faster
PySimpleGUI 2020-11-17T20:07:05Z
4.32.1 PySimpleGUI 17-Nov-2020
Sorry about the last minute bug-fix.
PySimpleGUI 2020-11-21T00:12:10Z
Bad news for Window.write_event_value()
I got caught by tkinter.
This is horrible news. The one call that I thought could bypass the tkinter-police is sometimes failing.
The specific setup that's causing the failure at the moment involves using one_line_progress_meter. My guess is that opening a new window is what triggered tkinter to do a runtime check and it caught me calling the write_event_value
function from a thread.
I suppose the broad warning would be to not open new windows when using the write_event_value
call. Hmmmm.... maybe the tkinter team could do something about this in an official kind of way??
PySimpleGUI 2020-11-22T21:15:39Z
PyInstaller Working Fine....
I had a scare for a bit where PyInstaller had trouble. It was a problem with installing PyInstaller on Python 3.6 more than anything else. I was able to build using other versions of Python. Once the 3.6 install problem was solved, pyinstaller ran beautifully. The ExeMaker demo has been cranking out EXE's with no problems.
It was important to get it running smoothly again. The combination of PySimpleGUI and pyinstaller are the simplest way of making a "Windows Program" that I know of, in any language. 1 line of Python code for a complete, working windows application is doing pretty good.
PySimpleGUI 2020-11-23T15:07:27Z
Gauge Demos
There are 2 new demos added this morning based on work done by @jason990420 a year or more ago. At that time I made a request for someone to create a meter / gauge for PySimpleGUI by utilizing the Graph element. Jason wrote a nice little demo back then, but I didn't take it very far. It was stored away for later use I suppose.
Now seems like a fine time to release it. I hacked on the code a bit over the weekend so that one class Gauge
is used. The demos that were released were a couple more "Rainmeter-style Desktop Widgets". There was already a couple of them to show CPU and RAM used. The design for them was a simple square that is shaded to indicate the current value. Seemed like a great place for one of these Gauges.
Here's the one that shows CPU time used:
And here are 4 widgets. The two on the top are the ones that were released already. The gauges are clearly on the bottom.
The class made it really easy to drop these anywhere in a layout. For example, I made a grid of these gauges to show CPU usage for all of the processor cores. If the window is refreshed every couple of seconds then you get a readable graph.
But if the refresh time is set too quickly, then they become not as useful. For highly volatile signals, gauges don't work so well. This shot shows the existing bar-graph CPU Core Desktop Widget and below it is a gauge version of the same data. I set the gauges to have a fast refresh which is kinda crazy looking.
Note that each needle changes to red when the usage of that core goes above 50%.
This is a higher-end example of a "user-defined element". There are a number of mini-bar graphs and other user-defined elements, but nothing quite as complex as these Gauges.
PySimpleGUI 2020-11-24T20:33:37Z
GitHub Demo Copier
Demo
I just realized how much I rely on this one little PySimpleGUI demo program. I use it constantly. It's a good example of a purpose-built utility. I can do the same kinds of operations with PyCharm, but they often require more effort in PyCharm.
Here's a screenshot.
Summary of what it does....
Enables searching for filenames or file contents in the left hand column. Within those items found, I can copy them to a GitHub release folder, run them or edit them in PyCharm. It's really handy for editing demo programs. I can type in the part of the name that I know and it'll bring up a list that I can then choose from.
For example, lately, I've been working on a bunch of "Gauge" demos. Typing "gauge" into the top search box searches the filenames for this word and then shows me the results.
I can then click on one and to edit it, click the "edit" button.
If I'm working on a particular feature and want to see what demos I have that can test that feature, then the searching within a file is used (like a grep). The second search box is used for searching within files. Let's say I'm working on the "read all windows" feature. The function is read_all_windows
. As I type "read_all_windows" into the search box, the results are brought up in realtime. Often when I'm searching like this I don't need to type the entire name.
Depending on your projects and number of files within those projects, then perhaps a little GUI utility like this to augment your IDE would be helpful to you too.
PySimpleGUI 2020-11-24T20:54:47Z
Today's Readme Update - Funding....
I really did not like adding this section to the readme, but felt it needed to be added. I have a choice of letting the run out of funds and die, or try to keep it going as long as possible by being more direct in asking for help. I opted for "be direct and ask for help".
Asking for sponsorship, donations, handouts, is not pleasant. It doesn't feel right. "Marketing" PySimpleGUI didn't feel right either, but I did it anyway, and the result was a friendly user community showed up and started using the software. Maybe it looks tacky or makes people feel uneasy, but I would like to see PySimpleGUI live on as long as possible before throwing in the towel. If writing a few paragraphs about funding is what it's going to require, then OK, I'll do it.
My apologies to everyone that's helped and done all that they can. I am truly grateful to everyone that's helped, in whatever capacity that's been. In case you missed it, here is what was added:
Funding - Your help is needed
A frank discussion is needed here. Subtle hasn't worked.
The financial part of Open Source development is not openly discussed often. As an Open Source developer, there is no automatic form of incoming happening, especially with Python where the source code essentially has to be provided. Creating and administrating a Commercial License is expensive. It's a big hurdle to take a project from an Open Source License to a Commercial License. The attorneys I've spoken with haven't heard of it happening successfully. So, licensing is not a practical option.
It's expensive to operate an active Open Source project. The labor involved is massive. How does it get paid for? Well, it comes from the developer is how. Just like YouTube creators have expenses for camera equipment and time making their content and need supporters in order to operate, so do Open Source developers.
PySimpleGUI needs your help. Without some kind of funding, this project will end, likely sooner than later. The individuals with the most ability to make a financial contribution are Corporate Users. It's not tremendously difficult nor does it pose a financial hardship on someone working for a company to make a donation to PySimpleGUI. You're spending someone else's money. If you get a paycheck from a corporation and you're using PySimpleGUI, you're a "corporate user". It doesn't matter if PySimpleGUI is shipping in a product you sell. Your company is benefitting by running PySimpleGUI. If it wasn't, you wouldn't be using it. The person at your company that can help the PySimpleGUI effort is you, the user. Your CFO isn't going to automatically make a payment. Your legal team isn't on the lookout for Open Source projects to help. I've not struck licensing deals with your company or any company. It's you, the end-user that is the person at your company that will need to take action and has the ability to help the project continue.
This PySimpleGUI software isn't the output from an AI bot. Nor is the support for users that are using it. There's a software developer (with help from some very kind, friendly, generous people) that's doing all this work. I do it because I love creating and enabling people to do cool things. But that love doesn't pay bills. The energy put into the project doesn't create electricity. I make stuff, electricity isn't one of them.
Patreon works well for YouTubers. It typically fails miserably for developers. But there are multiple mechanisms available including PayPal, GitHub sponsorship, and BuyMeACoffee. They all work pretty well and take 2 minutes if that. One thing it requires is action on the part of the PySimpleGUI user. If you can't afford to help, it's OK. Use the software for free. Make cool stuff. Make the world a better, easier to use place. If you can afford to help, please consider donating to the project. It's for a good cause.
To everyone that's helped, in whatever fashion, I'm very very grateful. And thanks to everyone that takes a moment to say "thank you", it's a small price to pay and adds to the project's momentum.
PySimpleGUI 2020-11-26T16:08:54Z
Thank you!
Thanks to all the great users of PySimpleGUI! One thing this project has attracted is grateful and polite users. So many times a bug report includes a "thank you". I get emails from thankful users, and every now and again someone will have something nice to say on Reddit. There's a pretty big thank you on there right now :-)
There's been a lot of positive energy with this project and that's made working hard easier to do. I really appreciate the positivity that has come along for the ride. If it wasn't "fun", it wouldn't have made it this far, and you guys and gals are a big part of what makes it fun.
Special thanks to @jason990420 who makes this project hummmm smoothly when people have problems or questions. He makes it possible for me to keep the progress going forward.
I hope everyone has a Happy Thanksgiving. It's a pretty upside down time right now, but there's also a lot to be thankful for and to appreciate.
PySimpleGUI 2020-11-26T18:25:08Z Of course, there needed to be a demo program to go with that "Thank you".
Replace line 48 in the desktop bouncing balls demo.
ball.gui_circle_figure = self.graph_elem.draw_text('Thank you!', (x, y), font='Default 20', color=random.choice(('#23a0a0', '#56d856', '#be45be', '#5681d8', '#d34545', '#BE7C29')), angle=random.randint(0,180))
PySimpleGUI 2020-11-26T19:01:12Z
Share Your PySimpleGUI Program
I've been meaning to open up the Wiki for some time and am finally getting around to doing it.
You can add your application to the Wiki by going here:
https://github.com/PySimpleGUI/PySimpleGUI/wiki
Edit the page and add your application information to the bottom. A template is provided for you to copy and use.
Screenshots are an important part of sharing your GUI. It's very easy to upload them to GitHub if you use a GitHub issue. All you have to do is drag and drop an image file into a GitHub Issue comment and the file will be uploaded. You can even paste an image from your clipboard into a GitHub issue. Once in an issue, you'll be given a link that you can use to embed the image into the Wiki page or into your Readme. There is a YouTube tutorial I made on how to do this.
PySimpleGUI 2020-11-27T22:27:53Z
PySimpleGUIQt - Frames
The new Frames code is on GitHub.
It's an odd step backward in some ways. Pad of (0,0) won't cause Frames to be touching. Hmmm.... I may make a special case if possible.
With it, you'll be able to control the padding around a Frame. Previously if you modified the padding, it would shift the text around. The change is needed as part of moving over to the new QtStyle code.
There is a problem with making the font too big as well. There is a surprising amount of tweaking pixel counts in Style Sheets.
Doing the best I can on it. After 3 weeks on this, I've gotta move on and just live with the settings for now. I'm afraid it's a "good enough" situation when I was shooting for perfect. Can't win them all, but it's better than a poke in the eye.
PySimpleGUI 2020-11-27T22:29:19Z
Frame Colors
We did pick up the ability to set the Frame color.
PySimpleGUI 2020-11-28T15:56:45Z
Still in Qt Hell
I thought maybe I would take a weekend off since it's a holiday weekend, but ended up spending most of last night and 6 hours this morning working on Window Margins and Comboboxes.
I've come to a terrible realization after much coding, testing, and researching. In order to get "padding" around elements, they each have to be placed inside of a "Groupbox". If not, trying to use the "margin" setting applies the padding in very odd ways because it tries to add it to all parts of a widget. It's the problem that I spent 3 weeks on for the Frame element. The same awful path was followed today, but with the Combobox instead of Frame.
The Qt Designer uses absolute sizes for things for the mostpart. It's a part of why it's not a big problem dealing with these Style Sheets when you're using the designer. It's because everything is hardcoded. People futz around with pixel values until it looks good and then they never touch it again. PySimpleGUIQt can't do that.
This is a much worse situation than I thought it was when I started on this a few weeks back. The more I learn about Qt Style Sheets, the worse it's getting. Qt doesn't provide the same kind of capabilities on your behalf as tkinter and WxPython does.
Qt Margins
Here's the lovely result from setting a margin of (40,40) on a Qt window.
Something tells me that pretty much no one wants their menubar to be shifted in 40 pixels from the top of their window (or from the left and right).
I'm setting the default margin = (0,0). If you wish to set it to a value to get the kind of results like above, then it's there for you to use.
Otherwise, to duplicate the effect that you'll get by using tkinter's margins, you'll need to use a Column element.
Padding into the future
And, speaking of Column elements. The news on "padding" is that every element is going to need to essentially need to be placed into a Column element. The "margins" setting on Widgets doesn't provide the kind of padding that we need for the way layouts are done with PySimpleGUI. When setting the margin for Qt widgets, it impacts all parts of the widget, not just the area around the widget.
This combobox is a great example:
Setting the margin for the Combobox affects the margin and placement of the down-arrow button. Notice how it's shifted over and cropped a little. Adding more padding to the element makes it unusable.
Schedule is a little unclear
I've got a problem with scheduling this work. It's going to be quite a bit more before I can get all of the elements placed inside of Columns, etc.
Udemy
The biggest conflict at the moment is a Udemy course.
As mentioned previously, funding has become a big issue. Funding is coming down to "training". Everyone is racing to make video courses in the Python world if you've not noticed. Authors, podcasters, programmers, .... Anyone that wants to have some level of income/compensation has taken this approach.
While I've recorded 3 different series of video lessons for PySimpleGUI, the Udemy course I've been designing is significantly more than the sum of the other courses. It's a massive undertaking and it's one that needs to happen every quickly or the PySimpleGUI project is going to end in the next few weeks.
I'm short on time and ability to get everything done with this Qt port, support users, and write, record, and publish a Udemy course (with a couple hundred lessons and project programs). I've spent quite a bit of time working out the course on paper, enough to have a grasp of the scale.
Juggling things around
I need a few days to determine how to best get the priorities set so that both the Qt work can get done and the Udemy course done in the next few weeks. It may simply not be possible as I'm running out of runway much faster than expected and the plane that needs to take off is overloaded considerably.
I'll try to get this Qt release posted to GitHub today assuming I can get this Combobox working right.
Thank you for your patience.
PySimpleGUI 2020-11-29T22:34:31Z
PySimpleGUIQt 0.35.0.19
Posted the version with Window margins, combox box style sheets and a fix to the draw_circle function. Would be great to start getting some runtime if there are any Qt users that want to give things a whirl.
PySimpleGUI 2020-12-01T16:48:21Z
Taking a Project Break....
I need some time away from the project. Rather than giving only partial attention and doing a 1/2-assed job as a result, I'm unplugging entirely and not providing support for PySimpleGUI on GitHub, nor elsewhere. I hope to return in a few weeks with perhaps some solutions to the project's problems.
In the meantime, do what you can to help yourself and each other using the materials at hand. @jason990420 may be able to help as he's been providing incredible PySimpleGUI support... he's over the top good at it. But, he's got no obligation to continue to be so generous.
Wishing everyone a happy and safe holiday.
PySimpleGUI 2021-01-02T21:46:05Z
Hello 2021! Release 4.33.0
4.33.0 PySimpleGUI 2-Jan-2021
Custom Titlebars, Fix for Docstrings so PyCharm 2020 works correctly, New shortcuts, Window Close Attempted
-
Custom Titlebar - new element
-
Initial reason was Trinket, but great feature overall
-
Allows windows to be styled to match the colors of the window
-
Automatically uses theme for colors
-
Automatically used when running on Trinket
-
Can specify using them by using set_options, a Titlebar element, or parameters in Window creation
-
Documentation is coming soonish
-
Demo exists showing how to use (it's enough that you won't need a Cookbook / detailed docs to add it to your own program)
-
Changes include adding a 16x16 pixel version of the PySimpleGUI icon
-
popups - If custom titlebar is set using set_options (and is thus globally applied) then popups will use the custom titlebar
-
-
MASSIVE number of changes to docstrings so that PyCharm again works correctly. All Unions had to be changed to use "|" instead
-
Internal functions added to check what OS is being used rather than having os.platform checks all over thee place
-
Element.Visible removed. Element.visible property returns current visibility state for element
- This is a read-only property
-
Added dummy Element.update method so that PyCharm doesn't complain about a missing method
-
InputElement class changed to Input. Both will work as InputElement is now an alias
-
Fix in Spin.update. Was using an illegal state value of "enable" rather than "normal"
-
New Shortcuts for Elements
-
Sp = Spin
-
SBar = StatusBar
-
BM = ButtonMenu
-
Progress = ProgressBar
-
Im = Image
-
G = Graph
-
Fr = Frame
-
Sl = Slider
-
-
Button - Allow button color background to be specified as None. This will cause the theme's color to be auto chosen as background
-
Image.DrawArc - fill_color parameter added
-
Column - update now uses the expand information so that a column will re-pack correctly when made invisible to visible. Added fill parm to pack call
-
New Window parameters:
-
enable_close_attempted_event=False
-
titlebar_background_color=None
-
titlebar_text_color=None
-
titlebar_font=None
-
titlebar_icon=None
-
use_custom_titlebar=None
-
-
Removed "Faking Timeout" print because the state that triggered it can be reached using a normal auto-closing window
-
Can now intercept window close attempts when the user clicks X
-
If you don't want "X" to close the window, set enable_close_attempted_event to True when creating window
-
When enabled a WINDOW_CLOSE_ATTEMPTED_EVENT will be returned from read instead of WIN_CLOSED
-
Multiple aliases for the key: WINDOW_CLOSE_ATTEMPTED_EVENT, WIN_X_EVENT, WIN_CLOSE_ATTEMPTED_EVENT
-
-
New Window property - key_dict
- Returns the "All keys dictionary" which has keys and elements for all elements that have keys specified
-
pin helper function got 2 new paramters - expand_x=None, expand_y=None. Was needed for the Titlebar element
-
no_titlebar implementation changed on Linux. Not using "splash" and instead using "dock". Was needed to get the minimize/restore to work
-
New set_options parameters in support of custom Titlebar element
-
use_custom_titlebar=None
-
titlebar_background_color=None
-
titlebar_text_color=None
-
titlebar_font=None
-
titlebar_icon=None
-
-
get_globals removed - not required for normal PySimpleGUI. Was only used by patched packages which will need to fork PySimpleGUI for this feature.
-
popup - support for custom titlebar!
-
Changed from pathlib to os.path
PySimpleGUI 2021-01-03T00:20:48Z
Happy 2021 !
Big new release posted for 2021. Let's get things started with some good stuff. The new Titlebar element makes it possible to create windows that match from top to bottom. It was done for Trinket but works on all OS's. You will not see an icon on the taskbar until you minimize the window. I'll eventually simulate one.
I hope everyone had a safe and happy holiday, however you spent it.
I've been virtually away working exclusively on a new upcoming course. It takes a ton of time and a lot of focus which is why I'm still not back dealing with Issues. @jason990420 is the best there is. And for the few that I've seen because they're older, it looks like some user to user help is happening too....
I'll be back in a few weeks. Hopefully the release won't bomb and instead things will work better.
PyCharm 2020
A good number of the 573 changes were to docstrings. This should fix the problems that PyCharm 2020 was having. I almost made it work in 2020, but it's 2021 and so there's something to celebrate right off the bat. I switched to 2020.3 and it's been humming along well.
New docs
There are new docs based off the updated docstrings.
Demo Programs Gallery
https://pysimplegui.readthedocs.io/en/latest/screenshots_demos/
It's a work in progress. It's a basic set of screenshots for the Demo Programs. There is a second round of changes. The automated screenshots captured the "loading" screens, so some hand editing is happening.
One thing that would be really helpful is if they were categorized. It's the next documentation task that would make them even more useful.
See you soon!
Back soon....
PySimpleGUI 2021-01-04T15:30:00Z
Reminders & News
Sharing your creations
Now there's a more public and structures place to share your screenshots and repos.
The Wiki is available to all. I posted about it earlier, but some people may have not noticed.
https://github.com/PySimpleGUI/PySimpleGUI/wiki
Post a screenshot, a description, and maybe even a link to your repo.
The Other SimpleGUI solutions
A word of caution about using a patched version of PySimpleGUI. Some packages are changing how you access information in PySimpleGUI. Rather than using the existing interfaces, new ones that are offered that are pitched as being more Pythonic.
There is a lot of time spent thinking about the past, current and future architecture of PySimpleGUI. It's evolved over the years, but it's largely been highly backwards compatible and while I'm personally away not working on Issues, supporting users is a big part of the PySimpleGUI project.
Should you use a modified, patched, non-standard interface to PySimpleGUI, you can likely not go back to the original PySimpleGUI. You'll be tied to the patched package. You also will not be able to receive support here. It's difficult enough supporting the base PySimpleGUI users. Hacked versions of PySimpleGUI won't be supported.
I get why some people would want to use a modified version and if that's your thing, go for it. Well-informed users can make better choices is what I'm saying.
New Demo - Window Closed Attempted
One new feature of 4.33.0 is the "window close attempted' feature. Here's the code that you'll find in the demo programs section:
import PySimpleGUI as sg
"""
Demo_Close_Attempted_Event
Catches if a window close was tried by user (click "X") and confirms with a popup.
Requires PySimpleGUI 4.33.0 and later
Copyright 2021 PySimpleGUI Inc.
"""
layout = [[sg.Text('Close confirmation demo')],
[sg.Text('Try closing window with the "X"')],
[sg.Button('Go'), sg.Button('Exit')]]
window = sg.Window('Window Title', layout, enable_close_attempted_event=True)
while True:
event, values = window.read()
print(event, values)
if event == sg.WINDOW_CLOSE_ATTEMPTED_EVENT:
if sg.popup_yes_no('Do yuou really want to exit?') == 'Yes':
break
if event in (sg.WIN_CLOSED, 'Exit'):
break
window.close()
Happy 2021
I hope everyone is having an excellent year so far. So much to look forward to this year.
PySimpleGUI 2021-01-13T16:16:52Z
Issues and "The Form"
I've continued to be fortunate to have Jason's help handling 100% of the Issues while I focus 100% on the new PySimpleGUI course.
The few times I've accidentally seen the list of Issues, I can't help but notice the tag "Not enough info. Please fill out the Issue Form".
It is needed
If you are here, looking for support, you are encouraged to file an Issue. We want to help people. Honest.
You have to fill in the form though. You just do. You don't need to understand in your heart or head why or that it's a requirement or feel it's bull sh*t. If you go to Jetbrains and file a bug, you fill one out there too.
If the information provided by the form was not required and will result in you getting to a solution faster, it would not be there. I wouldn't be sending out these periodic messages. If it wasn't important, I wouldn't reply to Issues without the form asking that one be filled out, knowing it's probably going to trigger an unhappy response from the Issue's author.
Please.....
-
Please fill it out.
-
Fill it out, damnit.
-
It would be really helpful if you filled it out
-
You will help yourself if it's filled out
-
You will help others if you fill it out
Choose the message you need to hear, but fill in the form when filing an Issue.
Thank you
While you're reading, thank you to the many many many supportive and helpful people. This project seems to attract nice people. It's weird, but I like it. Most people do even seemingly useless requests. It's appreciated. It's appreciated when you supply information that makes it efficient and easier to troubleshoot and solve problems. Thank you for doing it.
I hope you find much success using PySimpleGUI and find the experience as enjoyable as it has been to create PySimpleGUI and help users be successful.
.
PySimpleGUI 2021-01-16T23:01:51Z
Restructure of Methods, Funcs, and the Call Reference
It's taken too long for me to get to this, but it's finally done. There were a lot of changes required, so changes of an error are higher, but the testing so far has been smooth sailing.
The PEP8 and non-PEP8 versions of functions and methods have been reversed for quite some time. What I mean by this is that the definition, the def
statement, previously had the non-PEP8 name and then later in the code an alias was created to make it PEP8 compliant.
Let's take popup
as an example. Until this change was made (posted today to GitHub), the definition for popup was
def Popup()
And an alias was created:
popup = Popup
The changes swapped those so that now the def is
def popup()
and the alias is
Popup = popup
Additionally, the call reference documentation has been changed so that all of the Non-PEP8 methods are moved to the end of the list of methods for each element. They were first previously.
Hopefully, this will lead to more use of the PEP8 versions!!
And, hopefully, nothing broke.
Head down mode
I'm still spending all of my time working on the Udemy course. It's going well, but it's a lot of stuff to cover and I'm no videographer. I think viewers will be quite happy with the course though. It's by far the best video series I've done on PySimpleGUI. I believe this is the 4th series so one would think by now I would have a handle on what to teach.
Thank you to the users, and as always, a HUGE thank you to @jason990420 . I hope everyone is kind and helpful to each other (and of course to Jason... please be nice.... I'm sure you all are, but gonna ask anyway).
Better and better
One thing that making the course is doing is forcing a number of these cleanup activities to happen, or it's at least making them be a higher priority so that new users have the best possible experience.
Maybe you're not aware, but there is a thriving community of PySimpleGUI users that regularly post on Twitter their accomplishments and articles they've written. It's also another place to get announcements, sometimes more frequently, especially recently.
2021
Really hoping everyone is experiencing a better 2021 than 2020. I know a good number of people have had a very rough time. Hoping & wishing a happier and healthier world this year....
PySimpleGUI 2021-01-17T22:24:13Z
Demo Program Browser
A new demo for 2021!
The same kind of functionality was already available in the GitHub Copier Demo Program. The new Demo_Demo_Programs_Browser is simplified compared to the copy demo.
With it, you can:
-
Filter list of files based on filename
-
Search through files for strings
-
Run one or more selected files
-
Edit one or more selected files
-
Choose the theme to use for the program
The settings are automatically saved in a settings file using the PySimpleGUI UserSettings APIs and remembered across runs.
Use
-
Download the DemoPrograms folder from this GitHub
-
Run Demo_Demo_Programs_Browser.py that is in the programs you downloaded
-
Click "Settings" button and fill in the information
-
Enjoy your new Demo Programs Superpower!
Settings
There are 3 items you can set/change:
-
The folder containing the demo programs
-
The program to run when the edit button is clicked
-
The theme to use for the program
Until you set the folder for the demo programs, the list of programs will be empty.
Filter
The top-most Input element with the label "Filter" next to it narrows down the list of files shown by searching for the input string in the demo program filename. The list is updated in realtime as you type each character. The more you type, the narrower the list will become.
This example shows filtering the files so that only those with "matplotlib" are shown.
Find
The second Input element with the label "Find" next to it searches through the demo files for the string you input. The case of the string is ignored. Both the string entered and the file contents are converted to lowercase. Just like the Filter input, the list of files is updated in realtime as you type. The more you type, the fewer files will be shown.
This example shows the list of files that have the string "read_all_" because I was looking for all demos that make the call to "read_all_windows"
Edit Me
The Edit Me button is a capability I've been adding to more and more programs, especially utilities I use and change on a frequent basis. It saves a lot of time as I don't have to locate the file on my hard disk, open it in an editor, etc. Click the button and I'm editing the file immediately in PyCharm (or whatever editor you choose in the settings)
Gallery Reminder
A "first draft" gallery of Demo Programs screenshots has been created and is part of the PySimpleGUI documentation. The
"Screenshots Demos" tab has them. More work is underway to make some GIFs from some and make more relevant shots of others (some require navigating an initial window). I'm also working on putting the demos into categories as another way to help navigate through them as there are over 250 of them now.
Really is a Great Utility
I use the "Demo_GitHub_File_Copier" version of this program every single day and have been since it was written last year. It's an important part of my development process and allows me to quickly determine which programs may be impacted by a change to PySimpleGUI, or which programs will help me exercise specific functions or elements.
PySimpleGUI 2021-01-18T18:28:57Z
4.34.0 Going out today....
I'm preparing the release for today. The fact that popup_scrolled crashes are unacceptable to have on PyPI and so it needs immediate addressing. That's a catastrophic failure and I'm sorry for putting out a crap release like that.
It's going to take some time to run through the platform tests. While there are few features, there have been well over 200 changes to the source. And the documentation has been reworked a bit. Overall, it's an excellent release to be making, so really glad to get it posted today.
Plenty of risks though as many changes were to nearly all methods and functions definitions. The Docstrings are getting better as is the documentation.
More later today!
PySimpleGUI 2021-01-18T19:57:48Z
4.34.0 PySimpleGUI 18-Jan-2021
Fix popup_scrolled, big swap of PEP8 valid names
-
Quick "Emergency" release since popup_scrolled crashes. BAD bad thing that has to be corrected ASAP
-
Changed all of the functions and methods so that the definition is PEP8 compliant and and alias is not compliant
-
Built-in SDK help
-
Added a "Summary mode"
-
Make window smaller to fit on more monitors
-
-
metadata
-
Changed into a class Property so that it shows up in the docs correctly
-
The Element, Window and SystemTray classes all got this same change
-
-
Added all elements to the docstring for window[key] style lookups to make PyCharm happier
-
Moved all PEP8 function aliases to a centralized spot at the end of the code
-
sdk_help alias of main_sdk_help
-
Several new demos including a demo browser
As the course continues the non-stop, daily march forward, more and more attention is paid to the documentation, the built-in SDK doc tools, docstrings, etc. More demos are on the way.
If PySimpleGUI 2021 had a theme it would be "cleanup". Expect more fixes, more docs, more demos that will help, and less new features.
PySimpleGUI 2021-01-30T15:40:22Z
A Poll
I've created a poll on Twitter. It would be SO helpful to know more about you... yes, you... the reader of this message.
You'll find it here:
https://twitter.com/PySimpleGUI/status/1355539259311202307
Still working hard on the course
I'm still hyper-focused on the new course. Apologies to everyone that I need to turn off everything else, including providing help and support to the users.
I know you're in more than capable hands as Jason has demonstrated he knows PySimpleGUI better than I do many times. He's also a nicer person when answering perhaps.
I don't see the issues being posted, but Jason will contact me if something really urgent comes up
2021 - The Year Getting Cleaner
Some things are being added or fixed due to the course. Trying very hard to resist the urge to add new features and instead work on polishing up what we have.
THANK YOU!
Not kidding when I say I feel fortunate. 🙏🏼 It's an honest statement and it's because of the users being SO nice. The messages you send, the politeness to each other, the patience, the inspiration you provide, it all gets noticed and it has a large impact on this project.
PySimpleGUI 2021-02-02T14:17:41Z
Awesome PySimpleGUI Apps
Seeing a post this morning by Jason in the screenshots section made me realize that his Repo has not been highlighted here...
https://github.com/jason990420/PySimpleGUI-Projects
The post I saw today was this viewer:
Jason was one of, if not the early developers of games that pushed the PySimpleGUI capabilities in ways I had never seen. His solitaire game, complete with card dealing animations, was mind-blowing to witness in 2019.
Jason's a fantastic advanced user to learn from. He does things beyond my capability and has provided us all with solutions to problems using workarounds.
Learning from everyone - beginners too
One reason I ask for screenshots in other Repos, and ask for screenshots on Twitter, even from, and especially from complete beginners is that there is something to learn from every PySimpleGUI program/programmer.
Beginners sometimes do things that "they don't know any better not to do them" which sometimes results in genius-level results.
A middle-school kid posted on Twitter about using enums for keys.
https://twitter.com/Glassesman10/status/1356226908606799872
Not saying this kid is a beginner as a programmer. Who knows how advanced he (she?... I think he) is. He's tried something I haven't. I try to keep the demos and samples as basic as possible so they work on 3.4 or 3.6+ and are understandable by a wide audience (or maybe I'm making up excuses why I got one-upped by a middle-shool student).
One reason for PySimpleGUI's architecture and way of doing things is the result of being inexperienced in GUIs and in Python. Being inexperienced I think means you've not yet had the creativity taken from you. Being shown an answer can cause you to miss other answers.
So... please keep sharing what you make... you inspire others.
PySimpleGUI 2021-02-02T14:24:50Z
Twitter Poll Results
It's a very small population sample of 20, but informative just the same.
https://twitter.com/PySimpleGUI/status/1355539259311202307
It's the verification of what I was hoping to see, a good mix of all categories of users.
"Broad appeal" is what I meant by this goal in the documentation:
PySimpleGUI 2021-02-02T16:53:35Z
New "Project Browser Searchedr Launcher" Demo
One rewarding and satisfying outcome of using PySimpleGUI has been the ability for me to add my own custom tools to my toolbelt. Maybe this is not a new / novel thing for many of you, but it has been for me and I like it!
Maybe I'm re-inventing the wheel with some of the tools, but I'm inventing the wheel that I like. I'm also learning more about PySimpleGUI and making things other people can use
The Demo Browser has become an important tool for me as it's allowed me to easily search through the demo programs to find which demos are using a particular element or function. I use it daily, many times a day.
You may already have tools that do these things. PyCharm can search folders, etc, but this new demo is more targeted and I find it easier to use than trying to do it all through PyCharm. PyCharm is integrated in a way because editing files in the file list can be opened with PyCharm (or the editor of your choosing) by clicking the "Edit" button.
Project Browser Flattens You Tree
As I expanded out from the PySimpleGUI Demos and started running some code in other user's Repos as well as other trees of code on my local machine, the files are stored in a tree of folders, not just a single "Demo Programs Folder"
To make it easier to see all of the files in the tree at once, the file list shows just the filenames with no tree structure nor paths. It's a simple list of files.
History of Previously Chosen Folders - A classy feature for your GUI
This is a concept that's been around for a while and you'll find a demo that shows you how to create one of these combo interfaces for your programs. Rather than your file/folder browser targetting an Input element, a combo box is targeted.
The User Settings APIs are used to store the history of folders and the last one chosen. Using these APIs significantly shortens the amount of code required versus using json calls yourself. You don't have to worry about loading or saving the file. You don't even need to worry about the json file location nor the name as PySimpleGUI will set a default for you.,
Because I'm switching around from one tree to another, a history of previously chosen folders is shown both in the settings window, where you choose the folder, and also on the main window. This allows you to quickly switch between projects.
No Console Window Shown
Because it's assumed you're launching GUI programs, the console window is not shown. Clicking Run will cause your program to run and show your PySimpleGUI program without that perky console to minimize.
Let's have a look....
Like the Demo Browser, you can set the theme for the Project Browser.
I chose 2 projects in this screen capture - Mike Discoll's PIL book and Jason's PySimpleGUI tools repo.
Repo #1
- New PIL Book
The Repo made by Mike Driscoll that have examples from his upcoming PIL book.
Here's the Kickstarter but it's ending in less than 1 day:
https://www.kickstarter.com/projects/driscollis/image-processing-with-python
You can buy the book here in the future:
https://leanpub.com/pillow
He is using PySimpleGUI for this book.... based on feedback from his book's backers! He switched from using WxPython to PySimpleGUI. I didn't pay him to do it, honest. Thank you to everyone that's been so supportive of both PySimpleGUI and Mike Driscoll's work.
He's also got a great Python blog
https://www.blog.pythonlibrary.org/
Repo #2
- Jason's PySimpleGUI-Projects Repo
This repo was mentioned in the announcement earlier today.
So much PySimpleGUI goodness in one place!
Now I can search his code easier.
https://github.com/jason990420/PySimpleGUI-Projects
PySimpleGUI 2021-02-06T16:24:46Z
New [Almost] All Elements Demo
The old "All Elements" demo was pretty stale.
A new demo was posted yesterday.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_All_Elements.py
Big thank you and a warm welcome to the new PySimpleGUI team member Tanay who worked with me on this one. I like his design. It's nice and compact and thus fits on more screens.
Sorry I'm out for so long
REALLY appreciate everyone's massive patience while I'm away working on the course.
I'm trying to fit a couple of items here and there into the code, but really have to stay out of the daily fray.
You're in fantastic hands with Jason (I'm so so sorry Jason that you're holding down the entire fort). Please be kind to him, as you all normally are so it's not like I need to actually say that.
BEST user community an Open Source project could ever want.
I'm trying to get back to working hard on your issues.
Thank you, supporters!
Your messages are read, with great eagerness. They're impactful.
If anyone is able to get a clone machine from Amazon, there are a number of people I would like to clone.
PySimpleGUI 2021-02-11T05:35:31Z
Release Coming Soon....
There has been a pile of changes building up, largely due to changes made while making the Udemy course. There have been 19 0.0.0.1 releases since the 4.34.0 release. It may be getting close to a release.
Calendar button on Multiwindow
There should nothing stopping users from implementing the functionality of the "Calendar / Date Chooser button". It's 1 line of code to do it yourself. I thought there was a demo for this specific work-around, but I guess not from what I saw recently posting about an update to the fix.
Try this
import PySimpleGUI as sg
def main():
layout1 = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Go'), sg.Button('Exit')] ]
layout2 = [ [sg.Text('My Window')],
[sg.Input(key='-IN-'), sg.Button('Cal')],
[sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window1 = sg.Window('Window Title', layout1, finalize=True)
window2 = sg.Window('Window Title', layout2, finalize=True, location=(window1.current_location()[0]-400, window1.current_location()[1]))
while True: # Event Loop
window, event, values = sg.read_all_windows()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Cal':
date = sg.popup_get_date()
window2['-IN-'].update('/'.join([str(d) for d in date]) if date else '')
window.close()
if __name__ == '__main__':
main()
Mac Support - HELP WANTED
Help wanted... MAC user that loves PySimpleGUI and the Mac.
There are too many variables running around at the moment to make sense of where htings are with the Mac.
It would be great for someone that's energetic, generous enough to want to help, and upbeat about doing some seemingly boring, but incredibly important work.
There are plenty of "XYZ" does work on Mac ____ Insert some noun like a mountain or an animal.
What's needed is someone that is willing to test, the same tests, on multiple version of Mac, with multiple versions of tkinter. There are too many variables to just toss around binary "works/doesn't". It like yea, works on what speicic combination of:
-
PySimpleGUI
-
Python
-
tkinter
-
Mac OS
-
?????
These are just the minimum known variables that need to be tracked and carefully compared.
There needs to be the kind of discipline that is used for the Windows and Liinux versions of PySimpleGUI.
It would be great to see a priority list of bugs that have these things figured out about them.
PySimpleGUI 2021-02-11T22:59:41Z
Updated Project File Searcher & Launcher
This program is a generalization of the Demo Programa Browser. Instead of browsing only for PySimpleGUI programs, with this "Project Browser" you can point it to any tree of python files and folders and it will search through them all.
There are 3 types of searches.
-
Filter - searches the name of the file
-
Find - searches inside each file for the match. The list is updated for every character you type. Case is ignored.
-
Find RE - searches inside each file using a regular expression. Type in the string and click the "Find RE" button
In the GIF above, you'll see that I'm using it to navigate the programs that are in the Repo that accompanies Mike Driscoll's new PIL book. Searched for the PySimpleGUI import and then simply highlighted the program and clicked "Run"
https://github.com/driscollis/image_processing_with_python
You can pre-order it here:
https://leanpub.com/pillow
Features & Techniques You'll Learn
It's a demo program because it's meant to teach you. What this program teaches is adding these features to your programs:
-
Settings window
-
Theme selection
-
"History" of files or folders selected
-
Color printing with cprint
-
Using an "Edit Me" button to make program development easier. Click the button and your program is opened in your favorite editor
-
Global settings (not yet released to PyPI but works if using the GitHub version)
-
Launching another Python program
-
Launching your IDE / Editor to edit selected files
QA Test Case Execution?
In addition to single file search and edit, you can also work with groups of files. You can select 1, some or all of the programs in the list. If the scripts were individual test cases then you could highlight all of them you want to run and click run. They will all be started.
PySimpleGUI 2021-02-12T16:38:56Z
The Issues Form
I now realize that newcomers arrive and haven't seen the previous announcements about filling in the form.
If your issue has been tagged with:
Then it means you've not filled in the form.
The instructions are pinned at the top of the "Issues page", where you are clicking "New Issue"
Here is the link to it:
https://github.com/PySimpleGUI/PySimpleGUI/issues/1646
The "How to fill in an issue " was written a long time ago.
I've just updated it with info that will help you get the stuff needed for the form.
The easy way to get the version numbers is to call
sg.main_get_debug_data()
You will get this window. Do what it says.
NOTE - you do not need to highlight and copy the info in the window. It's already on the clipboard after you open the window. Just paste into the issue form, then close the window.
ALSO - these instructions are for the later versions of the tkinter port.
Generally speaking sg.main() is where you can get info about your release like the version, the GUI framework version, etc.
Your help is greatly appreciated
The form can feel like a pain, a nuisance, maybe it's frustrating for you. It's not there to upset you, it's there to get your problem solved as quickly as possible.
If you open an Issue for PyCharm or pretty much any piece of software, you'll find similar forms.
Thank you to all PySimpleGUI users. The majority of folks fill in the form and it's appreciated (for real, it is).
And thank you for the "Thank You"'s that many of you put into Issue. It's nice to get something that says PySimpleGUI is helping you in addition to the problem or suggestion you're reporting.
🙏🏼
PySimpleGUI 2021-02-14T00:09:21Z
More Features Due to Course.....
As the course is being recorded, there are places where it's clear some things haven't been exposed that could be or that some of the elements could benefit from an additional parameter. These changes aren't massive, but there are a fair number of them.
We're up to 4.34.0.21, which makes me quite nervous to have this much piled up. So, there may be a PyPI release shortly to let some of these things out into the wild and into users' hands.
An easy example is the color of the checkbox and radio button box and circle. They are computed values by default and there's no way currently to change them. It's one of those "not possible for the user to do" situations which bumps up the priority a tad. So, you'll find a new parm for both Checkbox and Radio elements.
Cleanup
It's also a bit of a cleanup period. The Demo Programs are not fully compliant with the coding conventions. There have been many passes through them in the past. It's time for another pass which is underway now. Key names are a good example of an inconsistency with the guidelines.
One of the reasons for some of the features you see in the latest "Project Finder" demo is Regular Expression searching. This was added to make finding these inconsistent keys easier.
Thankfully I've got some help on the new demos and the cleanup effort so they are happening in parallel with the course.
Thank you... as has always been... you're a great community of users....
Thank you everyone for being such a great community of users! If you have a program to share, Tweet a screenshot, and add it to the WIKI. Of course, Issue #10 is always a good place too. I appreciate the help that you're giving to Jason to make his life a little easier to support everyone.
You've been telling your friends.... the number of installs nearly doubled this past month.... and some users were vocal on Mike Driscoll's PIL book Kickstarter page to the point that he switched to using PySimpleGUI for his book. Awesome group you folks all are! It is so very appreciated. Not a day goes by that I'm not thankful. 🙏🏼
PySimpleGUI 2021-02-15T04:32:03Z
Demo - Change your window's theme
While the design pattern on how to change your window theme has been presented a number of times in demo programs, there isn't a super-simplified demo that shows only code to choose a theme and switch to it.
I'm happy to say that this is no longer the case. A new demo was added that focuses solely on changing the theme - Demo_Theme_Change_Your_Windows_Theme.py. You'll find it here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Theme_Change_Your_Windows_Theme.py
Here's the entire program:
import PySimpleGUI as sg
"""
Demo - Changing your window's theme at runtime
* Create your window using a "window create function"
* When your window's theme changes, close the window, call the "window create function"
Copyright 2021 PySimpleGUI
"""
# ------------------- Create the window -------------------
def make_window(theme=None):
if theme:
sg.theme(theme)
# ----- Layout & Window Create -----
layout = [[sg.T('This is your layout')],
[sg.Button('Ok'), sg.Button('Change Theme'), sg.Button('Exit')]]
return sg.Window('Pattern for changing theme', layout)
# ------------------- Main Program and Event Loop -------------------
def main():
window = make_window()
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED or event == 'Exit':
break
if event == 'Change Theme': # Theme button clicked, so get new theme and restart window
event, values = sg.Window('Choose Theme',
[[sg.Combo(sg.theme_list(), readonly=True, k='-THEME LIST-'), sg.OK(), sg.Cancel()]]
).read(close=True)
if event == 'OK':
# ---- Switch to your new theme! ---- ** MOST IMPORTANT PART OF THE PROGRAM **
window.close()
window = make_window(values['-THEME LIST-'])
window.close()
if __name__ == '__main__':
main()
PySimpleGUI 2021-02-16T22:41:20Z
Progress Despite Visible Evidence
It may appear that the project has slowed way down if looking at the features being added or bugs being fixed. 90% of my time is spent writing and recording the lessons for the new course. The remainder is fixing problems or coordinating software contractors. Your patience and support have been awesome over the past weeks as they've stretched into months. There are 29 elements in PySimpleGUI, with multiple ports, and a number of different types of APIs (user settings, themes, popups, ...). It'll be worth it in the long run for sure.
There is some cleanup that's happening along the way as well. Checkboxes and Radio buttons had new parameters added, for example, to provide more control over the colors.
Doing my best to get the writing and recording complete ASAP while also keeping things moving forward with the added help.
PySimpleGUI 2021-02-19T19:35:47Z
A Brilliant Solution for Progress Bars!
I renamed a variable and changed the key name. Other than that, it's a 100% @jason990420, our hero GitHub Issues help, code!
It's stunning it how GREAT it looks and it only takes a single Text
element. There's beauty in this kind of simplicity.
import PySimpleGUI as sg
sg.theme('DarkBlue')
layout = [[sg.Text('', size=(50, 1), relief='sunken', font=('Courier', 11),
text_color='yellow', background_color='black',key='-TEXT-')]]
window = sg.Window('Title', layout, finalize=True)
text, counter = window['-TEXT-'], 0
while True:
event, values = window.read(timeout=100)
if event == sg.WINDOW_CLOSED:
break
counter = (counter + 1) % 51
text.update('█' * counter)
window.close()
Here's a version that uses the Text element's metadata to store the current value.
"""
Demo Program - Progress Meter using a Text Element
This program was written by @jason990420
This is a clever use of a Text Element to create the same look
and feel of a progress bar in PySimpleGUI using only a Text Element.
Copyright 2020 PySimpleGUI.org
"""
import PySimpleGUI as sg
sg.theme('DarkBlue')
layout = [[sg.Text('', size=(50, 1), relief='sunken', font=('Courier', 11),
text_color='yellow', background_color='black',key='-TEXT-', metadata=0)]]
window = sg.Window('Title', layout, finalize=True)
text = window['-TEXT-']
while True:
event, values = window.read(timeout=100)
if event == sg.WINDOW_CLOSED:
break
text.metadata = (text.metadata + 1) % 51
text.update('█' * text.metadata)
window.close()
PySimpleGUI 2021-02-20T13:36:26Z
Demos demos demos!
It's a good thing there are 2 Demo Programs that help you locate Demo Programs!
The second Demo Browser is being actively expanded and is called the "Demo Project File Searcher". Expect some nice updates coming in the next week or two.
The current count for plain PySimpleGUI demos (tkinter based) is 266 and that number is growing at quite a pace. The reason for the continued growth is 2-fold.
-
Demos often originate from tests I run when developing a feature or fixing a bug. A lot of PySimpleGUI programs end up being written.
-
It's clear these demos are very helpful to both users and to me as the PySimpleGUI developer.
Some of the demos are getting more specific. One added this morning was a demo for the one_line_progress_meter
. There is already one demo that shows using this call, but it's a powerful capability and deserved to be spotlighted on its own. Thus, a demo of its own.
Here's the entire demo.
"""
Demo one_line_progress_meter
Add 1 line of code, get a very nice graphical progress meter window
As a software engineer, it's frustrating to know that there is a better way that
are not being shown. Adding a progress meter to your loop does not require 2 lines
of code. It can be done with 1.
So many of the popular progress meter packages require multiple changes to your code.
There are 2 varieties:
* Add 2 lines of code
1. Add - A setup outside your loop
2. Add - A call to a meter update function inside your loop
* Modify 1, add 1
1. Modify - Your existing for statement to use an iterator made by the meter API
2. Add - A call to the meter update function inside your loop
The PySimpleGUI "One Line Progress Meter" requires you to:
* Add - A call to the meter update function inside your loop
Copyright 2021 PySimpleGUI.org
"""
import PySimpleGUI as sg
import time
# --------------------------------- BEFORE ---------------------------------
# Your EXISTING code may look like this
MAX=100 # the max number of items you'll process
for i in range(MAX):
# Do your processing stuff here (simulated with this sleep)
time.sleep(.1)
print(f'Your old code simply looped through {i}')
# --------------------------------- AFTER ---------------------------------
# Now let's add a PySimpleGUI one line progress meter
MAX=100 # the max number of items you'll process
for i in range(MAX):
# Here is your line of code
sg.one_line_progress_meter('Some test', i+1, MAX)
time.sleep(.1)
print(f'Your new code still simply loops through, but you also get the nifty progress window {i}')
sg.popup('Done', 'As you can see, the bar auto disappeared', 'because it reached max value')
# --------------------------------- FANCY ---------------------------------
# What about that "Cancel" button? Let's hook it up
MAX=100 # the max number of items you'll process
for i in range(MAX):
# This time we're checking to see if the meter stopped. If it stopped early, then it was cancelled.
if not sg.one_line_progress_meter('A Meter You Can Cancel', i+1, MAX, 'KEY', 'Try Clicking Cancel Button') and i+1 != MAX:
sg.popup_auto_close('Cancelling your loop...')
break
time.sleep(.1)
print(f'Your new code still simply loops through, but you also get the nifty progress window {i}')
sg.popup('Done with your loop!', 'About to exit program')
The important parts are the 13 lines of code in the middle. Or, to boil it down further, these 6 lines:
MAX=100 # the max number of items you'll process
for i in range(MAX):
# Here is your line of code
sg.one_line_progress_meter('Some test', i+1, MAX)
time.sleep(.1)
print(f'Your new code still simply loops through, but you also get the nifty progress window {i}')
sg.popup('Done', 'As you can see, the bar auto disappeared', 'because it reached max value')
Here's what the demo looks like to run:
More changes due to recording the course
As every parameter of every element is explored, a few tweaks were really beneficial to complete so they're being added as the course is being recorded.
I expect a release to PyPI very very soon.
PySimpleGUI 2021-02-21T15:35:38Z
Cookbook update - Instructions for the Demo Browser and the Project Searcher
This morning this section was added to the Cookbook to help users get up and running on the Demo Browser, a tool that's becoming more and more important as the number of demos continues to grow rapidly.
Recipe - The Demo Browser
There are so many demo programs that a way of quickly searching them was needed. There are 2 programs for doing this. There is the "Demo Programs Browser" and a more generalized "Project Browser".
If you have not yet downloaded the Demo Programs, then follow these instructions to download the repo and demos:
-
Go to http://www.PySimpleGUI.com (the PySimpleGUI GitHub)
-
Download the repo as a ZIP file
- Unzip the downloaded zip and place the folder
DemoPrograms
somewere on your local disk drive that you have write access
To set up the Demo Browser:
-
Run the program
Demo_Demo_Programs_Browser.py
that is in the folder you unzipped -
Click the "Settings" button
-
Fill in the input fields labelled Path to Demos and Editor Program
-
Path to Demos - Defaults to the location of the Demo when you run it the first time. You can leave unchanged if this program is going to remain with the other demos. Use an absolute path.
-
Editor Program - If you want to be able to use the "Edit" button in this browser to open and edit the demo programs, then fill in the name of the .EXE (for windows) of your editor/IDE.
-
PyCharm
- Windows - it's not an EXE but a batch file. It will look something like this:
C:\Program Files\JetBrains\PyCharm Community Edition 2020.3\bin\pycharm.bat
* Linux - it's a bit trickier. It may resemble something like this:
/home/mike/.local/share/JetBrains/Toolbox/apps/PyCharm-C/ch-0/202.8194.15/bin/pycharm.sh
* Mac - I dunno yet.... there's an open Issue on GitHub asking for help from Mac user
-
Notepad++
- Windows - Something along the lines of
C:\Program Files\NotePad++\notepad++.exe
- Windows - Something along the lines of
-
Notepad
-
Windows -
c:\windows\notepad
-
Linux -
/usr/bin/notepad
-
-
Custom
- Assuming your editor is invoked using "editor filename" when you can use any editor you wish by filling in the "Editor Program" field with a path to the editor executable
-
The Project Browser - A More Generalized Solution
There is an extended version of the Demo Browser that allows you to search for filenames and inside of files for any directory tree of your choosing. The tree is flattened and you are shown a single list of files.
Look for the demo - Demo_Project_File_Searcher_Launcher.py
This screenshot shows that the theme used for these demos is entirely under your control. I've simply set the theme to "Dark Gray 13" in the settings window and this is the result.
"Open Folder" feature
It has the same settings window with an additional field: File Explorer Program
:
-
Windows - Defaults to
explorer
-
Linux - defaults to
nemo
This is the program you want to launch when the "Open Folder" button is clicked
Window Explanation
The Project File Searcher & Launcher (hmmmm... will change the name of this demo as it's too long) has a number of upgraded features. This diagram explains a few of the differences.
Settings Window
The settings window has a few changesfrom the basic Demo Browser. These include:
-
A history of previously chosen folders
-
A "File Explorer Program" that is needed if you want to use the "Open Folder" button
Verbose mode will show you the full matching line from the file. This is handy for when you're looking for a specific way something is used.
Features still under development
As you can see from the note in the window, there are a few features that are still being developed.
Currently:
-
When searching within the files, the case is ignored
- If using the Regular Expression search, then the case is not ignored. It must be a perfect match.
-
Verbose displays only the first line - will enable showing all lines in the file that match in the future
PySimpleGUI 2021-02-24T12:51:04Z
Dials! Expanded PySimpleGUI Elements and User Defined Elements Coming Soon!
Coming very soon..... PySimpleGUI Extensions and true "User Defined Elements".
The PySimpleGUI User Defined Element feature enables users to make functions that return elements. These functions can then be placed into layouts directly.
That capability is being expanded so that users can write their own elements that are subclassed from other elements. Still working on the architecture to make it easy and clear how to make these elements and hook them into PySimpleGUI. The new architecture uses a tighter integration with PySimpleGUI so that the values dictionary returns the custom element's value correctly.
@jason990420, our brilliant Issues wizard 🧙🏼♂️, has come through with another amazing piece of work.
He has duplicated the look and feel of Qt's Dial. The PySimpleGUIQt port has a Dial element that's unique to that port. Nothing like it exists in Tkinter.
Here's a little demo that shows them in action and how they match your theme.
PySimpleGUI 2021-03-02T12:54:01Z
Using Python 3.4 or 3.5 with PySimpleGUI?
If you're a Python 3.4 or 3.5 users I need your help.
Please see the newly posted Issue:
https://github.com/PySimpleGUI/PySimpleGUI/issues/3991
3.6 may be required soon
The reason for asking for your help and getting more information from users is that I'm working through whether or not to continue to support these older versions of Python.
3.6 for..... forever?
I don't see ever requiring users to run anything beyond 3.6, at least for the 4 ports that exist today.
However, because PySimpleGUI relies on other GUI frameworks, if one of these frameworks requires a later version of Ptyho, then you'll need to upgrade Python to that level.
I don't see the code in PySimpleGUI.py, the Demo Programs, or any other core component of PySimpleGUI ever needing more than what 3.6 provides.
PySimpleGUI 2021-03-03T21:18:12Z
4.35.0 PySimpleGUI 3-Mar-2021
Emojis, Global settings, Exec APIs
-
Emojis! Help has arrived!
-
Official PySimpleGUI emojis now usable for your applications
-
Used in the error messages
-
Has the PSG super-hero logo on his/her chest
-
1 PySimpleGUI Goal remains the same.... FUN!
-
EMOJI_BASE64_LIST is the list of all emojis. These are formed from the EMOJI_BASE64_SAD_LIST and EMOJI_BASE64_HAPPY_LIST
-
-
"Take me to error"
-
It's been close to 2 years in the making, but finally it's here.
-
Suppress error popups are
-
-
Mac loses Modal windows setting
- Another Mac feature turned off. The modal setting is now ignored for the Mac. Will turn back on if fixed in tkinter.
-
Built-in SDK Help
-
Expanded to cinlude init and update parms summary
-
Function search capability
-
Mode to filter out non-PEP8 compliant functions
-
Function search
-
Link to external live documentation at bottom
-
Sorted list now
-
Summary checkbox immediately updates window when changed
-
-
Global Settings & Global Settings Window
-
Can set defaults that all programs using PySimpleGUI package will use
-
sg.main() has a button "Global Settings"
- Directly access the settings window by calling sg.main_global_pysimplegui_settings()
-
Main settings include:
-
Default theme
-
Editor to use
-
Specification of how to launch your editor to editor a specific file at a specific line #
-
Python interpreter to use when calling
execute_py_file()
-
-
Theme (see themes section too)
-
-
User Settings
-
Option added to set the default user settings path
-
user_settings_path: default path for user_settings API calls. Expanded with os.path.expanduser so can contain ~ to represent user
-
pysimplegui_settings_path: default path for the global PySimpleGUI user_settings
-
pysimplegui_settings_filename: default filename for the global PySimpleGUI user_settings
-
-
The initial values can be found with constants: DEFAULT_USER_SETTINGS_
-
-
Buttons
-
Button color string more robust, less crashes due to bad user formatting
-
If a single color specified, then only the button background will be set/modified
-
"Disabled means ignore"
-
The parameter "disabled" is a tertiary now instead of bool
-
disabled True/False still works as it always has
-
If disabled parameter is set to the value BUTTON_DISABLED_MEANS_IGNORE, then the button will stop returning events
-
Enables you to create your own disabled button colors / behavior. Especially important with buttons with images
-
There is a new toggle button demo that shows how to use this feature
-
-
TRANSPARENT_BUTTON is being updated now when the theme changes. It's not recommended for use, but just in case, it's being updated.
-
files_delimiter parameter added to BrowseFiles
-
-
Themes
-
Spaces can now be used in the theme names
-
themes_global() - Gets and sets the theme globally
-
Easy and dangerous all in 1 call
-
Can also change this setting using the global settings window via sg.main() or main_global_pysimplegui_settings()
-
-
Swatch previewer copies colors onto clipboard correctly now
-
-
Exec APIs - A new set of APIs for executing subprocesses
-
execute_command_subprocess
-
execute_py_file
-
execute_editor
-
execute_file_explorer
-
execute_get_results
-
-
Debug button color fixed
-
popup_get_file
-
fixed files_delimiter not being passed correctly to button
-
files_delimiter parameter added
-
-
Column - auto expands entire ROW if y-expand is set to True
-
popups
- fixed problem when using custom buttons
-
Print - easy_print or Debug Print
-
Addition of color / c parameter
-
erase_all parameter added
-
100% use of Multiline element. Output Element no longer used for Print
-
Autorefreshes the multiline
-
Window.close needed to havera tkroot.update() added in order to close these windows
-
-
Graph
-
Update coordinate when user bound event happens
-
Update corrdinate when right click menu item elected
-
-
Checkbox
- Box color parameter added. Normally computed. Now directly accessable to users
-
Radio buttons
- Circle color paramter added. Like Checkbox, this is a computed value but is now accessable
-
Slider
- Trough color is now settable on a per-element basis
-
Input
- update method now includes ability to change the password character
-
Listbox
- update values converts items to list
-
OptionMenu
-
Does not set a default if none was specified
-
Use correct font and colors for the list
-
Added size parm to update
-
-
Combo
-
Ausizes 1 additional character wide to account for arrow
-
fixed update bug when default was previously specified
-
Added size parm to update
-
-
Element.set_cursor
- now has a color parameter to set the color of the BEAM for input and other elements like them
PySimpleGUI 2021-03-03T21:35:18Z
Hello from the new PySimpleGUI Helpers!
4.35.0 was a long time coming.... over 300 changes in this release including these fun emojis as well as changes that resulted from recording the Udemy course. Because the course covers every parameter of every element, it showed a number of places where things could be a little better, so I've been making changes as I'm recording.
There is still more to do so expect another batch of changes in the future.
There was also the addition this time around of APIs that help with the integrated error handling. In order to launch your IDE or editor, it required infrastructure that made sense to expose for users to use as well. They're also needed by the Demo Browser, a tool that's going to be used more and more over time as the number of demo programs has grown significantly.
Enjoy!
PySimpleGUI 2021-03-07T02:10:16Z
Toggle Button With 4.35.0
There's a new Button capability that makes creating a nice-looking disabled button easier now.
This Trinket will enable you to run the demo without installing anything:
https://pysimplegui.trinket.io/demo-programs#/buttons/toggle-buttons
The Demo program Button_Toggle2 can be found here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Button_Toggle2.py
Here it is in action.
PySimpleGUI 2021-03-08T13:39:31Z
"Edit Me" Button or Menu
The way I work on programs is a little bit at a time. If I see a problem with a program that's running, I can quickly open it in my editor / IDE to make a change when this "Edit Me" capability is there. Without it, I need to find the location of the .py file on my computer. This can be a long search involving 12 different folders and 100's of programs.
My recent task - add "Edit me" to my "Desktop Widgets"
Because 4.35.0 makes it really easy to add this feature, I've been adding it to all of my Desktop Widgets.
There are 2 locations to change in your file to add this capability
1. Adding the menu item
The easiest way to add this is to make a right-click menu for the window with an "Edit me" item.
This was my target last night. It didn't have any right-click menu. So, first was to add that. I added this parameter to my call toWindow
to create my window:
Once I added this line of code, my program now looks like this when I right-click it.
2. Add Opening the Editor to your Event Loop
The second place to change is the event loop. It is here that you will "handle" the click-click event.
Typically event loops have a series of "if" statements" checking the event. Add these 2 lines and you should be done.
The End Result
This is how it turned out after adding these 3 lines of code:
PySimpleGUI 2021-03-09T13:17:24Z
Demo Programs Browser Renamed on GitHub
Recent posts may have been confusing due to themes
To try out the "dark theme" trend, lately I've been running a theme that is different than that system default. As a result, sometimes my screenshots from this program may look different than yours. This is "Dark Gray 13" and you've likely seen some screenshots lately using this theme:
Other than the colors, It's exactly the same Demo Browser program.
Renaming the Demoi Program
The Demo Programs Browser is a critical tool to help you find the right demo programs) to help you. This program was named:
Demo_Demo_Programs_Browser.py
I count 255 Demo Programs in the folder on GitHub:
http://Demos.PySimpleGUI.org (https://github.com/PySimpleGUI/PySimpleGUI/tree/master/DemoPrograms)
Because the number got so large, a "Browser" program was written to help you navigate these. This browser is being very actively developed. There is an "Advanced Mode" that allows you to use the program not just with the Demo Programs, but with all of your projects, in any language. I use this tool all day long. It's what I use to help answer Issues you post.
Because the name of the program caused it to be listed part of the way from the top and thus is easy to miss, I have renamed the program today to be:
Browser_START_HERE_Demo_Programs_Browser.py
If you look at the Demo Programs page today, you'll see this:
Notice the very first file listed is the Demo Browser
Migrating your settings
If you previously set up the browser already, then you'll need to set it up again, or, you can "migrate the settings" to migrate, you rename the settings file.
Step 1 - Find the location of this settings file.
The location depends on the OS you run. These are the default paths for most PySimpleGUI settings files:
DEFAULT_USER_SETTINGS_WIN_PATH = r'~\AppData\Local\PySimpleGUI\settings'
DEFAULT_USER_SETTINGS_LINUX_PATH = r'~/.config/PySimpleGUI/settings'
DEFAULT_USER_SETTINGS_MAC_PATH =r'~/Library/Application Support/PySimpleGUI/settings'
Replace ~ with the appropriate starting folder for your user name. On my Windows system, with the user name Mike, the ~ is r3eplcated with `C:\Users\mike
. Thus my user settings are located at:
C:\Users\mike\AppData\Local\PySimpleGUI\settings
Step 2 - Find the old settings file
The filename itself is called:
Demo_Demo_Programs_Browser.json
Step 3 - Rename the settings file
You will need to rename this file to:
Browser_START_HERE_Demo_Programs_Browser.json
Step 4 - Test and enjoy!
You should now be able to run :
Browser_START_HERE_Demo_Programs_Browser.py
And it will have the old settings.
Demo Browser Program Relies on the Lastest 4.35.0 release from PyPI
The 4.35.0 release has a number of functions added to aid in launching your editor / IDE. It's also the frist version that you can specify your IDE with PySimpleGUI.
You can use the find and run features, but the edit features will cause the program to crash.
If you are running an older version of PySimpleGUI, then you will be warned when starting the new Browser.
The window resembles this:
Sorry about this rename and the inconvenience it may have caused
This change will help your other users find this program quicker and thus perhaps save them time, me time and thus you time.
Cookbook Recipe on Running this program
One of the first Recipes in the Cookbook is about using the Demo Browser (drat, now I have to go fix those docs).
Anyway, it's become a critical part of the PySimpleGUI toolbelt. It's another tool for you to become a super-hero in your department.
Expansion is almost complete
There is one final set of features being added now.
These all deal with the multiple finds in a file. When it is complete, choosing to "Edit" a file based on a verbose search that resulted in several matches, then it's desirable to choose which line to begin the editing on. There has been an additional step added that you'll notice. More on this feature coming soon when it's finally completed and released.
PySimpleGUI 2021-03-09T18:17:21Z
Thank you users... welcome new users.... and thank you to everyone helping out!
PySimpleGUI has been such a fun experience. One of the big reasons behind that has been the user community. You guys and gals are the best users a project could hope for. You're supportive, courteous, appreciative, positive attitudes, helpful, and so many other things that I could list. I'm thankful that many of you have been around for so long and helped the project.
I'm not sure how many of you watch or notice the GitHub trends. If you've not been paying attention to them over the past year, then you've likely not noticed that the PySimpleGUI Developer account on GitHub trends in the top Python projects, frequently. At times it trends at the top of all GitHub projects. It's because of you that this happens. It's also because of the amazing help I get from people like @jason990420 and @nngogol and @Chr0nicT.
Today PySimpleGUI is at # 3 for all developers on GitHub and # 1 for Python.
Here's the Trend today for all of GitHub
And for just Python projects
I'm looking forward to a bright future for this project. I hear from a number of people privately that PySimpleGUI has helped them and it's really touching to know it's had a positive impact.
It's not been easy to put in the hours required to create, document, and support this product, day after day, and now year after year, but it's been worth it.
PySimpleGUI 2021-03-10T00:43:19Z
Supporting PySimpleGUI Users
Support is one of the fundamental parts of PySimpleGUI. There are 4 components of the "PySimpleGUI System".
-
The PySimpleGUI package (the code)
-
The Documentation (main documentation, call reference, cookbook, readme)
-
Demo Programs
-
Support
Support for PySimpleGUI is provided through GitHub using the Issues feature.
Before getting into the details of GitHub issues, I want to reiterate the 2 primary goals of this project:
-
Having fun
-
Your success
I work on this project because it's enjoyable. I like to help people and I like to help other people be successful. Part of helping you be successful with your project is providing support. Sometimes there are bugs, or something's not clear, or you just don't understand and need help. It's all good... it's part of the process. Support is provided to help make you and others successful.
GitHub Issue Bot Cometh...
Automation.... what a great way to regain time and offload work to a computer for tasks that are routine.
Automation works well when there a process is that is well-defined. The PySimpleGUI GitHub Issues process is an ideal kind of thing to automate because the process is quite simple and easily defined.
As you read through this post pay attention to the green buttons as those as what you'll be clicking. Also pay attention to large, bold text as they have the simplified version of the actions those seeking help need to take.
Filiing a new issue summary
In case you're new to the project, here's a quick summary of how Issue posting for PySimpleGUI works.
-
Click the "New Issue" green button
-
Click the "Getting Started" green button
-
Read and fill in the form
-
Click Submit Issue
1. Click "New Issue"
Let's start with that green button. If you click on Issues at the top of this page, you'll see this:
There's a green button to file a "New Issue". Clicking that green button brings up another page with another green button.
Before we move forward with the "Get Started" button, take a moment and notice that there's a pinned issue at the top of the Issues list. This pinned Issue is clearly visible in the screenshot:
This Issue has the title:
In this Issue, you're provided instructions for how to obtain the information needed to fill in the form. It explains why this form exists, what it does for you, the reader, and me (and others) the support engineers.
2. Click "Getting Started"
OK, you've read the instructions on why the form is important. You've read where you can find the information you'll need to fill in the form. So let's click the green "Getting Started". When you do, you'll see this screen:
I think most people's eyes are likely drawn to the top of the page to the bold title with the *'s
3. Read and fill in the form
One of the nice things about the form is that it has a checklist. This checklist is meant to help you troubleshoot your problem. It tells you some things that you can try that perhaps you've not yet tried.
Let's take a look at that troubleshooting checklist:
That's not too bad of a list of things to check out and try. Sometimes it'll solve the problem for you by helping you find an issue that already shows this is a problem, or provides a workaround, or is a common error that users make and you simply need to make a change to your code.
The rest of the form are individual parts, straightforward, and pre-formatted. You don't need to learn how to format your code because that has been done for you in the form. All you need to do is paste in the code that you want to accompany the issue.
It literally says "Paste your code here"
4. Click "Submit new issue"
Once you've got everything entered, click the "Preview" tab at the top to see how your Issue will look once submitted.
If it all looks good, click that final green button "Submit new issue".
Why the bot?
Given everything you've endured getting to this part of this announcement...
with all this explaining about how to fill in the information, where to get the information, why the information is needed, some users instead of filling in the form do this:
-
Select all
-
Delete
-
Write what they want
-
Click "Submit new issue"
The result of that action is that the person that's been nice enough to spend their time answering GitHub Issues marks the Issue with a label:
And sometimes also leaves a comment asking the person to fill in the form.
This takes time. It takes patience. It takes letting go of the questions of "why do people do this??"
The bot is going to remove this step from the person supplying support.
The Closed Issues Comments
The bot will also politely inform people that are replying to a closed issue that they are requested to open a new Issue instead of replying to a closed issue.
PySimpleGUI 2021-03-13T15:51:03Z
Exec APIs Bug Fix
Pretty bad bug found in the new Exec APIs.
There is a bug in the launching of subprocesses in the 4.35.0 release. It's a serious problem that stops the demo browser from working correctly on versions 3.8-3.10a of Python.
More Documentation Coming on the Demo Browser
There's already a Recipe in the Cookbook that goes through the Demo Browser, but it already needs changing as the name of the program has changed and so has some of the Windows.
I'll be adding info on this program to the Readme so that it's introduced starting with the first visit to the PySimpleGUI GitHub by a user.
4.36.0 coming this weekend...
I want to get a new release, 4.36.0, posted to PyPI this weekend so that the Demo Browser works correctly on all versions of Python. Still need to do more testing, but seems like I've got a good fix for this one issue of doing the basic launch.
PySimpleGUI 2021-03-15T01:46:58Z
4.36.0 PySimpleGUI 14-Mar-2021
Happy Pi Day!
Exec APIs 1.1, some others fixes too
-
Exec APIs
-
Fixed the Popen problems found in 3.8+
-
Add quotes on all platforms now, not just Windows
-
-
Added checks for COLOR_SYSTEM_DEFAULT to a number of the element .update methods
-
Changed GreenTan theme to use black
-
Fix for button update when subsample used
-
Changed image update animation to start & stop at correct frame
-
Added return values for popup_animated
-
Themes - gray or grey can be used to select the gray themes. Spelling doesn't matter now
-
New scrollbar parm for Multiline Element - will use a Text Widget now if scrollbar is False
-
New Text element class methods for measuring size of characters
-
Debugger theme changed and red button removed
PySimpleGUI 2021-03-15T15:13:26Z
4.36.1 Coming today
Expect another release soon that deals with the Exec APIs again. This time more was needed to deal with pipping of stdout.
PySimpleGUI 2021-03-15T20:40:51Z
4.37.0 PySimpleGUI 15-Mar-2021
Happy "Pi with significant rounding error day"!
I'll eventually figure out this subprocess thing... honest...
-
Exec APIs
-
More control needed over routing of STDOUT
-
Additional parm added pipe_output to execute_command_subprocess
-
execute_get_results has a timeout parm now
-
execute_subprocess_still_running added to check if a subprocess is still running
-
-
Exposed the "running" functions so they can be used by Demos
-
Used internally to see if running on Windows, Linux, Mac, Trinket
-
Makes it one less import and the code already existed. All that needed to happen is the _ removed from the front of function name
-
PySimpleGUI 2021-03-16T13:09:04Z
Stepping away from Issues for a bit.....
Now that the PySimpleGUI releases are stablized a bit, I need to get back to the Udemy course.
There are 12 subprojects that are underway for the PySimpleGUI project, so it is not standing still while I'm away from the GitHub Issues. The Qt port, for example, is being reworked significantly and I hope to get another release out for it. The GitHub bot I've mentioned recently as well as PySimpleGUI+. You get the idea.
You're in the best hands possible with @jason990420 at the helm!
Thank you to everyone that's been so supportive over the past days, weeks, months, and years. I read every comment on Buy Me A Coffee and reply to them.
I'm on Twitter and see the posts made by PySimpleGUI users that are showing what they've created. Share with the world what you've made. People love seeing this stuff. Some share screenshots, others share tutorials and articles they've written.
🙏🏼
PySimpleGUI 2021-03-17T14:59:38Z
Cookbook updated - Demo Program Browser Instructions
The Demo Program Browser is the official "jumping off point" for using the Demo Programs to find answers. As a result, it's important that the instructions for its use be kept up to date.
The Cookbook felt like the right place for this information to live. So, that's where you'll find the instructions. Here is the "Recipe" that shows how to download and use this program.
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-the-demo-browser
Some samples parts of the Recipe
It covers downloading the Demos
Setting it up
Advanced Find With Editing
PySimpleGUI 2021-03-20T15:46:06Z
New Demo - Custom Menubar
If a custom Titlebar is used, then a normal Menu Element doesn't work correctly. Because it is supplied by the OS, it must be at the top of the window.
This demo gives you a "User Defined Element" that implements a Menubar element. Not only does it work in conjunction with a custom Titlebar, but you can also change the appearance of the Menubar, something you cannot do with a normal Menu Element (again because the OS provides this functionality)
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Menubar_Custom.py
Here it is in use...
The code for the Menubar itself is short:
sg.MENU_SHORTCUT_CHARACTER = '&'
def Menubar(menu_def, text_color, background_color, pad=(0, 0)):
"""
A User Defined element that simulates a Menu element by using ButtonMenu elements
:param menu_def: A standard PySimpleGUI menu definition
:type menu_def: List[List[Tuple[str, List[str]]]
:param text_color: color for the menubar's text
:type text_color:
:param background_color: color for the menubar's background
:type background_color:
:param pad: Amount of padding around each menu entry
:type pad:
:return: A column element that has a row of ButtonMenu buttons
:rtype: sg.Column
"""
row = []
for menu in menu_def:
text = menu[0]
if text.__contains__(sg.MENU_SHORTCUT_CHARACTER):
text = text.replace(sg.MENU_SHORTCUT_CHARACTER, '')
if text.startswith(sg.MENU_DISABLED_CHARACTER):
disabled = True
text = text[len(sg.MENU_DISABLED_CHARACTER):]
else:
disabled = False
row += [sg.ButtonMenu(text, menu, border_width=0, button_color=f'{text_color} on {background_color}',key=text, pad=pad, disabled=disabled)]
return sg.Column([row], background_color=background_color, pad=(0,0), expand_x=True)
Note that there's a new constant, sg.MENU_DISABLED_CHARACTER
that is not in previous versions of PySimpleGUI and isn't released to PyPI yet, so I've added this constant to the Demo itself. It's the ampersand that's used in menu definitions.
You can use the exact same menu definition you normally would with a Menu element with this new Menubar user element.
Because it's using themes to generate the colors, it will match the rest of your window.
Dark Green 7
Dark Purple 5
Enjoy!
PySimpleGUI 2021-03-21T01:10:54Z
Another Demo of Custom Menubar
There's a second Demo Program for the new Menubar User Defined Element. This demo shows you the traditional titlebar and menubar side-by-side with the custom title and menu bars. What was surprising about this demo is that it required only 1 change to the event loop. A single window read because a multi-window read and 2 more windows added. It was only 16 additional lines of code for the 2 other windows.
I think the thing that makes a demo like this one go smoothly is the simplicity. The more simple things are, the better they are working.
Themes are also an important part of the overall experience. These custom menubars use button colors, but they could use other theme colors and turn out just as great looking. Experiment and see what combinations you like.
PySimpleGUI 2021-03-21T01:14:39Z
THANK YOU SPONSORS!!!
I reply to everyone that leaves a comment on BuyMeACoffee and try to be openly thankful to everyone that's helping. The Sponsors on GitHub deserve a HUGE thank you too!! You're not being forgotten. I'm really appreciative of your help. You're making an impact. All of your help goes directly into PySimpleGUI and making it better. 100% of your help is applied directly with zero overhead. Thank you so very much for sponsoring the project! 🙏🏼
PySimpleGUI 2021-03-21T15:44:59Z
I post more information on Twitter in addition to here on GitHub. Some days it's a "Tip of the Day". Other times it's an announcement about PyPI releases. I started using it because of the large number of overseas PySimpleGUI users that are on Twitter. It's also quite easy to post GIFs there to demonstrate new features.
Of course, the Twitter account is: @PySimpleGUI
PySimpleGUI 2021-03-21T22:33:36Z
4.38.0 PySimpleGUI 21-Mar-2021
The "so much for no new releases for a while" release
-
Changed name of the NEW parm in Multiline element from scrollbar to no_scrollbar
-
This matches the other elements that also have this same parameter (Listbox)
-
Wanted to get this release posted prior to users writing code that uses it (it's only been 1 week)
-
This is the actual purpose for the release... so that it doesn't linger to the point it breaks being backwards compatible
-
-
Some additional debugger stuff... nothing to see here... keep moving.... will let you know when there's more
-
Added icon parameter to popup_scrolled
-
New Exec API call - execute_find_callers_filename
-
It basically looks backwards until PySimpleGUI isn't found
-
Hopefully will help in error messages to determine who is calling PySimpleGUI
-
-
Made a constant variable for the & char used by Menus in PySimpleGUI for shortcuts
- Also fixed a couple of places where they were being erroneously stripped from the normal menu text
-
Better error reporting for duplicatea keys
-
Found a problem with using print for errors - rerouted stdout/stderr can cause MORE errors
-
Interestingly, popups work great for these errors as they do not havea cascading error effect
-
PySimpleGUI 2021-03-22T17:12:53Z
New Rainmeter-Style Desktop Widget TEMPLATE
Really happy with the way this Demo Program turned out.
In under 100 lines of code you get a template that provides all of the features you would likely want/need in a desktop widget.
You'll find it here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Desktop_Widget_Template.py
Here's the Template in use
It has a solid feature set that I think you'll find can be used to create just about any Rainmeter style widget you would want. This one feels like a mature template to use. This feature list is in the comment at the top:
It has many of the features that a Rainmeter-style Desktop Widget would have
* Save position of window
* Set Alpha channel
* "Edit Me" which will launch your editor to edit the code
* Right click menu to access all setup
* Theme selection
* Preview of window using a different theme
* A command line parm to set the intial position of the window in case one hasn't been saved
* A status section of the window that can be hidden / restored (currently shows last refresh time)
* A title
* A main display area
I used the template to create this date widget:
It took under 5 minutes to write the Date Widget using the Template.
It has a full complement of right-click menu items
Enjoy!!
If you make something, please post a screenshot in your readme, and post one in Issue #10. It does not have to be a fancy program in order for others to be inspired and learn something from you.
PySimpleGUI 2021-03-23T15:13:16Z
Twitter Poll - What OS Do You Use with PySimpleGUI?
https://twitter.com/PySimpleGUI/status/1374369799300612096
PySimpleGUI 2021-03-30T13:35:06Z
The Window.write_event_value
problem
For a number of months the implementation of write_event_value
was working well.
But, it too started to exhibit the familiar problem of "not in the mainloop". I spent a large chunk of time on this over the past few days and I understand the problem better than ever.
I had one solution that looked like it completely solved the problem, but like any intermittent error, it eventually showed the same issue. I feel like I'm getting close to a solution.
In the meantime, the absolute safest thing for your application to use is a queue for your thread to talk to and an event loop with a timeout that checks this queue.
This demo shows the basic mechanism:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Multithreaded_popup.py
A queue object is created. The Thread calls the put
method for the queue.
The event loop is running with a window.read(timeout=500)
. Each time through the event loop, the queue is checked.
This type of polling operation certainly has a downside of latency and CPU usage, but it's the safest approach.
I hope to have some GREAT news on this soon. Thank you for your pateince!
PySimpleGUI 2021-03-31T16:10:43Z
NEW on GitHub (4.38.0.3)
Listbox Better Theming
The selection color has always defaulted to the blue that Tkinter provides.
As PySimpleGUI grows and evolves, these details fill in over time. My gosh how far things have come over 2.5 years!
July 2018, the first release has this:
2 1/2 years later we've got 4 ports, and now hot Listboxes!
The upper left corner is how the highlighting worked before today's changes.
The window below that one shows the new highlights with a standard titlebar. The other windows have Custom Titlebars. Very happy with these results! MUCH more appealing in my opinion. It doesn't push my "something looks off" button now.
The Dark Red one was an incorrectly chosen image. I was testing turning off this theming. Here is how it actually looks with the defaults.
Macs can use TK Buttons
There was a request for Macs to be allowed to use tk Buttons instead of being forced to ttk only. This was a fine request to make. I don't think I meant to be so exclusionary. I prefer to allow rather than dis-allow when possible. It may not work out well for you, but actively blowing you from trying is not the approach I want to take.
You will need to set the ttk indicator on each button that you want to be a tk button.
The parameter use_ttk_buttons
in the Button
element is how you will need to indicate it. Working at the Window level won't do it. It's got to be explicitly set on the Button.
Giive this code a try....
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Button('Go', use_ttk_buttons=False), sg.Button('Exit', use_ttk_buttons=False)] ]
window = sg.Window('Window Title', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
PySimpleGUI 2021-04-02T12:09:34Z
Heads-up on PIL + Python 3.6
Big distraction hit yesterday.
The function I've used everywhere for PIL connecting up with PySimpleGUI has a pretty big issue when running on 3.6 that I wasn't aware of until I hit yesterday. The Digital Picture Frame desktop widget was supposed to be a QUICK little personal project lasting an hour, tops, as a warm-up exercise for the day.
I had no idea the rabbit hole would end up doing down, and down. It's still not solved.
The effect is a rippling one where priories have gotten pushed down, like a stack.
I'm sorry about this, but it's the nature of software development.
One reason for it taking a top priority spot is that PySimpleGUI is used in Mike Driscoll's new book on PIL, and the last thing I want to see happen is for PySimpleGUI to cause that book any harm. So, it has jumped the normal priority queue and rose to the top quickly.
For what it's worth, it does not appear to be a PySimpleGUI problem itself, but it does heavily impact PySimpleGUI. The PIL function I've been using is portable across the PySimpleGUI ports, but it's the one now with a problem.
I'm sorry about the detour. Hope to be back on track very soon.
PySimpleGUI 2021-04-03T23:17:45Z
Update on Issue Bot and Issue GUI
The Issue checking bot is in the final stages of testing for deployment.
I'm reworking the form in the meantime as well.
Since the bot closes issues, I'm going to manually close them or Jason will if they lack the form. The incoming issues should be clean and not littered with posts that have 1/2 or less of the info needed.
I've been working on a GUI that will go directly into PySimpleGUI. This will remove the need for you to collect the versions, etc.
It looks like we'll be able to also not just generate the markdown, but also paste it into a new issue, paste in the title, and get everything ready for you to hit submit.
It stops short of submitting so that you can easily drop in screenshots. For those, it's a paste operation or a drag and drop.
Trying to get this done by the end of the weekend, but not sure if I'm going to get it all done by then. Trying....
PySimpleGUI 2021-04-04T02:42:37Z
Give Kindness
A friend sent this to me today and I think it's worth remembering. I've written it down and hung it next to my computer.
Life is an echo.
What you send out, comes back.
What you sow, you reap.
What you give, you get.
What you see in others, exists in you.
Remember, life is an echo.
It always gets back to you.
So give kindness...
PySimpleGUI 2021-04-05T02:26:26Z
Happy Easter-Egg
I hope everyone had a fun Easter with loved ones, friends, a pet, your houseplant, or PySimpleGUI... or wherever you find joy.
A new feature snuck into the code that's not documented in the docs yet and is available on GitHub.
Right-click menus can be made to be torn off by setting a flag when you create the Window. This screen capture shows the effect. It a very interesting capability that will be interesting to see how it's used.
PySimpleGUI 2021-04-06T11:29:09Z
The GitHub Issssue Poster GUI is Ready for Beta....
Last night I released a new Demo....
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Post_An_Issue.py
This code is going to be INSIDE of PySimpleGUI itself, but for now it's a demo so it can be easily tried out.
It will create the markdown form for you, fill it in, open up the webpage.
Try it!
I wanted to make the experience better for you, the user, prior to a bot release.
It's taken a lot over work over the past few days and I hope it's up to the standards that you've all come to expect.
Note that the theme is based on your current GLOBAL theme setting that you set in sg.main() which is why this screen capture shows a window that is Dark Gray 13 themed.
I want this Issue process to be nice for everyone. The idea is to provide you with the BEST support possible, in the most efficient manner.
PySimpleGUI 2021-04-06T14:42:37Z
Every Screenshot is Inspirational
The reason I say this, over and over, and Tweet it too, is that it's true. nothing is too small to see.
I hacked oni a little sample code I received. What FUN!
ALL CREDIT, 100%, goes to @neovich
It's too much fun to watch and not share this.....
PySimpleGUI 2021-04-09T01:37:26Z
Issues GUI
Please try the Demo_Post_An_Issue.py demo program when you need to log an issue next time. I don't yet have it in the PySimpleGUI code, but it will work the same except instead of running a demo, you'll call a function.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Post_An_Issue.py
Recent "Interesting Additions" in 4.38.0.9
Realtime Button
As the lessons keep moving... on Buttons.... some stuff is being changed along the way. I'm also trying to deal with some of the Issues, but it's difficult to balance things perfectly.
RealtimeButton
is a working feature again (yeah!). There's a new demo program that is replacing the quite dated Pi Robotics demo.
Basic Right-Click Menu Constant
You'll find that pretty much all of the newer Demo Programs have an Edit Me capability. You can get this really basic menu that has an "Edit Me" and an "Exit" entry by adding the constant with the right_click_menu
parameter to your Window creation:
window = sg.Window('Window Title', layout, finalize=True, right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_EXIT)
If you want to add the editing capability to your program, you'll need to set up the editor in the global settings via sg.main()
and then add this if statement to your event loop:
Right Click Menu Tearing Off
New Window parameter:
If True
, then your right click menus can be "torn off". They become little floating windows that you can use to control your program.
This feature addition is what made this feature possible/interesting.....
popup_menu
- a New Popup Function
This is a weird feature that was easy to drop in because of the internal PySimpleGUI menu data structure parsing/building functions. While adding the tearoff right click menu above, it was clear a more general purpose popup menu is possible.
You'll need to supply some parms like the window and an element within your window. They're needed by tkinter, but aren't going to restrict you in terms of the location. You can specify a location anywhere on the screen. The default location is the upper left corner of your window.
More Permissive Layouts
This is a bit of an experimental feature. It will allow you to have another level of layouts. It buys you nothing in terms of things ending up in different locations. But, it does provide for the appearance of User Defined Elements to be like a normal element. Your function can return a row, and with this code change, a row can have a row.
It has a downside in that you can make a mistake that was caught previously and now it'll instead emb3d the error rather than flagging it.
Updated Collapsible Sections Demo
The Collapsible Sections demo was updated.
This demo has a User Defined Element, but because it's only 1 element, a Column, it can be placed inside of [ ]. If this function instead returned a list of elements, then previously that would have had to be outside of [ ] like the "layout helper" functions are today.
Demo Browser New Features
Seeing how I live in this program much of the day, it gets improved upon.
Two features were recently added. The first is hotkeys on the main window. F1, F2, F3 will switch between searches.
You can also define what a double-click of the file list does using a setting in the settings window:
A double click can run or edit the program.
They save a little time, but do add up over time.
PySimpleGUI 2021-04-09T02:05:41Z
The s
Alias
I forgot to mention one of the more exciting and time-saving additions! Elements in 4.38.0.9 have an s
parameter that is an alias of the size
parameter. They work just like the k
parameter does for key
. You can use either. If you choose both for some weird reason, size
takes priority.
This will save keystrokes of course, and for those inline GUIs, it saves significant space. You can use the Element, key and size aliases to get the layout size quite small.
layout = [ [sg.T('My Window')],
[sg.I(s=(15,1), k='-IN-')],
[sg.T(s=(12,1), k='-OUT-')],
[sg.B('Go'), sg.B('Exit')]]
Produces this window:
PySimpleGUI 2021-04-09T16:01:38Z
PySimpleGUI and Macs
I've looked at stats for installs, taken polls on Twitter of users, searched the GitHub projects that use PySimpleGUI so that I can get an understanding of the size of the Mac community.
This decision I've been pondering, support or don't support the Mac on tkinter, is actually related in many ways to the decision of supporting back to Python 3.4. It's a pain in the ass to support 3.4/3.5. Not using f-strings in the core PySimpleGUI code is a pain in the ass.... but.... in the end... it's worth that pain in the ass. Besides, it's MY pain, not anyone else's.
When I learned that Python started blocking the installation of Python on Windows 7 machines, it felt distressing. This decision bars people from using an otherwise open/free piece of software. It's a personal opinion, so sorry about venturing into this space. The reason I'm mentioning it is that it's related.
The decision to support 3.4+ was made so that the PySimpleGUI tent would hold more people. PySimpleGUI should be a welcoming package, not one of exclusion.
So, for this reason, I'm going to keep right on supporting the Mac running tkinter. I don't want to exclude a group of people that have been with this project from the very first days.
The Early Days...
In fact, when I look waaayyyy back... before Windows where Windows and instead were FlexForms....
I recall the immense feeling of satisfaction, happiness, joy, when I saw user @sfneal posted his repo dirutility (I'm sorry to put you on the spot here Stephen)
This utility ran..... on a Mac.
We're in this together
I can't turn my back on this group of users regardless of the problems currently being experienced on the Mac. I also can't justify not supporting them because it a "smaller number of uses" than the other operating systems.
So, Mac users, we'll slog out the problems together. I'm not going to abandon you. I don't know exactly how I'm going to be able to get through all the weird ongoing problems, but we'll find a way.
PySimpleGUI 2021-04-09T18:50:54Z
write_event_value
update!
ooooo 8 8
8 8 8
8 8oPYo. .oPYo. odYo. 8 .o o o .oPYo. o o
8 8 8 .oooo8 8' `8 8oP' 8 8 8 8 8 8
8 8 8 8 8 8 8 8 `b. 8 8 8 8 8 8
8 8 8 `YooP8 8 8 8 `o. `YooP8 `YooP' `YooP'
::..::..:::..:.....:..::....::...:::....8 :.....::.....:
:::::::::::::::::::::::::::::::::::::ooP'.::::::::::::::
:::::::::::::::::::::::::::::::::::::...::::::::::::::::
8 .oPYo. .oPYo. .oPYo. .o 88 88
8 `8 8 .o8 `8 8 88 88
.oPYo8 .oPYo. .oPYo. ooYoYo. .oPYo. odYo. oP' 8 .P'8 oP' 8 88 88
8 8 .oooo8 8oooo8 8' 8 8 8 8 8' `8 .oP' 8.d' 8 .oP' 8 88 88
8 8 8 8 8. 8 8 8 8 8 8 8 8' 8o' 8 8' 8 `' `'
`YooP' `YooP8 `Yooo' 8 8 8 `YooP' 8 8 8ooooo `YooP' 8ooooo 8 88 88
:.....::.....::.....:..:..:..:.....:..::.........:.....:.......:..::......
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Wow I got a huge hand in getting this threading communications problem solved.
Best I can tell, the write_event_value
problem of tkinter complaining about not being in the mainthread is SOLVED
I've thrown as much as I can think of at it. I've started 100's of threads, each sending multiple messages, and it continues to work with no problems.
Elated that we're going to not have to worry about this problem sneaking up on us anymore.
It's working on 3.6, 3.7, 3.8, 3.9 on Windows and Linux. I have not yet tried it on my Pi but I can't imagine it not working.
Mac users, please give it a try if you've got a moment. You'll have to get PySimpleGUI from GitHub as it's not on PyPI yet. I plan on posting a release this weekend. The version with the fix is 4.8.0.11
FINALLY can breathe easy and focus back on getting through the Udemy recordings. This one has been weighing heavy for quite some time and has been a distraction for weeks, so I'm really thankful for the help! Great job of researching this problem snd finding the solution.
PySimpleGUI 2021-04-10T13:41:17Z
Thank you PySimpleGUI Users (again and again)
The PySimpleGUI Dream Come True
This is an entirely new experience for me. It's a dream come true that I didn't realize I had as a dream.
Seeing PySimpleGUI code, in print, in a real book, written by my favorite Python book author is joyful feeling that overflows the joy cup.
It was the PySimpleGUI users that made this happen
I did not request that PySimpleGUI be used in this book. I didn't even suggest it. The Kickstarter campaign was already underway with several chapters of the book and the accompanying code completed.
It was the community that suggested and encouraged the switch.
If you want a copy.....
No pressure... not pushing this on anyone, but if you like what you see and want to maybe pick up a copy and help support Mike as a Python book author, you can get a copy "Pillow: Image Processing with Python"
https://gumroad.com/a/296752243/LRAJQA
Bought through Kickstarter, and being a "Book person", I bought both an ebook and a hard copy. I can't comprehend when reading electronically. Searching and skimming reference material, OK, I can use a PDF for that. But "reading"... just doesn't work right with my brain without a paper book. I don't know why, it just works that way.
I have so many people to thank
Let me start with the obvious one. Mike Driscoll has been a fantastic new friend. The support, help, encouragement, and so much more, has made it clear to me that Mike is one of those "good people" that I don't question the intent of. A solid human being. It's priceless to have those in the world, and I want to help support making it possible for people like Mike to do what they love. In Mike's case, it's teaching people Python and writing books (MANY books). I've been a long-time fan, but only in the past year or so gotten to know Mike better and wow, what a great person to know is part of the Python community. Hope is a priceless thing and he brings hope for me to Python.
I'll forever be thanking the PySimpleGUI users because you're the reason I work on this project. 🙏 You're the fuel for the passion fire.
It's SO MUCH FUN sharing in someone else's success or happiness. It's a weird selfish thing to do, much like volunteering. There's something you get back in return that other people don't necessarily see or feel without having experienced it. When you're successful and share what you've made, I feel a little of that happiness you're feeling. That's why the goals are # 1 Fun # 2 Your success. Do that and we're all happy and successful. So far, so good!
PySimpleGUI 2021-04-11T15:19:12Z
Release coming today.... 4.39.0
LOTS of stuff piled up that are going to PyPI today. Verision on GitHub is 4.38.0.12 so over a dozen changes. One in particuilar, the "s" parameter, I'm looking forward to using, but has to be cross-ported to the new Qt port and the others too pretty quickly or else compatibility across the ports will suffer if you use this feature.
Buttons have been a focus because of the course and I'm working on the button lesson, so I wanted to get some changes in prior, like adding right click menus to buttons, fixing Realtime buttons
Issues GUI
I'm really on the fence about this. I've not heard a peep back from anyone about the demo program for issues. I'm assuming that means it's not been used/tried. So, rather than hold off on adding it oi the code, perhaps the best thing is to go ahead and release it to PyPI and let the real-world test it.
It'll take a little while to get it all integrated and tested today, but it's a day dedicated to the release of 4.39.0 anyway.
PySimpleGUI 2021-04-11T22:52:31Z (Almost posted to PyPI.... it's on GitHub but running some additional tests)
4.39.0 PySimpleGUI 11-Apr-2021
Window.write_event_value is solid release!
The s parm debut (alias for size... works like k does for key)
GitHub Issues GUI
-
write_event_value fixed(THANK YOU daemon2021!)
-
GitHub issue GUI added - access via sg.main() or sg.main_open_github_issue()
-
s parm added to all elements
-
Element.block_focus - blocks an element from getting focus when using keyboard
-
Listbox
-
Set the selected colors to be opposite of normal text/background colors
-
Added highlight parms to Listbox so that they can be directly set
-
The expand method now works for Listbox element
-
-
Button on Mac can be tk Buttons
-
In the past the Mac could only use ttk buttons
-
Now setting use_ttk=False will cause the tk buttons to be used
-
-
Right Click Menu
-
Window get new parameter right_click_menu_tearoff to enable tearoff feature for right click menus
-
Buttons and ButtonMenuus can now use right click menus. Will automatically use the Window's right click menu
-
New constants
-
MENU_RIGHT_CLICK_EDITME_EXIT = ['_', ['Edit Me', 'Exit']] - a common menu for simple programs
-
MENU_RIGHT_CLICK_DISABLED = [[]] to block an element from getting a window's right click menu
-
-
parameter right_click_entry_selected_colors added to Window - a simple dual color string or a tuple - used for right click menus and pop_menu
-
-
Error windows - better line wrapping
-
Show an error window if a bad Image specified in the Image element
-
expand_x & expand_y parms for vtop vbottom vcenter,
-
Added framework_version
-
RealtimeButton works again!
-
New popup - popup_menu will show a torn off right click menu at the indicated location
-
new comment figlets
-
More permissive layouts - embedded layouts for PSG+ features
-
Added more symbols for buttons - double L/R & arrowheads,
-
Moved theme tests into a tab" in sg.main
PySimpleGUI 2021-04-11T23:41:42Z
4.39.1 PySimpleGUI 11-Apr-2021
The initial release had the old code! So, if you grabbed 4.39.0, then you actually have 4.38.0.
Please do another upgrade and you'll get 4.39.1
PySimpleGUI 2021-04-11T23:53:08Z
Issues GUI!
In 4.39.1 you can log a GitHub Issue using PySimpleGUI. It's a more pleasant experience, or it's meant to be.
In the very least, you'll receive some empathy from your weary PySimpleGUI helper as you fill in the information.
This video shows you how to do use the GUI starting by calling sg.main()
. The first window you see is the main() window. You can directly call the Issues GUI as well by calling sg.main_open_github_issue()
Note that this GUI is only available in the tkinter version at this time. The PySimpleGUIQt reworking is just about complete. Adding this GUI is a high-priority item for that port.
PySimpleGUI 2021-04-12T00:04:20Z
GitHub Issue GUI Screenshots....
These are the basic windows you'll encounter to log in Issue if you call sg.main()
First is the main window
Click the "OpenGitHub Issue" button
If you close the window, there's a confirmation screen so that you don't lose the information by accidentally closing the window.
PySimpleGUI 2021-04-13T14:56:11Z
PySimpleGUI Lore.... Properties?
Making the Udemy course has generated a fair amount of reflection on the architecture and design choices about PySimpleGUI.
Maybe a FAQ down the road can house some of this information.
The question has come up in Issues in the past and recently as well. The Properties question that I want to answer is:
Why not use properties for all settings?
TLDR Answer - for simplicity
Simple
Simple is the foundation of PySimpleGUI. It's right in the middle of the name. It has to be simple yet powerful, extendable, and be able to solve complex problems. Despite being simple, PySimpleGUI is quite capable of running quite a complex program. The "Simple" part does not mean incapable of use to solve complex problems.
Being simple opens the PySimpleGUI tent up to more people. Supporting back to Python 3.4 also helps make the PySimpleGUI tent large. The more people the better that are able to 1. Have Fun and 2. Be Successful.
Different
PySimpleGUI is certainly different in the interfaces for programmers to use to build GUIs. From the layout to a single call to obtain both the event and the input values, PySimpleGUI is unique.
Perfect
PySimpleGUI is so very far from perfect!
Improvements can be made in 1,000s of ways. Looking for ways to improve PySimpleGUI can start with the > 600 open issues, many of them enhancements.
When resource-constrained, prioritization of activities is critical.
Highest Priority
The highest priority items are:
-
Bugs that cause significant problems to a large number of people
-
Enhancements that enable capabilities that are entirely out of reach of users without the enhancement
The update
method
As you're quite aware as a PySimpleGUI user, changes to elements at runtime happen via their update
method.
This was a design choice in the first version of PySimpleGUI. I didn't want many methods/functions/properties that are used to change an element. I wanted one.
The benefits of this approach are:
-
Users can look at one line of code to determine what's possible to change
-
The documentation is not required, nor doc strings, in order to get the list of modifications possible
-
Easy to compare the capabilities between ports
Input
Element
Let's look at an example... the Input
element. Here is the update method's definition for that class:
def update(self, value=None, disabled=None, select=None, visible=None, text_color=None, background_color=None, move_cursor_to='end', password_char=None)
Exceptions
Some exceptions exist. Some are by design. Others are by mistakes. It's a far from perfect package.
There are some methods that are common across all elements that are completed not via the update
method, but instead using a method specifically built for that purpose.
Setting the focus is an example of this. It "feels like" an "operation" than a "setting". So, elements have a set_focus
method.
Readonly Element Properties
One property that was added not long ago is visible
. It's nice because you can use it in an expression. This line of code is from the Collapsible Sections demo program and demonstrates what I mean about it being useful in an expression.
Metadata - a read/write property
For elements, the rare exception is metadata. It felt right to be a property. You can set it initially in the element and then access it as a property.
Why not do both?
Time & complexity.
I would rather stay simple than make a dual interface for the element's settings.
Hoping this helps
I dunno if it will help you understand the method to the madness, but I thought it worth communicating this.
Thank you to the fantastic PySimpleGUI community. You inspire me to do this!
PySimpleGUI 2021-04-23T21:34:36Z
Release coming this weekend
There was a big enough "oops" to get a release out asap. The proverbial 1-line-change to fix RelatimeButtons broke dragging events on Graph elements.
So, expect an A4 release over the weekend (you musician will recognize 440).
It has a number of changes that are somewhat nice. Some will be confusing because of how tkinter works on Linux versus Windows.
The reason for all this button activity is that Buttons are the current topic being recorded for the Udemy course. So, when I'm working on a lesson, I'm also fixing up that element as I go., I aw an opportunity to fix a couple of things, add a couple of "easy things" that cost me 2 days so there was NOTHING easy about them.... someday.... someday I'll learn....)
Seeing how the GitHub version is 4.39.1.13, that means there are at least 13 additions since the last release.
THANK YOU
While I've got your attention.... I want to take a moment to say "thank you" to this wonderful PySimpleGUI user community. You're a fantastic lot! I couldn't ask for a nice group of people to be taking the journey with me.
It looks like a number of you are using the new GitHub Issue posting GUI built into sg.main()
. THIS is exciting for me because it means it's saving you time and we're getting the information needed to provide the best support possible.
The vast majority of you are filling in the optional 'experience' question. I felt uneasy about this question and I've explained it many times, and it's talked about in the help pages as well. As someone answering the issues, it's been SO HELPFUL to understand a little bit about the person I'm conversing with. It helps me be on the same communication wavelength. The purpose is simple... to provide you with the best support we can. It is.... it is not there to embarrass you, or any other reason you might dream up.
So many of you say "thank you" when filing a bug. It's mind-blowing to see. It's helpful. It's impactful. It helps me have a better day. It's quite appreciated and it most certainly does NOT go unnoticed.
Keep Making! Keep Sharing!
THE way to learn to program is to do it. "Don't worry, be crappy". We all have to start somewhere. I'm a Python beginner too compared to many others out there in the world.
Please share what you make. Share on Twitter. She here in Issue #10. Share on the WIKI. It doesn't matter where. A screenshot is fine. Code is even better, but it's not a requirement.
I continue to learn from beginners. I look through the GitHub. I read some of what you're making. I learn from you guys and gals. I'm inspired by what you make.
Coffee and Sponsorships GREATLY Help
I don't feel comfortable making pledge drives, asking for financial help. But I'm going to ask this time anyway. It's been an expensive month for the PySimpleGUI project. Nothing you donate, none, zero, goes to me personally. 100% goes to:
-
Domain registration
-
ReadTheDocs
-
GitHub
-
Other programmers
-
Tools
-
Fiverr Vendors
-
Legal fees
It doesn't buy my food or pay my bills. PySimpleGUI is organized and managed as a company. It's different than other open-source projects in this way. It also means I personally am compensated last. The project has been and will continue to be in the red so that a paycheck won't likely come for some time, if ever. It does HELP this project greatly though, so I'm incredibly thankful for every coffee that every person buys. And of course to the monthly sponsors, OMG I'm so thankful for your help. The young programmers that you've helped pay thank you. The more funding available to the project, the more we're able to do.
Project Goals
Note that the project goals have not changed and that they don't have anything that mentions the financial stuff just discussed.
The PySimpleGUI's project goals are
-
To have fun
-
For you, the user, to experience success.
So far, these have served us all very well. I'm having fun. Everywhere I look I see others having fun... and I see tons of success happening. I feel incredibly fortunate to be able to do this with everyone. So, thank you for accompanying me on this journey. I am truly fortunate to have the support from this community that you demonstrate 🙏 Thank you from the bottom of my heart.
And thank you to @jason990420
Everyone has been particularly nice and shown great thanks to Jason, the one-man army that's ensuring your success. He's enabling me to work on the Udemy course while also providing you with top-notch support. I'm in awe of his skill, his generosity, and kindness. He sets a standard I aspire to be more like. Thank you for showing him you care.
PySimpleGUI 2021-04-24T17:54:05Z
REPLIT
One of the first places I ran PySimpleGUI in the browser was on REPLIT. It looks like I set up an account in Feb 2019. The initial use was for PySimpleGUIWeb from what I recall.
Then came the Trinkets .... Once I realized how much adjunct information that could be included on Trinket, I started to create a lot of demos on that site. At one point the Cookbook was FILLED with lots of embedded Trinkets. Then I realized that this SLOWED the page loading considerably... so, they were all removed.
The reason I'm working with it again is to make testing on Linux a bit easier and so that I can demonstrate the differences between Windows and Linux in the Udemy course.
Like so many of the external PySimpleGUI resources, these 2 sites are reachable using the PySimpleGUI.org address. It makes finding stuff a lot easier (for me at least.... maybe I'm selfish in this, but I'm going to pretend it was all done for you, the PySimpleGUI user):
HTTP://Trinket.PySimpleGUI.org
HTTP://replit.PySimpleGUI.org
I just created a copy of all of the demo programs as well as the Demo Browser and the GitHub (not yet released) PySimpleGUI, over to replit. This link opens that replit project.
https://replit.com/@PySimpleGUI/Demos
Assuming I haven't left it in some weird state, you should see something like this:
The main.py file is a copy of the Demo Browser. This is very handy when used with Replit because without it, you would need to use the shell to manually launch each demo.
I have configured the Demo Browser to launch a file if you double click it from the list.
There are some quirks that I'm seeing though:
-
The location parameter for windows seems to be ignored. Windows are always created at (0,0)
-
Getting a window to have no titlebar requires action on your part until I can figure out how to do it in code
-
After launching the program, right-click the virtual desktop and choose "restart"
-
This will remove the titlebar on any windows that shouldn't have one
-
-
Control-A does not select text
no_titlebar
Fix
Here is what I meant in the list above.... the CPU Core Udage Widget is one of the "Desktop Widget"demos.
On my windows machine it looks like this:
When you right click the replit desktop, you'll see this menu that has the "restart" option.
After I chose it, the screen became this:
I'm impressed with the direction replit has taken Python and tkinter.
If you want to try it, be sure and do NOT choose the tkinter option when creating your replit project. Choose the normal Python option.
The Demo REPL
This is the state I've left everything. I have no clue if it will stay this way. Still a lot to learn.
PySimpleGUI 2021-04-26T00:59:50Z
4.40.0 SOON....
I'm shocked that it's the end of the weekend and 4.40 hasn't been posted to PyPI yet. There have been a number of problems with TTK buttons that popped up when testing with the new "Gray Gray Gray" theme (like the "default1" theme but more ..... descriptive?)
A number of things are slowing this down. The biggest is that buttons, both ttk and tk button, behave differently on Linux than on Windows. New features were added that allow you more control over the button colors (highlighting and active settings for example). I think I may be done with the coding, but there is enough testing left to go that I don't want to just jam this code up to PyPI.
I would rather delay a day than have anyone waste time on a problem that could have been avoided with some additional testing. So, delay a day it's going to have to be.
PySimpleGUI 2021-04-26T21:08:51Z
4.40.0 PySimpleGUI 26-Apr-2021
The "A4 Release" (440 Hz)
Buttons get a boost
Fix for Graph Dragging caused by last release
Gray Gray Gray should you wish to go colorless
-
Right-click Menu constant - MENU_RIGHT_CLICK_EXIT - Has only "Exit"
- Constant = ['', ['Exit']]
-
Checkbox.get() now returns a bool instead of int
-
Button colors
-
mouseover_colors - new parm to Button. Sets the color when mouse moves over the button
-
When a TK Button this is Only visible on Linux systems when mouse is over button
-
On Windows, these colors appear when the button is clicked
-
Default is to swap the button's normal colors (text = background, background = text)
-
-
Close Window Only button type changed to work on all windows, not just non-blocking ones
-
ColorChooserButton - target now matches other choosers (target=(ThisRow, -1))
-
-
TabGroup - new size parm that will set size in either or both directions
-
Fix for TCL error when scrolling a column
-
Themes
-
Fix for COLOR_SYSTEM_DEFAULT error when choosing "default1" Theme
-
New Theme - "Gray Gray Gray" - sets no colors. The window will likely be some shades of gray
-
Changed error messages to use "theme" instead of the old "change_look_and_feel"
-
-
Debug window - problems were if set the erase_all parm and Debug window is then closed
-
timer_start, timer_stop - stop now returns the milliseconds elapsed instead of printing them
-
popup_menu - now uses the passed in the title if provided
-
GitHub Issues GUI
-
Made necessary changes to be 3.4 compatible. You can post Issues directly from your Pi running 3.4
-
Changed layout so that the window is smaller
-
New Help window uses tabs to make smaller
-
-
Fix for extend_layout when adding to a scrollable column
-
Added back functions accidentally lost during a PEP8 rework
- added back popup_annoying, popup_no_border, popup_no_frame, popup_no_wait, popup_timed, sgprint, sgprint_close
PySimpleGUI 2021-04-27T11:42:51Z
Mini-Lesson "Know Your Customer"
Part of the enjoyment I get from PySimpleGUI is teaching programming in a broader sense. I try to make my videos so that they teach PySimpleGUI, but also something about the tools, about the user experience, and in this case, about the end-user.
I saw a recent Issue posted here reminding me that not everyone is on Twitter, THE single site I use to communicate globally.
So, I'm posting a link here to a video I made in response to a Twitter post I saw from a user about their lack of need for a GUI. They may be absolutely correct. They may not need a GUI for their program and it may in fact be a terrible idea for them to add one.
Purposeful programming is just as important as purposeful living. I'm not a fan of over-building. I'm not talking about planning for expanding your programs and making them highly extensible when I speak of planning. My point is WHO are you writing this program for. Who is your CUSTOMER?
You'll find the video here on the PySimpleGUI YouTube channel....
https://youtu.be/7-cecLZtB1M
I don't have all the answers to anything. I do not know it all. There is SO much I don't know. Please keep this in mind for all of my work. These are my opinions, based on my experiences.
-
Fun
-
Success
Same goals as always. This video is targeting the "Success" goal.
PySimpleGUI 2021-05-01T16:58:11Z
Sorry about the Bot!
I'm really sorry that the Issues bot was enabled before I realized it would be taking action. I take full responsibility for this and am REALLY sorry this happened. The last thing I want to do is waste user's time (the whole purpose behind the form and process to begin with). It's a rare hiccup and I'll be more careful in the future.
Really sorry to @Zeus-HackOlympus in particular... you were quite patient and appreciate not only your patience, but persistence.
PySimpleGUI 2021-05-11T14:42:05Z
Recently Added Demo - Demo_Execute_Py
This demo is to show the linkage between the Exec call and the Global Setting for the Python interpreter to use when calling execute_py_file
.
The Demo Browser uses this setting. It's a way that you can try out different versions of Python without setting up virtual environments outside of PySimpleGUI. You can use the system default version to launch the browser, then use browser to launch another browser. Even if you don't re-launch the browser, it will launch using the global setting.
PySimpleGUI 2021-05-11T14:45:03Z
Demo - Locate Window
Added this week is a demo that will help you determine what value to entire into the location
parameter when creating your windows or creating a popup. Drag the window around to find the coordinates that tkinter believes the window is located. Then use these values to create windows in a particular spot. This is really valuable when you have multiple monitors set up. This capture is from Windows.
PyCharm is on a secondary monitor. When the demo window is moved into the PyCharm window, you'll see that one of the coordinates is negative because the secondary monitor is to the left of my primary one.
PySimpleGUI 2021-05-11T14:50:31Z
Right Click Menu Constants & Code with "Edit Me" capabilities
I've been adding some constants that create standard right click menus so that you don't have to memorize the format of the data structure.
Here are the definitions:
MENU_RIGHT_CLICK_EDITME_EXIT = ['', ['Edit Me', 'Exit']]
MENU_RIGHT_CLICK_EDITME_VER_EXIT = ['', ['Edit Me', 'Version', 'Exit']]
MENU_RIGHT_CLICK_EDITME_VER_SETTINGS_EXIT = ['', ['Edit Me', 'Settings', 'Version', 'Exit']]
MENU_RIGHT_CLICK_EXIT = ['', ['Exit']]
MENU_RIGHT_CLICK_DISABLED = [[]]
Note that the release 4.40 on PyPI only has these:
MENU_RIGHT_CLICK_EDITME_EXIT = ['', ['Edit Me', 'Exit']]
MENU_RIGHT_CLICK_EXIT = ['', ['Exit']]
MENU_RIGHT_CLICK_DISABLED = [[]]
This screen capture is showing how you can use the "Edit Me" entry to edit your PySimpleGUI program without having to know where it is on your system. The desktop has a shortcut to the Python file so that it's not immediately clear where it's located. Having a self-edit option while you're doing development is very handy from my experience. It's in all of my current desktop widgets that are running 24/7.
PySimpleGUI 2021-05-12T23:15:56Z
4.41.2 PySimpleGUI 12-May-2021
New Readme & Other PyPI info
Fixed Syntax error in Text.update
-
2 more menu definition constants (simply a shortcut way to add right click menu)
-
MENU_RIGHT_CLICK_EDITME_VER_EXIT = ['', ['Edit Me', 'Version', 'Exit']]
-
MENU_RIGHT_CLICK_EDITME_VER_SETTINGS_EXIT = ['', ['Edit Me', 'Settings', 'Version', 'Exit']]
-
-
3 new SYMBOL constants. Use code completion with SYMBOL_ to find some handy symbols
-
SYMBOL_CHECK = '✅'
-
SYMBOL_BALLOT_X ='☒'
-
SYMBOL_BALLOT_CHECK = '☑'
-
-
Syntax error, and thus crash, if the check for widget was created is false
-
Fix for scrollable Column (was able to scroll further than should have been possible)
-
More docstrings to explain Column.contents_changed is needed when layout is extended
-
Docstring addition for read_all_windows to explain which windows will be read and what's returned when a window is closed
-
Titlebar docstring fix - return was misplaced. rtype changed to Column
-
Added execute_py_get_interpreter to return the current global setting
-
get_versions() function added to aid in dubugging. print(sg.get_versions())
-
Returns a human readable string with labels next to each version.
-
Python version x.x.x
-
Port (tkinter)
-
tkinter version
-
PySimpleGUI version
-
PySimpleGUI filename with full path
-
PySimpleGUI 2021-05-12T23:22:40Z
New Readme.....
The reason for the multiple releases, that turned into multiple releases, was an update to the readme.
There are more documentation changes on the way. The readme was just the start. I hired a copy editor to deal with the grammar and spelling problems as well as changes submitted by users.
I thought I could just slip it onto PyPI without much fuss, but I discovered a series of errors from unicode char problems to a badly formatted table. UGH.... what was supposed to be a quiet trivial thing turned into everything but.
Hopefully, the full documentation change on the way won't go quite so badly! LOL.
One of the cleanups was to the stats at the top. Some of it was cleaned up by editor, but it was missing the overall stats. There is no badge I've been able to locate that has a label and the total downloads, so I ended up making this table in markdown. It turned out pretty well and was able to get the Python versions as well. Note that Qt, and the other ports should run on 3.9, 3.10, they just hasn't been updated on PyPI to reflect this.
PySimpleGUI 2021-05-15T20:51:39Z
Using New Development and Debugging Capabilities in 4.41.2
Here's an overview of how to use a number of the new features in a way that optimizes your development.
Add Runtime Display of Versions
Over the past year, there has been more effort put into the workflow of developing, debugging, and modifying your PySimpleGUI programs.
In the last release 4.42.2, a few additions were made to add more capabilities, easily, to your programs.
Some additional constants were added that are pre-defined right-click menus. These are long variable names, but they're shorter than it would be to type in the entire data structure. The assumption is that you're using code completion so typing a long name shouldn't be a problem.
Shaving time from your process
The idea is to remove the burden from you needed to memorize where on your hard drive your program lives as well as not having to manually start your editor if you want to edit your program.
Some of you may be testing on multiple versions of Python and tkinter. If so, then it can be confusing exactly which version of Python was used to start your program. Because you can interact with your application while it's running, it possible to build in features that will aid in your development. Adding a few simple events to your event loop can have a big impact on your day-to-day operations.
sg.MENU_RIGHT_CLICK_EDITME_VER_SETTINGS_EXIT
This constant can be used anywhere you're specifying a right click menu. The best place to put it is in your Window creation. Adding the parm right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_VER_SETTINGS_EXIT
will get you this right click many when you click on your window:
get_versions
- String of Version Numbers
If you're running the basic PySimpleGUI tkinter port, there are several versions of components you need to know including
-
Python Version
-
tkinter version
-
PySimpleGUI version
-
The location of your PySimpleGUI file
You can add the display of this string by printing it or putting it into a popup. To show it in a popup:
It shows a window that looks something like this:
Processing the Events
After adding the Right-Click menu to your window creation, it's a matter of adding the processing of these events to your event loop. Here's an example bit of code to get you started.
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
if event == 'Edit Me':
sp = sg.execute_editor(__file__)
elif event == 'Settings': # this one is entirely dependent on your specific window
settings_window()
elif event == 'Version':
sg.popup(sg.get_versions(), keep_on_top=True)
The result is that you'll be able to launch your editor, look up what versions of the components running in your window, exit the program and show a settings window if your window has one.
From a development cycle point of view, I've found this to be a very useful capability, particularly when your application is running continuously. For programs that are similar to Rainmeter-syle desktop widgets, it's highly efficient and cuts down on unknowns and debugging time.
Example using the Drive Status Demo
This screen capture is of the Demo_Desktop_Widget_Drive_Usage.py file modified using the changes detailed above.
PySimpleGUI 2021-05-19T18:07:57Z
Grab Anywhere Improvement! Plus new Sizegrip element
Was struck with the fix for the long-term problem of grab anywhere moving the window for elements that ideally shouldn't move the window. Multiline, Sliders, Input, Scrollbars will no longer move the window when grab_anywhere is set. Instead, they will take the normal drag operation. For example, in a Multiline Input element, a drag operation would ideally select text. Previously it moved the window.... now, it selects text.
Here's a little Postit example that shows both of these changes. It had grab anywhere set and also includes the Sizegrip element. Without a Sizegrip, it was impossible to resize windows that lacked a titlebar.
PySimpleGUI 2021-05-23T14:46:02Z
"User Appreciation Day" Release Coming
Pulling together a release for today. It will have the new Sizegrip element, but most importantly, it has the long-awaited changes to grab-anywhere that excludes Multiline and other elements the dragging within the element is desired.
"User Appreciation Day"
The reality is that every day for PySimpleGUI is User Appreciation Day 🙏
The guys and gals using PySimpleGUI have been incredibly supportive over the past 2 years 10 months. Thank you all so very much. It's appreciated.... I write about it in my notes as I design new features in my lab books. It's fueled the project and more than I ever expected.
More later today....
PySimpleGUI 2021-05-23T18:13:20Z
4.42.0 PySimpleGUI 23-May-2021
New Sizegrip Element
New MenubarCustom pseudo-Element
Grab Anywhere feature improved
-
New Sizegrip element
-
Needed in order to resize windows that doesn't have a titlebar
-
Place as the last element on the last row of your layout
-
-
New MenubarCustom Element
-
Needed when using a custom Titlebar
-
Provides the ability to have a window that is entirely themed
-
Without it, was not possible to have a custom Titlebar with a menubar
-
Works like the traditional Menu Element (the item chosen is returned as the event)
-
-
Added new elements to the SDK Reference built into PySimpleGUI and in the call reference documentation online
-
Grab Anywhere
-
Finally got the appropriate elements and widgets excluded! Yeah!
-
Now Multiline, Input, Slider, Pane, Sizegrip, active scrollbars will not move the window
-
Additionally, a new method Element.grab_anywhere_exclude() will exclude your element from being grabbed
-
Useful for Graph elements
-
Sometimes you'll have a window with graphs that you can to be able to move using Graph element
-
Other times, you are using your Graph element with drag option set. In this case, you will want to exclude it.
-
-
-
Improved torn-off menu placement. Now places them at the window's location
-
Combo element new bind_return_key parameter - if set, when return key is pressed and element is focused, then event will be generated. Works like the Listbox's bind_return_key
-
Fix for changing the title of a Tab using
PySimpleGUI 2021-05-24T00:20:21Z
Surprise!
Wasn't kidding about it being User Appreciation day
Enjoy the new Window.ding()
by driving your users crazy with error messages. And no, they were Window.ding is not called by PySimpleGUI when an error occurs. There is better error information from the earlier release today though.
A few additional changes to help with Multiline element and grab anywhere. There's a matching include now to go with the exclude for grab_anywhere.
The sg.Print debug window is now resizable by default as is the popup_scrolled.
Hopefully 🤞 doing the 2 releases today won't have been a train wreck. Really do want everyone to know that your creations are a joy to see and experience. These changes should make a number of applications perform better.
4.43.0 PySimpleGUI 23-May-2021
Happy User Appreciate Day!
Multiline expand_x, expand_y parms
Window.ding() - because FUN is the #1 goal
-
Added 2 new parms to Multiline Element
-
expand_x - if True, then the element will expand in the X direction
-
expand_y - if True, then the element will expand in the Y direction
-
replaces the need to perform: window['-MULTILINE KEY-'].expand(True, True, True)
-
Defaults to FALSE to be backward compatible
-
-
popup_scrolled
-
changed to be resizable by default and expands the multline too
-
if no_titlebar is set, then a Sizegrip will be added, unless no_sizerip parm = True
-
-
easy_print(sg.Print)
-
changed to be resizable by default and exands the multiline too
-
if no_titlebar is set, then a Sizegrip will be added
-
-
Window.ding() added - get your user's attention when errors happen or just for FUN
-
Added Element.grab_anywhere_include - includes an element in grab_anywhere in case you have something like a Multiline element that you can to move the window using that element
PySimpleGUI 2021-05-25T15:37:02Z
A Semi-Realtime Tutorial from Twitter
This morning I decided to make a little package tracking Desktop Widget.
I'm expecting a package and am tired of going to the FedEx site. So, I wrote a desktop widget that is constantly checking on the status. As I was working on it, off and on for 2 or 3 hours, I posted little updates.
Here's a basic, crude end result:
If you're on Twitter, you'll find the posts here:
https://twitter.com/PySimpleGUI/status/1397155333458567175
Tip of the Day - Polling
It started as a simple "Tip of the Day"....
Idea 💡 Make a Package Tracker
I got a little piece of code (19 line) from @israel-dryer that does a FedEx scrape given a tracking number
Design the GUI
Since there are a lot of complete beginners that follow "@PySimpleGUI" on Twitter, I thought posting the process I follow would be educational, so that's what I did.
Make a Skeleton
Next step was to mock up the GUI
A Final-ish Version
Then it was a matter of adding the logic to do the lookup of the status and update the window.
PySimpleGUI 2021-05-30T21:28:25Z
The GitHub Issues Bot Enabled
The GitHub Issues bot is now enabled. This bot is really simple in what it does and why it exists.
It checks to make sure that submitted GitHub issues are submitted with the basic Issue form filled in. The checks are really high level such as - not leaving the title with the default string. Or including the OS and Version parts of the form.
I won't bore you with the reason the form exists. If you're curious, scroll back in this Anncouments issue and you'll find a number of times where the concept is explained (i.e. fill in the form ---> get free and courteous support).
The reason for the bot: remove the need for a human being to do these basic checks.
Information about how to fix the problem is included in the message posted by the bot.
Apologies ahead of time if it somehow goes off the rails. There has been a lot of testing performed which is what's held back the deployment until now.
I hope you can understand that nothing is done to intentionally frustrate you nor create unnecessary bureaucracy.... honest. The intent is to save everyone time and get you the answers you seek in as quick of a way as possible.
PySimpleGUI 2021-05-31T21:51:16Z
Pong!
How about some fun added to your Monday?
The Pong demo has been refreshed with a better look and much smoother play. All credit goes to long-time friend @jaynabonne .
The existing demo was replaced. You'll find it in the Demo Programs folder:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Pong.py
PySimpleGUI 2021-06-06T02:29:15Z
Demo - Threaded Progress Bars
For some programs, downloading takes place in a thread. In these situations, it would be ideal if the thread could call the one_line_progress_beter function or perform a ProgressBar update in the user's window.
This demo is a design pattern on how to set up and run a thread with communications back to the mainthread for showing progress.
Here's how it looks. It uses both the one_line_progress_meter as well as one that is part of the main window.
PySimpleGUI 2021-06-06T16:08:01Z
Demo - Right Click Menu for Multiline Elements
New Demo Program added that displays a right click menu similar to what you normally see on Windows. Tkinter doesn't supply these menus but does provide the standard Control+A, Control+C, etc, keybindings.
The code is quite straightforward and lives in the user's code space.
You'll find the demo located in the demo programs folder:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Multiline_Right_Click_Menu_Clipboard.py
PySimpleGUI 2021-06-09T14:19:34Z
Project Spotlight.... derikvanschaik/MIMI
For me, it's been so rewarding and enjoyable to see all the wonderful creations that have been made with PySimpleGUI. It's not something I would have predicted as being a reading outcome.
I've stated a number of times that I like taking a look at code from beginners (to PySimpleGUI). I don't mean to be belittling or disrespectful when I say "beginner" in this case. I'm simply referring to someone that's not an expert... yet.
I found this project to be particularly interesting because Derik has introduced a way of achieving an outcome using a technique that I could have never thought of. He was clever.
Simple and Clever... they both light up the happy spot in my brain.
https://github.com/derikvanschaik/MIMI
This project is a mind-mapping program.
What I wanted to understand is how he was getting the text input. My assumption - keyboard input was enabled for the Window. And, that assumption, was incorrect.
Derik was much more clever. He used an Input
element. OK... so that made me think that he perhaps made the Input Element not visible. * BBBZTTTT * wong again. It's not visible, but not at the element level. It's not visible because he set the text color to be the same as the background color.
Keep on building stuff! It's so much fun watching what's being made. Really rewarding and inspiring to see these creative uses of PySimpleGUI.
PySimpleGUI 2021-06-12T17:02:39Z
popup_get_file
Gets a History Feature
Included in the upcoming release to PyPI is a new popup_get_file. I'll make the same set of changes to popup_get_folder.
popup_get_file
continues to work exactly as before if you call it with the parameters you've used in the past. You'll need to set a new parameter, history
to True
in order to get the new feature.
You'll find a number of demos that show how this kind of feature works. It's worked well enough in my personal programs that I pulled it into the popup_get_file function itself.
If you are using a program that uses the same file over and over and rarely changes, then you'll love this change. To use the previously entered filename, simply press the return key.
PySimpleGUI 2021-06-12T20:21:46Z
popup_get_folder
also has history....
Same kind of history feature added to popup_get_folder
as was added to popup_get_file
.
At least 15 changes since the last release, so likely going to release tomorrow.
PySimpleGUI 2021-06-13T16:46:36Z
4.44.0 PySimpleGUI 13-Jun-2021
popup with history
clipboard functions
fonts for printing
-
Added clipboard_set and clipboard_get functions
- Known tkinter problem requires application to remain running until pasted (EXCEPT on Windows)
-
History feature added to popup_get_file and popup_get_folder
-
Set parameter history=True
-
Your users will love it! (promise)
-
-
font parameter added for Multiline-type of outputs so font can be changed on a per char basis. Added to:
-
Multiline.print
-
cprint
-
Debug print - Print, easy_print
-
-
Listbox visibility fix
-
Tree, Table expansion fixed
-
Combo size not changed unless the size parameter changes in the update call
-
Canvas removed from return values
-
Versions string returned from get_versions() is clearer
-
cwd automatically set for folder of application being launched when execute_py_file is called with cwd=None
-
Fix for Mac for popup_get_file
-
Better button error handling when bad Unicode chars are used or bad colors provided
-
Open GitHub Issue GUI improved. Added collapse button for top section
-
See-through mode in test harness changed to be a toggle
-
Several error messages changed to error popups with traceback
-
Combo added to list of elements that initially get focus when default focus is used
-
Sizegrip autoexpands row so that it anchors correctly to right hand side
-
MENU_SEPARATOR_LINE constant
-
Button highlightthickness set to 0 if padding on the button is 0 in either x or y
-
__version__
fix for pip installed versions -
Release dedicated to Lester Moore
PySimpleGUI 2021-06-14T15:04:38Z
Issue Response Speed
Over the past couple of weeks, I've been taking a break from working on the Udemy course and spending more time here directly working on GitHub Issues.
The Qt port rework was completed this past week so the testing of this code is going to take up a large portion of my time. There are some non-technical project priorities also on the list the next couple of weeks.
You're in fantastic hands, of course, with Jason. Even with me being as on top of issues as I can, he often beats me to a solution. If he's booked up, then there will simply be some lag that happens to get your issue addressed.
Your support has been fantastic, as usual, and it's greatly appreciated. 🙏 I wake happy and motivated every day to work for you, my customers.
PySimpleGUI 2021-06-15T12:21:47Z
Clipboard Functions in 4.44.0
There are a number of "supporting APIs" that are built into PySimpleGUI. These sets of calls and classes are meant to make your application development Simple, require less integration of other packages and hopefully, simpler code in the process.
The UserSettings are beginning to be used more heavily in Demo Programs and within PySimpleGUI itself. It no doubt saves a good deal of code than if you were using the JSON calls it wraps.
The two additional functions in the release for clipboards are documented in the call reference documentation here:
https://pysimplegui.readthedocs.io/en/latest/call%20reference/#clipboard-apis
The are:
-
clipboard_set(new_value)
-
clipboard_get()
tkinter Clipboards - Word of Caution
Because PySimpleGUI relies only on the standard library available on 3.4 and greater and no other external packages, that means these clipboard functions are implemented using the tkinter based clipboards.
For non-Windows systems - This clipboard is erased when your application exits.
Yes, you read that correctly, and it is unfortunate, but the tkinter clipboard is emptied when the application exits. The bit of silver lining is that on Windows systems, I've managed to get the right combination of calls together that does NOT ERASE the clipboard when your application exits.
Recommendation - limit to operations inside your application, provide words of caution or use a clipboard package
While these 2 functions are quite handy, be sure and be responsible with how you use them. The documentation / docstring provides warnings of this limitation. You should do the same in your application if your user is going to be copying from your application to somewhere else.
Two of the Demo Programs that use a clipboard Demo_Base64_Single_Image_Encoder and Demo_Theme_Color_Swatches both use pyperclip as it's assumed that the user will be pasting into other applications from these demos and it's highly likely that the demo program will not continue to be running during the paste operation.
As always, thank you for your support and encouragement!
PySimpleGUI 2021-06-17T20:00:52Z
X1 and Copernic
I've been using X1 and Copernic since at least 2010 (based on emails found using X1).
If you're in business and work with documentation and emails frequently, these tools are huge timesavers. Not only are they very quick at locating information, but they also remove the need to maintain a memorable folder structure for your emails and documents.
The way these tools work is they constantly index the names and contents of files. This name searching for items incredibly fast.... as fast as you can type. In meetings, I was able to find information inside of documents while my colleagues were still trying to locate the documents on their hard drives. What I find particularly appealing about them is that as you type, the number of entries found gets smaller and smaller. When you find the information you're after, you simply stop typing.
I have never used these tools with code until the past year. I'm not sure why I had any doubts considering how well they perform in general.
It's particularly good when you're looking for information that's contained both in the documentation and in code.
I've been using X1 mostly, but have been trying out Copernic this week. This screenshot is an example of looking for uses of popup_get_file
. You can see it finds the string in the Cookbook, main documentation, and a number of demo programs as well as the PySimpleGUI code itself.
PySimpleGUI 2021-06-17T20:15:37Z
popup_error_with_traceback
- a new popup
A new popup for your enjoyment!
popup_error_with_traceback
is the same popup that's used internally by PySimpleGUI to report problems like key errors. It has the unique feature of opening your editor to the line with the error. In this case, the line reporting the error is the line of code with your call to the popup.
Editor Setup
In order to use the "Take me to error" feature, you will need to set up your editor in the PySimpleGUI Global Settings.
This can be easily accomplished by calling sg.main()
and clicking the Global Settings button. You will be shown this window:
Set up your editor's location. Depending on the editor you choose, an "Edit Format String" will be automatically set. If you use an editor not in tooltip:
then you will need to find how to invoke your editor so that the file and line number are correctly passed on the command line when the editor is started.
Parms
At the moment there are only 2 parameters - the title and then a variable number of arguments that are shown in the popup window.
Here is how the parms are displayed in PyCharm's documentation window:
PySimpleGUI 2021-06-18T11:38:25Z
Code Grepper Chrome Extension
Disclaimer - I have not thoroughly examined the privacy factors of this extension. I also have nothing at all to do with its development, marketing, sales or any other nefarious activity it may or may not be engaged in. I accidentally found it while looking for ways to search GitHub.
Copy Code Snippets
It's capable of a lot more evidently, but the single purpose I use it for is to copy code fragments. Take for example this code posted by, of course, Jason, here in a PySimpleGUI GitHub issue. The extension adds this "splat" looking character that when clicked adds the code onto your clipboard.
Found in the Chrome store
I located this tool via the Chrome Web Store
https://chrome.google.com/webstore/detail/grepper/amaaokahonnfjjemodnpmeenfpnnbkco
Please report security issues if you find any
If you find a problem using this extension, I'm interested in learning about it since I'm taking the rather unusual action of making a post about it. If I didn't feel like it could be a direct and positive impact on PySimpleGUI users, I wouldn't have posted it. If it has any negative impact, I would like to be alerted quickly.
PySimpleGUI 2021-06-20T16:46:15Z
Project Spotlight - cenkakay08/Webcam-GUI-with-PySimpleGUI
This project popped onto my radar via Twitter, basically the only point of contact I have with users outside of GitHub.
The Repo is here:
https://github.com/cenkakay08/Webcam-GUI-with-PySimpleGUI
One thing I really like to see in PySimpleGUI repos are screenshots and this one had several.
I was able to download and run the program without doing any setup or changing anything at all. I simply ran main.py and it worked. Works right out of the box is a fantastic feature to have for a project!
Here's the image I Tweeted
Tutorial - Integrating with Trello
Another Twitter item that showed up. I generally don't read tutorials anymore, but do use Trello and didn't know that they had an API, so I made an exception and gave it a spin. It's a "what the heck" kind of day.
It too was a works out of the box, but I did need to gather a series of tokens, keys, id, etc. It took under 5 minutes though.
https://www.qlitre-weblog.com/post_detail/53
I downloaded code for 2 files, generated the keys, and was able to pull data from one of my boards.
PySimpleGUI 2021-06-20T21:13:57Z
The Issues Form Biggest Surprise... Experience
Ah... the PySimpleGUI GitHub Issues Form.... doesn't it make you a little queasy just reading the words?
THANK YOU to everyone that's submitting issues for doing a great job with a primitive system.
It's been a bumpy road but it's been super helpful to have the information in the issues organized and the information collected ahead of time. I hope that the checklist has been of help in solving your problem so that you didn't end up needing to submit an Issue.
The big surprise, and I'm truly shocked by this, is the Experience section.
It's clearly marked as optional. I expected this section to be the most controversial part of the process, but it's gone entirely in the "it's working great" direction. Love it!
I wish more companies did this now that I've experienced having it be part of the process.
It's helpful to the person answering the issue as it gets us all speaking the same language and operating at the most efficient level possible.
If someone has 20 years of programming experience, then a lot of stuff can be skipped over or compacted in the explanation. Or maybe some programming terms are used that an experienced software engineer would know, but not a complete beginner. It's great seeing experienced developers asking questions here! Seeing someone with a hefty amount of time at a keyboard using PySimpleGUI feels really nice.
I thought, incorrectly, that it would be intimidating for beginners. But I think what's happening is just the opposite. It gives beginners a place to very safely raise their hand and say "hi, I'm a beginner, and I'm struggling a little". It gives you a bit more room for making errors.
We've all been beginners. I'm still a beginner in Python to some extent. The really early PySimpleGUI code exposes just how much of a beginner I was.... so I've been where you are in your education as a Python developer, not that long ago. I get help from friends that are more experienced with Python than I am. I asked my friend Jay today for help with a problem.... and he was an enormous help!
So... keep on filling it in please! It's helpful information.
Finally, thank you for the "thank you's". It's SO nice to see Jason being thanked, frequently, for his expertly answered problems. It makes me feel good to see his hard work and patience being recognized because I can clearly see what he's doing and it's a good bit of work he's putting in for this project.
These kind words really do fuel this project. I'm eager to work on PySimpleGUI every day. You all make it such an enjoyable thing to do by creating the amazing creations you make and being a fantastic community.
PySimpleGUI 2021-06-21T13:50:17Z
4.45.0 PySimpleGUI 21-Jun-2021
Happy 1M installs and 3 year anniversary edition!
-
Fix for no titlebar windows on Raspberry Pi
-
This appears to have fixed a problem on REPL.It
-
And also on the Mac!
-
Setting twice now - not sure if will cause a side effect
-
-
Docstring updates for more clarity on Window.current_location
-
Menu Element (recorded the Udemy lesson which generally results in finding some problems)
-
fix for update modifying the caller's data!
-
fix for color settings incorrectly in update
-
fixed docstring
-
fixed menu tearoff location after update
-
-
Better string length handling in the error popups
-
NEW popup - popup_error_with_traceback
- Provides the same error window as used internally with PySimpleGUI
-
Changed Output element's docstring to explain Multiline is now recommended instead
-
Fix for combo and input element readonly state not being recalled when updating disabled value
-
Moved *args to end in one_line_progress_meter
Watch this space for another announcement today!
PySimpleGUI 2021-06-21T15:17:06Z
Happy Anniversary and 1,000,000 install milestone!
I'll get right to the good part....
System Tray For Tkinter - From Me to You...
As a way to say "thank you all for being a great community" I've written a new mini-module, psgtray, that you'll find in the root folder of this repo. It's not packaged, it's just a .py file that you can put into your app's folder or place on your Python Path.
It requires installing
-
pystray
-
PIL
It will run on 3.6, minimally and has been tested against 3.9 as well
There is a demo built into the file and there is also a Demo Program posted here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_psgtray_Tray_Icon_Tkinter.py
It's meant to be a little "gift" of sorts.
The code works well on Windows. On Linux, well, it sometimes works with GTK and sometimes struggles. Hopefully this will continue to improve and some of the Linux experts can jump in and give us a hand with this one.
I'll make a specific Issue dedicated to this new capability.
1,000,000 Pip Installs
I rarely talk about numbers and ranks and status and all the other trappings that can get in the way of the more important thing, the thing being built. But I would like to take this moment to reflect a little.
The PyPI site mentions that installs aren't a particularly good reflection on a project's health, but in this case, I think it's a valid measurement. As a math/science kind person, I need some kinds of yard-sticks (sorry American here) to measure progress. I don't view PySimpleGUI as competing with other solutions. It's simply another option. There is no best. There is only best for the situation and even then that's a dicey use of best.
Trends
Another measurement that I use is the GitHub Trends. Interestingly, PySimpleGUI, the project, doesn't trend so much on GitHub. Or if it does, I never notice as I'm more focused on the other GitHub Trend.... the Account.
https://github.com/trending/developers/python?since=daily
PySimpleGUI, the GitHub Account, has been trending on GitHub's top 25 for a year or more. Some days it's #1
for all Python projects and I have no clue why. Astonishingly, some days it's the #1
account for all of GitHub. That I will never be able to wrap my head around.
Today, it's at #16
for the day, #3
for the week. I don't know all the magic that goes into the trend stats, and to be honest, I don't want to know. It may influence my behavior or something like that and I don't want to be a slave to a number or a trend. It's a fun bit of recognition, but not meant to be an actual target, something to post or boast about. It's a personal little bit of recognition by the GitHub algorithm.
It's great the PySimpleGUI account is getting attention and used, and it's been great that the focus is on the package, not me. It's not about me, never has been about me, and I hope never will be. It's about you.
Why Do This?
While it's fun to measure progress, that's not what gets me excited about this project. Stats and status are not the reason I work every day on PySimpleGUI. It's seeing what you make, getting the heart-felt "thank you emails", marveling at the clever and unique uses, and the biggest one is getting to see the spark that happens for beginner developers.
I'm fortunate to get to witness people discovering programming. I see it often on Twitter. I fondly recall falling in love with programming and I get to relive that moment through you and your discovery of learning to code.
Why PySimpleGUI is Structured the Way It Is
PySimpleGUI is different than other Open Source projects as you all know. Pull requests aren't accepted. No doubt some will find this frustrating and feel like the project is moving slower than it could. Maybe that's true. I don't know.
The primary reason the project is structured the way that it is - it enables me to completely dedicate myself to this effort. It's the environment I need to wake and race to the computer, ready to see what the day brings for PySimpleGUI. It's simply what I require. I know that sounds selfish, and maybe it is. I hope that it's offset by what has been given to the community as a result of this setup.
I appreciate the support... more than I can express in words. 🙏 A few kind words go a very long way in someone's day. I sometimes comment on a PySimpleGUI Repo someone has made by opening an issue. Seeing "you've made my day" in a response is pure gold.
Sometimes an email arrives from someone explaining that PySimpleGUI has enabled them to create something they've dreamed of making for years, has not been successful in the past, but PySimpleGUI has finally made that dream come true.
These are priceless interactions. This feels like what life's all about. Writing perfectly clean Python code... being an "ista".... this doesn't have the same kind of effect on me. But seeing someone be successful at making their dream come true. That's impactful.
The funding situation continues to be a problem, but not going to spoil the fun here by focusing on anything that's not positive.
Thank you all!
I owe thanks to SO many people.... Jason is an obvious one, but there are others behind the scenes that help too. See the readme for a growing list.
Thank you to the GUI makers that publish their work...
And to the sizable Japanese community that I see active on Twitter.
I'm fortunate and thankful 🙏 I hope we can continue and have 3 more years of fun moments and successful projects together.
PySimpleGUI 2021-06-21T19:51:28Z
pip install psgtray
Decided to go ahead and make this a pip installable package to save you the trouble of having to copy the file, etc.
Hopefully I've done the PyPI setup correctly!
There is an issue opened that announces the new feature, so feel free to add any install or other problems you find.
PySimpleGUI 2021-06-22T14:31:50Z
Tip - Platform Test APIs
The call reference has this section that may be of interest to some of you:
https://pysimplegui.readthedocs.io/en/latest/call%20reference/#platform-checks
The programs I write that use PySimpleGUI has as few imports as possible. PySimpleGUI has some calls that are used internally to check the platform. They are of course based on the sys.platform
variable. Using them means I don't need to import sys along with PySimpleGUI.
Rather than importing sys and checking the platform yourself, try using the PySimpleGUI calls. For example if you want to run some Linux specific code, you can use this construct:
PySimpleGUI 2021-06-23T18:05:39Z
New Demo - Demo_Notify_Integration
While putting together the "System Tray Icon" celebration demo I considered using this notification package. I ended up not needing it, but since I've got it working with PySimpleGUI I might as well release it as a Demo Program.
You will need to install the notify package using this pip:
pip install notify-py
Note the spelling. The PyPI name is not the same as the import name.
Like other PySimpleGUI Demo Programs, this demo is not meant to be an exhaustive demonstration of all of the capabilities of the notify package. Take a look at the project's GitHub for more options. There are a number of settings that this demo doesn't show such as a custom sound.
Even though the posted "thank you" system tray project didn't use this code, it's still a little bit of the "thank you" 🙏
The code is short so I'll drop it in this announcement.
import PySimpleGUI as sg
from notifypy import Notify
import tempfile
import base64
import os
"""
Demo of Notification integration with PySimpleGUI
You will need to install the py-notifypy package (note spelling!):
pip install notify-py
Displays an OS created notification
There are more options than those in this Demo... like all PySimpleGUI Demo Programs
the demo is meant to give you a starting point
For more info about the notifypy package, visit the project's GitHub
https://github.com/ms7m/notify-py
To show a notification, call the function provided: notify_popout
If you use a base64 icon, then a temp file will be created. If you wish to cleanup these
temp files (an optional step), then include this line of code when you close the window:
[os.remove(file) for file in notify_popout.temp_files] if hasattr(notify_popout, 'temp_files') else None
Copyright 2021 PySimpleGUI
"""
def notify_popout(title=None, message=None, icon=sg.DEFAULT_BASE64_ICON, app_name=None):
"""
Show a notification popout window
:param title: Title shown in the notification
:param message: Message shown in the notification
:param icon: Icon shown in the notification - defaults to PySimpleGUI icon. Should be a PNG file
:param app_name: Application name shown in the notification
"""
if not hasattr(notify_popout, 'temp_files'):
notify_popout.temp_files = []
notification = Notify()
notification.title = title
notification.message = message
tmp = None
if isinstance(icon, bytes):
with tempfile.TemporaryFile(suffix='.png', delete=False) as tmp:
tmp.write(base64.b64decode(icon))
tmp.close()
notification.icon = tmp.name
elif icon is not None:
notification.icon = icon
if app_name is not None:
notification.application_name = app_name
notification.send(block=False)
if tmp is not None:
notify_popout.temp_files.append(tmp.name)
def main():
"""
A little test application that demonstrates calling the notify_popout function
"""
layout = [ [sg.Text('My Window')],
[sg.T('Notification message:'), sg.Input(key='-IN-')],
[sg.B('Show Notification', bind_return_key=True), sg.Button('Exit')] ]
window = sg.Window('My PySimpleGUI Application', layout)
while True: # Event Loop
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Show Notification':
notify_popout(title=window.Title, message=values['-IN-'], app_name=window.Title)
window.close()
# enjoy the anti-pattern that cleans up the temp files
[os.remove(file) for file in notify_popout.temp_files] if hasattr(notify_popout, 'temp_files') else None
if __name__ == '__main__':
main()
PySimpleGUI 2021-06-26T20:13:11Z
New repo - PySimpleGUI/psgtray
I've made a repo to match the pip installable psgtray package.
I don't do a lot of these adjunct projects that are themselves packages. Hopefully... with a little luck... I got it kinda sorta maybe close to being right. If not, I'm sure someone will eventually open an issue here for it.
The location of the repo is:
https://github.com/PySimpleGUI/psgtray
It's the same code that was uploaded to PyPI this past week. On my system, running the install file installed the package into my site-packages list of packages and made it available to be imported. The Demo Program ran without any problems.
PySimpleGUI 2021-06-30T15:48:19Z
New Matplotlib Demos
I'm recording the lesson on the Image element and wanted to get a couple of Demos posted that use the Image element, rather than the Canvas element, to draw Matplotlib graphs.
I saw a spectrogram recently in this machine learning project. I've seen them in a number of radio tuner GUIs. At least I think that's what those GUIs show.
https://github.com/CorentinJ/Real-Time-Voice-Cloning
Here is the basic demo that makes a Spectrogram.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Matplotlib_Image_Elem.py
It uses, directly, the code from the Matplotlib Gallery page:
https://matplotlib.org/3.3.3/gallery/images_contours_and_fields/specgram_demo.html
It seemed to me that users may animate this particular graph.... so, a demo was created to animate the graph.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Matplotlib_Image_Elem_Spetrogram_Animated.py
The frame rate isn't all that high, so decided to try a multi-threaded version.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Matplotlib_Image_Elem_Spetrogram_Animated_Threaded.py
PySimpleGUI 2021-07-02T22:24:22Z
Project Spotlight - ella444/Hackathon
https://github.com/ella444/Hackathon
It's really enjoyable looking through projects that you guys and gals are posting. Being an "enabling technology" is great because I get the pleasure of seeing what's created... and it's a real pleasure to get to see it. Maybe teachers get this kind of satisfaction from their jobs.
A college group was posting about their project on Twitter a couple of weeks ago and learned today that they did well with their professor. It's great hearing your stories and how you're using PySimpleGUI so keep them coming. Post screenshots in Issue #10, throw them into an Issue if you have a question, or add them to the Wiki... or all 3.
I stumbled upon this project that looks like a Parkinson's Research project from the description.
Of course, the screenshot immediately caught my attention:
What's really surprising, and continues to be a surprise, is the diversity of things everyone is making. I keep thinking that I've seen all there is to see, and of course haven't.
Thank you for all the nice messages I keep seeing! They're really appreciated and definitely keep me working at this. 🙏🏻
PySimpleGUI 2021-07-03T18:41:52Z
File Browse with History Demo
This file history feature was added to popup_get_filename
recently. Someone asked for just the code that implemented the history portion.
There wasn't a standalone demo program that only implemented this "file browse with clearable history" feature, so made one that you'll find here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Combo_Filechooser_With_History_And_Clear.py
It's a short piece of code so I'll include here:
import PySimpleGUI as sg
layout = [[sg.Combo(sorted(sg.user_settings_get_entry('-filenames-', [])), default_value=sg.user_settings_get_entry('-last filename-', ''), size=(50, 1), key='-FILENAME-'), sg.FileBrowse(), sg.B('Clear History')],
[sg.Button('Ok'), sg.Button('Cancel')]]
window = sg.Window('Filename Chooser With History', layout)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Cancel'):
break
if event == 'Ok':
# If OK, then need to add the filename to the list of files and also set as the last used filename
sg.user_settings_set_entry('-filenames-', list(set(sg.user_settings_get_entry('-filenames-', []) + [values['-FILENAME-'], ])))
sg.user_settings_set_entry('-last filename-', values['-FILENAME-'])
break
elif event == 'Clear History':
sg.user_settings_set_entry('-filenames-', [])
sg.user_settings_set_entry('-last filename-', '')
window['-FILENAME-'].update(values=[], value='')
window.close()
It stores both the list of previous entries as well as the last entry used so that when you run your program, you can simply click Ok. You can also bind the return key to the Ok button so that all you need to do is press return and you'll be off and running. Replace the OK button in the above with:
PySimpleGUI 2021-07-05T12:07:35Z
popup_error_with_traceback
Gets a Kill Button
I use these error popups both internally to PySimpleGUI but also within apps. One issue that's come up is that it's possible to get into infinite loops... it's a very not-fun situation... until now (on GitHub), you had to sometimes open task manager in order to kill your app. Now you can click a "Kill Application" button in the error popup.
PySimpleGUI 2021-07-13T11:12:50Z
Repl.it Is Working Better
There has been a bit of a transition over the past few months. Some of the replit features broke as they improved the overall replit experience.
The 2 biggest problems where:
-
Unable to create windows at any location on the screen other than (0,0)
-
Unable to create windows without titlebars without having to refresh the window
Those have been fixed but there's a new problem
- Unable to move windows using the system supplied titlebar... grab anywhere windows move with no problem.
You'll find this replit has the Demo Browser and demos running in it:
https://replit.com/@PySimpleGUI/Demos#main.py
As you can see from this screenshot, I've updated the PySimpleGUI version in the project to 4.45.0.11, the latest and greatest on GitHub. You can run the demos listed in the Demo Browser. The nice thing about this environment is that it's a Linux implementation so it makes for an easy place to test Linux features without opening a virtual machine.
The versions shown using the PySimpleGUI get versions call are:
PySimpleGUI 2021-07-17T16:53:28Z
PySimpleHotkey
https://github.com/PySimpleGUI/PySimpleHotkey
This morning I threw together a new repo.... and this truly has been a threw-together kind of thing. It was meant to be a personal project / tool, but seems like others could benefit from at least seeing what I'm running.
It's a really simple hotkey program that runs a couple of utilities when their hotkeys are pressed.
The utilities operate on the clipboard and were written to help with the PySimpleGUI docstrings.
Here is how the system tray and window portion look.
The 2 utilities are described in more detail in the readme on the repo.
One lines up the descriptions and types in a docstring. The other utility adds type and rtype lines for each of the parameters. PyCharm will auto generate docstrings, but it doesn't include these type lines. I got tired of manually creating them and finally took action.
The alignment tool does this to docstrings:
Input:
Output:
"Robust" is not a term I would use for this repo.... "working" is a good description though. Windows is the best environment to use for this repo as it uses the psgtray package which hasn't been tested on the other environments.
PySimpleGUI 2021-07-18T18:38:23Z
Clipboard with Images.... what a lesson
How a 20-minute project turns into a 6 hour one.
15 minutes to write a GUI, and then the 5 minutes to clue it to the clipboard turned into a 5 1/2 hour lesson. Thankfully I've got smart friends and can search the net. But even with those resources, it was a difficult path.
One thing that has been enjoyable about the PySimpleGUI project is that I'm able to share with you what I learn and learn from you fine folks as well.
My naive view of the clipboard universe what that it's a "single entity".... you put an image on there and then you paste it into another application. Simple, right?
Well, it's not. When you place an image on the clipboard, you may need to save multiple formats of that image. Didn't have a clue this is how the Windows clipboard works.
For example, I wanted to save a PNG file to the clipboard so that I can paste it into GitHub, Discord, Outlook, etc. PNG files rock for a couple of reasons.
-
They're lossless
-
They have an alpha channel
The problem is that not all of the applications can read the PNG format and also deal with the alpha channel. So, to get around this, a bitmap format was also needed in my case. I invested the time in chasing this down because I know I'm going to be working with images for testing where the image from previous runs is compared to prior runs.
Emoji Toolbar Desktop Widget
The little 20 minute application this morning was to make a little toolbar that I can use to place the PySimpleGUI emoji's onto the clipboard for easy pasting.
You know, the happy PySimpleGUI emoji:
But, part way through, once I started to learn about these multiple formats, It became a not-so-fun experience
Making the floating toolbar was 15 minutes as the code is available in Demo Programs.
It's under 90 lines of code. In fact, the window itself was created with this bit code.
def make_toolbar(emoji_names, file_dict):
button_row1 =[sg.Button(image_data = convert_to_bytes(f'{file_dict[emoji_names[i]]}_{EMOJI_SIZES[2]}.png', (50,50)), tooltip=emoji_names[i], key=emoji_names[i], ) for i in range(len(emoji_names)//2)]
button_row2 =[sg.B(image_data = convert_to_bytes(f'{file_dict[emoji_names[i]]}_{EMOJI_SIZES[2]}.png', (50,50)), tooltip=emoji_names[i], key=emoji_names[i],) for i in range(len(emoji_names)//2, len(emoji_names))]
size_col = [sg.Col([[sg.Radio(s, 1, default=True if s == EMOJI_SIZES[2] else False, font='_ 6', k=s, pad=(0,0))] for s in EMOJI_SIZES], pad=(0,0))]
layout = [sg.vbottom(button_row1+size_col)]
layout += [button_row2]
return sg.Window('', layout, element_padding=(0,0), margins=(0,0), finalize=True, no_titlebar=True, grab_anywhere=True, right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_EXIT, keep_on_top=True, button_color='black')
Layout Built Using List Comprehensions
This Window is an interesting one as it's mostly generated. There are some techniques used that are worth mentioning. There is only 1 Column element used because it's a simple 2-row layout with Buttons being the majority of the interface. If you have a list comprehension in your layout, you can include it on the same row with other elements by "adding" it to the row. This is what happened in this statement:
The row of buttons on the first row was combined with the Column element to create the top row of the window. They are passed to the layout helped function vbottom
so that they are bottom justified.
Adding the second row onto the layout is done with simple addition:
It could have been written as 1 large layout definition, but it's easier to understand and debug if the list comprehensions are on individual statements and if the Column creation is also separated.
This is the line that makes the Radio buttons that choose the size of the image:
size_col = [sg.Col([[sg.Radio(s, 1, default=True if s == EMOJI_SIZES[2] else False, font='_ 6', k=s, pad=(0,0))] for s in EMOJI_SIZES], pad=(0,0))]
It creates this little portion of the window:
The Lesson Learned - Clipboards With Images Are Not Trivial
Here's the code that reads a cile and then puts 2 versions of the image onto the clipboard:
filename = os.path.join(EMOJI_PATH, f'{emoji_dict[event]}_{size}.png')
output = io.BytesIO()
image = PIL.Image.open(filename)
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
image.save(output, "PNG")
fmt = win32clipboard.RegisterClipboardFormat("PNG")
win32clipboard.SetClipboardData(fmt, output.getvalue())
background = Image.new("RGB", image.size, (255, 255, 255))
background.paste(image, mask=image.split()[3])
output = io.BytesIO()
background.save(output, 'BMP')
data = output.getvalue()[14:]
win32clipboard.SetClipboardData(win32con.CF_DIB, data)
win32clipboard.CloseClipboard()
Despite it being a lengthy lesson, I'm glad I went through the entire process and got an education on the Windows clipboard. It'll certainly be knowledge that I'll reuse.
PySimpleGUI 2021-07-20T13:06:13Z
Integrating PySimpleGUI With Other Packages
Early on it was clear that integrating with Matplotlib and OpenCV were important packages to demonstrate the different ways they can be brought together with PySimpleGUI.
PIL is another package that's been an important one to operate with.
Integrating keyboard
and pyautogui
You might have seen the hotkey repo that was added. It's been a nice addition as I can now easily integrate PySimpleGUI directly into workflow such as coding, or even chatting on Discord.
I've started integrating with pyautogui
this week as well.
Part of the PySimpleGUIQt testing is automated and I would like to leverage this work into all PySimpleGUI tests going forward. It's incremental and while not perfect it's still a positive step forward.
I'll release some of the tools in the various PySimpleGUI repos such as the PySimpleHotkey repo.
This morning as part of getting to know pyautogui
, I added the ability for my recent emoji chooser to popup wherever the mouse is located. When I learn a new technology, I learn its use best when I try to apply the technology. So, the idea here was to make this emoji chooser to work like the Window+. chooser that Windows has.
Now when I press a hotkey, the window is created where the cursor is located, you choose the emoji and it's put on the clipboard, ready for pasting.
It's a silly kind of application, but it was quick to add and now I have a nice design pattern I can use for the bigger application. I understand how getting the mouse position works and then how I can also integrate that information in to PySimpleGUI.
PyCharm
expansion using hotkeys
The recent addition of some simple docstring utilities paired well with the hotkey manager and enabled me to quickly fix a docstring bug that was posted yesterday.
You'll find the utilities and the PySimpleHotkey code in the repo:
https://github.com/PySimpleGUI/PySimpleHotkey
Working with the clipboard has turned out to be a real winning kind of combination when it comes to expanding IDEs, editors, email programs, etc. I don't need to learn how to write a plugin for PyCharm. Instead, a simple grab what's on the clipboard, modify it and place it back on the clipboard works in a very general way. This is why I created and posted the HotKey manager.
Making Your Own Tools
Perhaps many of you have experienced making tools using GUIs throughout your career, but I haven't. The novelty and the elite at being able to do this has been thrilling. Seriously, being able to write my own development tools has been really rewarding and it's paid off in time many times over.
For those of you that are searching for projects / tutorials, this is a highly fertile area as you win on multiple levels. Not only are you learning how to program, but the results of your efforts are not another version of tic tac toe, but instead a tool that you use daily.... that improves your life. This has been SO rewarding for me... maybe it will be for you too.
PySimpleGUI 2021-07-22T15:09:29Z
expand_x
and expand_y
added to all elements
The latest version on GitHub has a significant change. All elements now have the expand_x and expand_y parameters. Previously the expand method was called on elements that are to expand with window size changes.
This removes the code similar to this:
window['-DEMO LIST-'].expand(True, True, True)
window[ML_KEY].expand(True, True, True)
window['-PANE-'].expand(True, True, True)
Those are from the Demo Program Browser. They were all removed and the individual elements now use the expand parameters to achieve the same results.
Ripple Effect
By again bringing the setup of an element back into the constructor, that means the layout contains all of the required information. This in turn means that 1 line of code could be used for an entire window. The code collapses in on itself with the result being 1 line of code.
The single-line-of-code thing itself isn't all that important. It's making an element's initial settings be autonomous that's the more important point.
Evolution And Revolutionary
While PySimpleGUI has been a departure from the normal GUI architecture and the initial release contained all that was needed to have a package that was different, PySimpleGUI has continued afterward in an evolutionary fashion. This is how the expand
method came to be in the first place. It was an add-on that wasn't added in a particularly elegant way.
It's nice on occasion to be able to go back and fix some of these intermediate solutions so that they fit the PySimpleGUI architecture in a more natural way. It's been clear for a while now that the expand feature is being used more and more, so it got to the point where inesting in this change made a lot of sense.
PySimpleGUI 2021-07-22T19:42:24Z
Long-Operation Demo
There are a number of multi-threaded demos.
I'm constantly looking for new ways to make multithreading be accessible to complete beginners. The idea behind this demo/design pattern is to remove the need to understand threading entirely.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Multithreaded_Wrapper_Func.py
A user will need to do these things to incorporate this into their GUI:
-
Copy the section marked "Thread"
-
Add a call to
perform_long_operation
that passes in their function and a key that signals the end of the call -
Add a check for the "end of call" key
In the event loop, there are 2 things to modify, the parameters to the perform_long_operation
function call:
And a check for the end of operation key:
This is the same as calling:
my_long_func
with the parameter being the value entered
Here's the function being called:
def my_long_func(count, a=1, b=2):
"""
This is your function that takes a long time
:param count:
:param a:
:param b:
:return:
"""
for i in range(count):
print(i, a, b)
time.sleep(.5)
return 'DONE!'
The result is found in the values
dictionary when the end key is found.
There is a lot of demos of using threads. The idea in this demo is to remove the need for the user to understand threads at all. The only thing that's required is to fill in the lambda as if calling the function and then checking for the event when the function has completed.
PySimpleGUI 2021-07-23T13:08:30Z
Long Operation Capability Pulled into PySimpleGUI
Yesterday I released a Demo Program that had a function to help users start threads for their functions that take a long time.
This morning it's dawned on me (figuratively and literally) that this can be done without ever exposing the user to threads and can be simplified down further so that only the function and the "end of function key" is needed.
Let's look at how it works.
Direct Call
Let's say this is the normal direct call:
Indirect Call
And indirect call is done with this code:
Notice that the exact same line of code appears in the indirect call. The difference is that it's PART of a lambda. Still debating if this syntax is good or bad, but it's at least illustrative that the code is a cut and paste.
Return Value
In the direct call, the return value is directly received. With the indirect method, the return value comes back through the window.read()
call as an event.
Meant for complete beginners
Of course, more advanced Python programmers understand threads, they understand lambdas. But there is a class of PySimpleGUI users that have only just started their Python journey. If they have a function that takes so long that it locks up the GUI, they still need a solution. This new window method gives them that solution, even though they might not grasp how that happens.
What's been amazing about PySimpleGUI has been to see what beginners have done. Given the most primitive of building blocks, sometimes incredibly complex end results are made. I'm hoping this building block allows those early beginners to not have to stop just because they have an operation that is lengthy. That's the purpose of this new capability.
PySimpleGUI 2021-07-23T15:51:01Z
More threading....
This is the image I posted on Twitter (ID is of course @PySimpleGUI) as an explanation of the new Window.perform_long_operation
method.
Not sure what got me onto this problem yesterday other than a decent solution to the classic "my GUI is hanging" problem hit me yesterday afternoon.
PySimpleGUI 2021-07-24T15:06:57Z
Theme-based Cursor Color
On GitHub, and in the next release, is a new automatic setting of the cursor color (the i-beam). I've noted on dark themes, it becomes impossible or very difficult to see the cursor in the elements that allow character entry.
The default is black on tkinter or has been in PySimpleGUI at least. Now it'll match the color of the text in the element. So, if an input element's text is white, the i-beam will be white.
Exampling Using Dark Gray 13
These side by side shots of the test harness demonstrate the difference quite well.
The Element with focus is the Input Text
element. On the 4.45.0 release on the left, the black i-beam is nearly impossible to see. If the background were black as in some themes, the cursor would definitely be completely invisible.
Personally, I like that the window as a whole matches. I hope that users feel the same. It's possible for you to add a call to Element.set_cursor
to change this color. If there is a huge group of upset users, it could be made into an option to disable it. So far I've not had a feature that's been theme-related being that bothersome.
To be honest, I've been shocked, really shocked, that the default theme of PySimpleGUI has been so widely accepted as being OK. There's been no complaints about it. I think I simply got really lucky when choosing those colors as the default. Of course the benefit, just like the benefit of coding conventions, is that they really stand out from a distance. A PySimpleGUI window is quickly identified. Same with the code. Because so many in the community following the naming conventions for sg
, window
, event
, values
it's made reading other people's PySimpleGUI code really easy and it's also made a GitHub / internet "grep" for specific features being used.
Sorry.. back to cursors....
Another example
In this example, the i-beam is also in the Input
element and matches the yellow text color:
On GitHub
As always, you can upgrade to the GitHub version and give it a go.
PySimpleGUI 2021-07-25T10:41:48Z
Adding a Sizegrip
Now that the Sizegrip
element is finally working correctly and will be released in 4.46.0, a couple of suggestions you may find helpful.
Adding a Sizegrip is done by dropping it into the last row of your layout.
I've found it also handy to set the minimum size for your window so that it doesn't get away from you and disappear.
To set the minimum size on a finalized window, add this statement:
If you already have a layout and don't want to dig into the details of it, you can "append" the Sizegrip onto the last row by adding this before creating your Window:
So far these 2 techniques have worked out well.
Here's an example where the All Elements demo has been modified. The sg.Window
creation remained unchanged
# new line to add the Sizegrip
layout[-1].append(sg.Sizegrip())
# The window creation remained unchanged
window = sg.Window('All Elements Demo', layout, right_click_menu=right_click_menu_def, right_click_menu_tearoff=True, grab_anywhere=True, resizable=True, margins=(0,0), use_custom_titlebar=True, finalize=True, keep_on_top=True)
# new line to set the minimum size for the Window
window.set_min_size(window.size)
PySimpleGUI 2021-07-25T23:07:19Z
Delaying the Release by a day.....
Really wanted to get the release posted to PyPI this weekend / today, but since the Mac patch control only just now made it into the code in version 4.45.0.28, it feels a little risky to push up to PyPI this evening.
Mac Patch Control
The last minute addition that's slowed things a little is an addition to the global settings. There's a new Mac Patch Control window that you can get to from the Global Settings window.
There are currently 2 features that are being controlled via these settings. I can't recall if there are others that should be added, another reason to tap the breaks for a day on the release.
As you can see in the window, the 2 settings are:
-
If the no-titlebar patch should be applied
-
If modal windows should be enabled
The defaults are the the modal windows are disabled on the Mac unless enabled and the no-titlebar patch is disabled. These settings mimic the previous release's settings.
Would be swell to get a couple of Mac users to give it a try.
PySimpleGUI 2021-07-28T14:22:49Z
Two "Desktop Widget" related fixes...
In the current GitHub version, 4.45.0.33 there were a couple of changes that will benefit many PySimpleGUI programs, but it will benefit the no-titlebar "Desktop Widget" applications in particular. These are the "Rainmeter" style programs.
Here are a few that are always running on my system:
Grab Anywhere
The movement of the grab anywhere feature is been "OK". It's not perfectly smooth and worked to a satisfactory level.
I dug into this a bit yesterday and found an improvement to the way the movement is done that has resulted in better movement on Windows and on Linux. It's "smoother" is the best way I can put it.
Right Click Menu
The other change was to right click menus. The bind
method has been recently discussed in a couple of issues and I realized that I have been binding the right click button on button down instead of button up. The result is again, a better experience.
Right click menus are particularly useful with these desktop widgets because they often lack buttons. They are meant to be clean, devoid of controls and instead present information. The right click menu is a fantastic way to interact with these programs.
For example, these RAM monitoring programs lack controls:
If you right click either of them, you are presented with the controls... one to edit the program using the globally chosen IDE/editor and the other to exit the program.
Also among the changes in this release are that more areas of the window have the right click menu available. Previously only the elements themselves were right clickable. Now if the Window has a right click menu specified, then all areas of the window are right clickable. There is a limitation in areas that have padding so be aware of that.
Excited about the new release!
I'm excited about 4.46.0 and the new capabilities it adds with the expansion parameters and a number of other features like the threading API call. It was targeted for the weekend, but the Mac is holding things up for a moment. If I can't get past the Mac problems, I'll go ahead and publish the release to PyPI with the known problems.
PySimpleGUI 2021-08-01T22:31:24Z
Aug 2nd - 4.46.0 Target
FINALLY looks like the Mac problems are under control.
The no-titlebar problem is FIXED. The modal windows problem remains for versions that are pre 8.6.10.
Modal Windows
The new Mac Settings in the release turn off modal windows. This feature is still not fixed so it is by default disabled on Macs.
If you're running tkinter 8.6.10+, then you may be able to turn back on Modal Windows and you may not need the no-titlebar patch. Experiment and see what happens.
No Titlebar and Tooltips
FINALLY have a solution for this problem! Tanay gets the credit for finding the problem and for working hard at troubleshooting and running tests. This project is really fortunate to have the help of a number of individuals that have helped PySimpleGUI be what it is. 🙏 Thank you!
Release on Monday
I'm targeting to finish up the testing and pulling together the 4.46.0 release tomorrow. This will give Mac users overnight and tomorrow morning to give the GitHub version a try.
Despite being delayed and struggling through problems, I like this release. It's got a number of fixes and features that I think will result in a good release. I sure hope so or else Jason will get overrun with Issues.
New Issue Field
I'm thinking of adding a spot for you to describe your project. It's an optional thing just like the experience is. Of course, you're not required to provide details about your project in order to get help. I'm fascinated by the incredible diversity of applications that are being made.
There are about 6 to 8 new PySimpleGUI-based public GitHub repos a day that are popping up according to GitHub (which measures using requirements.txt files). Not all of the reported ones use PySimpleGUI, but most do, and not every repo has a requirements.txt file.
Fun - it's meant to be a fun addition..... I hope most users are having fun and not running into too many problems.
PySimpleGUI 2021-08-03T12:28:07Z
Back on 4.46.0
Well, clearly 4.46.0 did not post to PyPI yesterday.
I needed a break. It was a long weekend and this Mac problem has been an exhausting problem among other things. I simply didn't get through testing on all the platforms and all the versions of Python that I do for a release. I stopped early in the day as it was clear I wasn't going to make it.
It's a new day and fresh again and back working on it.
Other Projects (all are PySimpleGUI related)
There are a number of parallel projects that are happening as well. Some of them have been announced, others are not yet posted anywhere. There are times it may appear like no progress at all is being made on anything. An explanation for that is that it may be that nothing that's being publicly shown is making progress. I'm as committed to this project and the user community as much as was in the past 3 years.
It's too much fun and there is too much satisfaction I get from this project to simply stop. Thank you for your patience, support, and kind words. They're incredibly helpful.
PySimpleGUI 2021-08-03T17:29:52Z
4.46.0 Testing ✅ going well.....
Testing done on:
Windows using 3.6, 3.9, 3.10 beta
Linux using 3.8, 3.9
Pi using 3.4
Mac using 3.9
Replit using 3.8
Trinket using 3.6
Of that list, the ones that always make me nervous are the Pi (3.4) and Trinket. If an f-string is left in the PySimpleGUI.py file, then Python 3.4 will immediately crash with a syntax error. It doesn't need to run the code and hit it. The crash happens immediately upon import.
Trinket is tricky because it does not provide a titlebar. A few months ago I added code that automatically adds a custom titlebar if the runtime environment is Trinket. Without that code then all Trinket windows have no titlebar and you can't move them. With the custom titlebar code, the windows appear to users as if they're normal windows. If tkinter code is run then they too don't have titlebars. The reason for this is because the Operating System is responsible for adding the titlebar.
Repl.it was in a similar situation, but they've been adding a titlebar automatically. It's broken at the moment as you cannot move a Repl.it window around using their titlebar. You can move it if using PySimpleGUI's grab anywhere feature or a custom titlebar.
Left to do....
Make a final decision and code changes for the Mac no-titlebar fix. Still working through the defaults, if the Mac feature control window should attempt to use the tkinter detailed version number to set the default and if the setting in the global settings should override all of those checks.
Write release notes
Documentation updates, generation based on the source code, post to readthedocs
Post to PyPI
Celebrate!
PySimpleGUI 2021-08-04T13:50:39Z
Today for sure! (?)
OK, well, version 4.45.0.42 is starting a new round of testing. But first I need to make a decision about his Mac mess and if the code should have some awareness of the version number of tkinter for the Mac. Other than this change, I would like to get this release OUT the door and on PyPI.
I still have another round of testing to do. I got a portion of the call reference updated and have a couple more doc changes to do before generating a new set of readthedocs markdown documents. Every release gets an entirely new set of docs posted as the docstrings do change infrequently and the release notes are part of the documentation as well.
I'm really sorry for all these delays. I know a portion of users use only what's posted to PyPI, so these are very real delays for those users.
The Ripple
Of course, the bigger impact is felt by PySimpleGUIQt users that are being delayed and the other PySimpleGUI projects.
My primary, top priority, is completing the Udemy course. The plan has been that Jason holds down the fort by continuing to provide the amazing support he provides while I focus entirely on Udemy. This plan has fallen apart over the past few weeks, unfortunately.
There are a number of other projects and operational duties that take time away from the visible projects.
Daily Quote
I get a quote a day from an "Inspiring Quotes" email list. One of the few I'm on. I unsubscribed from almost everything last year. I like it because they give you a little backstory in addition to the quote.
Today's was from Einstein.
Logic will get you from A to B. Imagination will take you everywhere.
Born in Germany in 1879, physicist Albert Einstein was a curious, independent thinker from an early age. He worked as a clerk in a Swiss patent office as a young man while developing his groundbreaking theories regarding energy, space, time, and gravity. He excelled in visualizing his ideas and creating new explanations for stubborn scientific mysteries, often going against popular opinion and academic tradition. Instead, he applied his imaginative and analytical powers to many complex topics, including time travel, black holes, and atomic energy. Einstein’s studies earned him a Nobel Prize for Physics in 1921, and his work continues to demonstrate the enormous potential of an inquisitive and flexible mind.
Quote for this release....
Quotes fuel me and I draw energy from them. These short ideas and phrases are SIMPLE and I find them to be incredibly motivating as well as comforting. It depends on who's being quoted. When it seems like everything's stuck, I'm reminded by Confusious
“It does not matter how slowly you go as long as you do not stop.”
It'll all work out in the end as it has since the project started. We don't always end up where we initially planned, but where were end up isn't a terrible place.
PySimpleGUI 2021-08-05T13:48:16Z
Retest and the continuing with the release
There have been enough changes to the code yesterday to warrant a complete retest of the release. Not fun, but it's required in this case. I don't feel comfortable making changes that impact every window created.
At some point soon I'm going to simply stop making changes and live with the known problems as they are. Otherwise, the slips to all of the other projects are going to be really out of control. (See discussion above about the ripple effect that's happening).
Additional Linux Information For Issues
I'm investigating exactly what additional information is needed for Issues logged for Linux. I don't yet have a handle on all of the variables involved, but it's clear to me that I'm missing information that would enable me to duplicate problems that a user sees. There is more happening than just the distribution and the version number of Python, tkinter and PySimpleGUI.
It's unclear to me how many virtual machines I'll need in order to duplicate problems and am working with a friend to help me determine what the combination of the components will be which will help inform the decision about what added information is needed.
PySimpleGUI 2021-08-06T18:05:55Z
Another weekend try....
There are a couple more fixes I am shooting to get into the code and then get everything tested again and possibly released to PyPI this weekend.
Here are the release notes so far for what will be 4.46.0
-
Multiline.print & cprint
-
Added autoscroll parameter - defaults to True (backward compatible)
-
will now take a single color and use as text color
-
-
ButtonMenu
-
use font for button as menu font if none is supplied
-
fixed mutible problem - makes a copy of menu definition when making ButtonMenu
-
made menu definition optional so can change only some other settings
-
-
Mac
-
New window added to control the patches and feature disables. Access by calling main_mac_feature_control or through the global settings window from main()
-
Disables grab anywhere if a titlebar is present
-
Right click menu bound to Button2 which is the right button on a Mac (Button3 for all other systems)
-
FINALLY found the no-titlebar problem - weird tkinter bug. Can't set alpha channel while making window if no titlebar on * Mac (credit to Tanay for this find!!)
-
Allowed Modal windows again
-
Will not try to apply no titlebar patch if tkinter version >= 8.6.10 regardless of user settings
-
Disable the alpha chan to zero if the no titlebar patch is set on the Mac. Will see the window move to center of screen for these windows.
-
Added no-titlebar batch to toolore neetips
-
-
Fixed problem with titles on some Linux systems - set class_ for Toplevel windows
-
Menu defintion bug fix - when menu shortcut char in first pos and item is disabled !&Item
-
Sizegrip - fixed expansion problem
-
Added kill application button to error popup
-
one_line_progress_meter
-
keep_on_top parameter added
-
no_button parameter added so that no cancel button is shown
-
-
Deprication warning added to FindElement as first step of moving out of non-PEP8 world,
-
Added TabGroup.add_tab to add new tab to TabGroup at runtime
-
execute_py_file
-
set cwd='.' if dir not found
-
check for file exists
-
-
Right click menu
-
added to Radio Checkbox Tabgroup Spin Slider
-
Elements that don't have a right_click_menu parm now pick up the default from the Window
-
Added a right click menu callback to cover portions of the window that don't have an element on them
-
Changed Button binding for Mac to Button2 (the right button rather than middle on the other systems)
-
Made right click menus based on button release (MUCH better)
-
-
docstrings
-
Reformatted all docstrings to line up the desriptions for better readability
-
Added type and rtype to docstrings that were missing any entries
-
Updated all font entires in docstrings to include list as well as string
-
-
Added stderr to Debug print if rerouting stdout
-
expand_x and expand_y now in the constructor of all elements. No longer need to call Element.expand after finalizing window if using these.
-
Added Window.perform_long_operation to automatically run users functions as threads
-
Fixed Text.get() was returning not the latest value when set by another element
-
Set cursor color to the same as the text color for Input Combo Spin Multiline Output
-
Added echo_stdout to debug print so that stdout can be captured when run as a subprocess
-
Addition of autosave parameter for UserSettings
-
Test harness
-
Made progress meter shorter so that the test harness fit better on smaller screens (a constant battle)
-
Compacted Test Harness significantly so it's 690x670
-
-
Added Sizegrip to Debug Window
-
New Grab Anywhere move code
-
Move all windows at the same timed if using grab_anywhere (experimental) (set Window._move_all_windows = True)
-
Table element - set the headers to stretch if expand_x is True
-
Element.set_size - if Graph element then also set the member variable CanvasSize
-
added exception details when making window with 0 alpha
-
Check for no color setting when setting the cursor color for inputs (must test for gray gray gray theme in the future regression tests)
PySimpleGUI 2021-08-08T00:21:10Z
Thank you!
This PySimpleGUI thing, the software, the demos, the documentation, the support, is a single unit. It's all tied together and parts depend on other parts. The thing that holds it all together is people. We're all working together to make this PySimpleGUI experiment function in the end.
For me personally, being thankful, having gratitude, is an important thing. However, I try not to have the project be about me. It's about the users and their success. They're the important people. And the individuals that are helping to make others successful are also important.
I would like to take a moment to thank @jason990420 , @nachocho, @Chr0nicT, @israel-dryer, @driscollis, @nngogol , @readicculus, @Mysterious-Owl for their recent support. If I took a few more minutes I'm sure I could come up with a dozen more. So many people have been a part of what's make PySimpleGUI what it is. It's been a group effort. And sometimes it's an individual effort, where an individual really goes out of their way to do something, say something, find something, write something, that has a positive and lasting impact.
I'm in awe at what people build. It's truly stunning to see so many interesting projects. It's very easy to be excited to work on this project when there is so much imagination and creativity being demonstrated every day. It's thrilling to see screenshots. I know the feeling when something finally works and a screenshot is a representation of someone's success. I know that user experienced the fun of having their program work.
Thank you all so much for making this experience what it is.
PySimpleGUI 2021-08-10T11:32:12Z
Hey... look over there at the shiny thing... the User Setting APIs
Working on that release thing.
In the meantime, check out an interesting demo where the window saves its position before exiting. Then when you run the program again, it will start at the last position it was in.
I've found this to be really handy in the desktop widgets. Many of them had a "Save location" item on the right-click menu. It hit me yesterday... if I save the location of the window as a user setting, then it's easy to do this. All I have to do is add 1 line of code to add to the settings file.
If you haven't seen this API, the tldr.. User Settings are JSON files located in your OS's program settings folder under a PySimpleGUI folder. If you don't set a filename for your program's settings file, then the name of the .py file is used.
Note that settings files auto-save. If you make a change, it'll be saved.
The APIs are much like a dictionary. If you use the object interface, then you can use the [ ]
syntax.
One new demo shows one way to go about this. There is one additional line of code from a normal window. The added statement is the write of the window position to the settings file.
import PySimpleGUI as sg
layout = [[sg.Text('Window that Auto-saves position', font='_ 25')],
[sg.Button('Ok'), sg.Button('Exit')]]
window = sg.Window('Auto-saves Location', layout, enable_close_attempted_event=True, location=sg.user_settings_get_entry('-position-', (None, None)))
while True:
event, values = window.read()
print(event, values)
if event in ('Exit', sg.WINDOW_CLOSE_ATTEMPTED_EVENT):
sg.user_settings_set_entry('-position-', window.current_location()) # The line of code to save the position before exiting
break
window.close()
PySimpleGUI 2021-08-10T21:42:52Z
4.46.0 PySimpleGUI 10-Aug-2021
McRelease - Lots of Mac changes including new Mac patch control panel in global settings
expand_x, expand_y in the constructors
docstrings reformatted
Text Elements really autosize now
-
Multiline.print & cprint
-
- Added autoscroll parameter - defaults to True (backward compatible)
-
- will now take a single color and use as text color
-
Text element - autosize with size of None, None creates an expanding Label widget with size and width of None and wraplen=0 (truely autosizing it appears!),
-
ButtonMenu
-
- use font for button as menu font if none is supplied
-
- fixed mutible problem - makes a copy of menu definition when making ButtonMenu
-
- made menu definition optional so can change only some other settings
-
Mac
-
- New window added to control the patches and feature disables. Access by calling main_mac_feature_control or through the global settings window from main()
-
- Disables grab anywhere if a titlebar is present
-
- Right click menu bound to Button2 which is the right button on a Mac (Button3 for all other systems)
-
- FINALLY found the no-titlebar problem - weird tkinter bug. Can't set alpha channel while making window if no titlebar on Mac (credit to Tanay for this find!!)
-
- Allowed Modal windows again
-
- Will not try to apply no titlebar patch if tkinter version >= 8.6.10 regardless of user settings
-
- Disable the alpha chan to zero if the no titlebar patch is set on the Mac. Will see the window move to center of screen for these windows.
-
- Added no-titlebar batch to toolore neetips
-
Fixed problem with titles on some Linux systems - set class_ for Toplevel windows
-
Menu defintion bug fix - when menu shortcut char in first pos and item is disabled !&Item
-
Sizegrip - fixed expansion problem
-
Added kill application button to error popup
-
one_line_progress_meter
-
- keep_on_top parameter added
-
- no_button parameter added so that no cancel button is shown
-
Deprication warning added to FindElement as first step of moving out of non-PEP8 world,
-
Added TabGroup.add_tab to add new tab to TabGroup at runtime
-
execute_py_file
-
- set cwd='.' if dir not found
-
- check for file exists
-
Right click menu
-
- added to Radio Checkbox Tabgroup Spin Slider
-
- Elements that don't have a right_click_menu parm now pick up the default from the Window
-
- Added a right click menu callback to cover portions of the window that don't have an element on them
-
- Changed Button binding for Mac to Button2 (the right button rather than middle on the other systems)
-
- Made right click menus based on button release (MUCH better)
-
docstrings
-
- Reformatted all docstrings to line up the desriptions for better readability
-
- Added type and rtype to docstrings that were missing any entries
-
- Updated all font entires in docstrings to include list as well as string
-
Added stderr to Debug print if rerouting stdout
-
expand_x and expand_y now in the constructor of all elements. No longer need to call Element.expand after finalizing window if using these.
-
Added Window.perform_long_operation to automatically run users functions as threads
-
Fixed Text.get() was returning not the latest value when set by another element
-
Set cursor color to the same as the text color for Input Combo Spin Multiline Output
-
Added echo_stdout to debug print so that stdout can be captured when run as a subprocess
-
Addition of autosave parameter for UserSettings
-
Test harness
-
- Made progress meter shorter so that the test harness fit better on smaller screens (a constant battle)
-
- Compacted Test Harness significantly so it's 690x670
-
Added Sizegrip to Debug Window
-
New Grab Anywhere move code
-
Move all windows at the same timed if using grab_anywhere (experimental) (set Window._move_all_windows = True)
-
Table element - set the headers to stretch if expand_x is True
-
Element.set_size - if Graph element then also set the member variable CanvasSize
-
added exception details when making window with 0 alpha
-
Check for no color setting when setting the cursor color for inputs (must test for gray gray gray theme in the future regression tests)
-
Added exception details if have a problem with the wm_overriderediect
-
Addition of "project information" to the issue - your opportunity to share something about what you're making
PySimpleGUI 2021-08-11T18:30:37Z
The Lego Analogy
I forget to copy them here, but I try to copy the Tweets I made here in the Announcements since not everyone is on Twitter.
I wanted to share a couple of thoughts with the Twitter Universe.
One is a popular notion that PySimpleGUI is only good for "Simple Applications". I've known from the start that this is simply not true. It's a misconception that may stick around forever which is fine. I just want to make sure that some counterbalancing is happening.
The other is to show off the incredible work the users are putting into their GUIs
The point of the Tweet is that if you're writing a review of PySimpleGUI and all you build is something simple, then it's neither correct nor "fair" (if I want to complain about it) to then conclude "PySimpleGUI is only capable of making simple applications".
If you don't have immense amounts of education and experience, you have to try to find out what's possible with technology.
The Unexpected Conclusion
One thing I've loved about this project is the excitement of seeing where it goes next. It was never meant to exist to begin with, so just "being" was a complete change of plans. I've never had any desire to make an open source project. But, yet, here I am in the middle of this PySimpleGUI mess, and having a dream that I never knew about come true. Is it a "dream come true" if you don't have the initial dream?
Sorry... back to the conclusion
If given simple, but complete, tools, then users can create incredibly complex results.
The PySimpleGUI Elements are exactly what they sound like.... they're ATOMS. And, with these atoms, an incredible number of very different molecules can be built.
Because PySimpleGUI Elements are easy to combine, users that have the creativity and the time have come up with STUNNING applications. I'm frequently blown away. This isn't an exaggeration on my part. I'm truly stunned when I see these programs.
The First Example Was...
Something "clicked" in my brain when I saw this image and I learned that the creator, @neovich , doesn't have "Software Engineer" in their title. Up to this point, I was already being blown away by the screenshots and things that users of all levels have been posting. There was something unique about this image that triggered this epiphany.
And from yesterday's Tweet
What a beautiful window!
Stunning, brilliant, creative, inspirational, motivating, ......
I can easily list the many positive impacts that your creations have, not just on me, but on the world as a whole.
I loved the backstory from @AyhamSaffar
It finds the average grain size in a microscope image.
I always wanted to make this app ever since we did this process manually in a lab. I am so lucky i stumbled across a PySimpleGUI video on my youtube and realised it was actually possible!
I am so grateful for the library and all the support. Mike & Jason u guys are amazing.
Cant wait to show this off when i get back to uni!
Thank you!
I'm so incredibly thankful and fortunate to be experiencing all these things that everyone is doing and creating. In a world where there seems to be a lot of negativity, the PySimpleGUI world I experience is one filled with inspiration, hope, joy, and excitement. Thank you everyone for making that happen. It's a group effort.
PySimpleGUI 2021-08-14T13:43:15Z
Watcha Makin?
I'm SO EXCITED!
Maybe I say that a lot, but it's because I get excited a lot... honestly excited!
The 2 newest Issues posted both say something about what the person reporting the issue is making! Oh, this is going to be so much fun! I don't know why some things like this simple question motivate me the way they do, I just know they do. It's so much FUN to hear about your projects!
3,000 Repos Today
I saw this morning that the number of repos that GitHub is reporting as using PySimpleGUI crossed the 3,000 mark!
All stats are off in their own ways. I'm sure not all of these are valid projects to be counted as being PySimpleGUI projects. But there are also none of the Qt, Wx and Web ports that are in that number.,
It's just a number... but it tells me that people are using PySimpleGUI. This makes it more than a number for me personally. It's a thrill! It's got joy attached to it.
Enabling Technology
Being an enabling bit of technology means that I get the pleasure of giving the users a little boost... and then seeing what the outcome of that little boost is. It's often really shocking, in multiple ways. Sometimes it's shocking in the complexity of what's built, that's an obvious one to count. But other times it's shocking in the gratitude users show. Or the imagination they show.
Teaching a 12 Year Old to Code GUIs
I had a conversation with a Python expert, instructor, etc... someone I really respect and look up to. My theory is that kids, quite young kids, can code in Python AND they can code GUIs too. Our opinions differed and that's fine... that's great sometimes. I am not looking for friends that are clones of me... I've got a mirror if I want that and I talk to myself all day long anyway.
How About a 12 Year Old Teaching You to Code GUIs??
I ran into a video yesterday that was a real mind-blowing video. Is it obvious that I'm having the time of my life on this project??
This video answered the question, very quickly, if a young person can code in Python and can on top of that code GUIs.
https://youtu.be/Z2AKGjc8bqk
Speechless (for a change)
PySimpleGUI 2021-08-17T15:01:08Z
Officially Stepping Away From Issues for a Bit
You all already know that Jason kicks my ass in support, daily, so it's not like I'm banding the amazing group of people known as PySimpleGUI users.
There are 2 really important publicly visible projects that are soaking up my time for the coming weeks.
In case there are questions about what I view as the primary priorities on my plate at the moment:
-
The PySimpleGUIQt Alpha - I'm FINALLY able to place this in THE number 1 priority spot. More will be posted about joining the Alpha, so watch the announcements for this.
-
The Udemy Course
-
The Docs - Mulitple updates are in progress
-
Several not yet public "side projects and features".
-
Some of these I was directly involved in, some not up much
-
A PSG designer
-
A new web capability
-
Bringing new help up to speed - It's been a long time coming. Finally found an admin to help.
That's all that comes to mind right now. Priorities change of course, but these are the big ones.
We've been here before. There were a few months where I was able to step away from the issues and focus on Udemy. It worked out well. I made lots of progress and the Issues were handled really well.
Thank you for the support! I can't express, in words, just how much the encouragement has helped. The kind words I see in the Issues, Twitter, and YouTube are so helpful. They really are seen and they really do fuel this project.
The donations help too! Still very much in the red... like really a deep red, but I've got faith that in the long run this will change. In the short term, anything helps. Seriously, anything helps. You can see in BuyMeACoffee just how much is "rolling in". It's tens of dollars and very much appreciated. It adds up, sorta. Not sure how to say a huge thank you while communicating that I'm struggling.
Anyway, I'll be around, just now at much.
PySimpleGUI 2021-08-26T18:42:40Z
PySimpleGUIQt Alpha IS COMING SOON... HONEST!
Still working hard on this Alpha. Your guest host for this release of 1.0 of PySimpleGUIQt will be @nngogol , who I have been working with for years and has been preparing the Alpha.
Udemy Triggers Changes - to Image
element this time
You can sometimes get a hint as to what I'm writing for Udemy based on the changes being checked in.
The Image element got a new initial parameter, source
.
This change is written so that it's 100% backward compatible. I know a number of people (me included most likely) that assume the first parameter to the Image
element creation and update
is filename
.
The NEW parameter is called source
and it can be EITHER a filename
or a base64
byte string (indicated with the data
parameter normally).
The result is that this code:
[sg.Image(data=sg.EMOJI_BASE64_HAPPY_BIG_SMILE, key='-IMAGE2-')],
[sg.Image(filename=r'C:\Python\PycharmProjects\PSG\Logos\logo200.png', k='-IMAGE3-')],
Can be simplified to:
[sg.Image(sg.EMOJI_BASE64_HAPPY_BIG_SMILE, key='-IMAGE2-')],
[sg.Image(r'C:\Python\PycharmProjects\PSG\Logos\logo200.png', k='-IMAGE3-')],
No need for any parameter naming now.
class Image(Element):
"""
Image Element - show an image in the window. Should be a GIF or a PNG only
"""
def __init__(self, source=None, filename=None, data=None, background_color=None, size=(None, None), s=(None, None), pad=None, key=None, k=None, tooltip=None,
right_click_menu=None, expand_x=False, expand_y=False, visible=True, enable_events=False, metadata=None):
"""
:param source: A filename or a base64 bytes. Will automatically detect the type and fill in filename or data for you.
:type source: str | bytes | None
:param filename: image filename if there is a button image. GIFs and PNGs only.
:type filename: str | None
:param data: Raw or Base64 representation of the image to put on button. Choose either filename or data
:type data: bytes | str | None
NEW size
parameter setting
This one is going to have a big effect on also simplifying down the code.
How many times have we written?
Or any size with a height of 1.
With the change checked in with 4.46.0.10, both the size
and the alias s
parameter can take an INT as a parameter in addition to a tuple.
If an int is specified, the it's assume the height should be (int, 1)
It saves 3 characters on every element that has a size.
And the shortest version
They produce identical results.
I want to get a bunch of these new things released to PyPI sooner than later so I can start using them in code.
Thank you for the many "thank you" messages I see!
I write them down. They carry weight so thank you for posting them, sending them, tweeting them.
PySimpleGUI 2021-08-26T21:49:02Z
New "Tagline"
Saw on Twitter this morning:
PySimpleGUI
Makes GUI Programming Fun Again (For The Very First Time)
It's funny, but could be a little bit offensive to all those amazing GUI framework writers out there that have worked hard for many years.
I DO like hearing a user state that it's made GUI programming fun for them.
The same user set a challenge for himself to recreate a GUI from another project in a shorter amount of code. It took me a few minutes to make the GUI in 9 lines. You can also do it in 2 lines if you're willing to put the layout into the Window creation, but that feels a bit like cheating.
import PySimpleGUI as sg
layout = [ [sg.T('Serial Port', s=13), sg.OptionMenu(('COM1', 'COM2'), k='-SERIAL-', s=10)],
[sg.T('Waveform', s=13), sg.OptionMenu(('Sign', 'Square', 'Triangle'), k='-WAVEFORM-', s=10), sg.B('Set Waveform')],
[sg.T('Freuquency (Hz)', s=13), sg.I(s=15), sg.B('Set Freq0'), sg.B('Set Freq1', disabled=True)],
[sg.T('Phase (deg)', s=13), sg.I(s=15), sg.B('Set Phase0'), sg.B('Set Phrse1', disabled=True)],
[sg.Frame('Output Mode', [[sg.R('Waveform', 1, True, k='-RADIO WAVE FORM', s=15)], [sg.R('Modulation', 1, False, k='-RADIO MODULATION', s=15)]])]]
sg.Window('bFunc Control', layout, default_button_element_size=(10, 1), auto_size_buttons=False, element_padding=(0,0)).read(close=True)
This is the original window:
If I use the gray gray gray
theme, I get a similar look:
And if you don't use padding = (0,0), then it looks like this:
PySimpleGUI 2021-08-27T22:55:43Z
Shortcut & New GitHub Upgrade Weekend
Going to release 4.47.0 this weekend.
It's not a HUGE release in terms of the amount of code changed, but the changes are significant.
Changelog
Changelog since 4.46.0 release to PyPI on 10 Aug 2021
4.46.0.1
Added rstrip parm to Multiline element
4.46.0.2
Combo.update - fixed bug added in 4.45.0 with disabled not working correctly when calling update
4.46.0.3
Changed font type in all docstrings to be (str or (str, int[, str]) or None) (thank you Jason!!)
4.46.0.4
Added code from Jason (slightly modified) for _fixed_map
4.46.0.5
Fix for default element size - was incorrectly using as the default for parm in Window.
Needed to set it in the init code rather than using the parm to set it.
4.46.0.6
Window.ation gets a new parm - more_accurate (defaults to False). If True, uses window's geometry
4.46.0.7
Added Window.keep_on_top_set and Window.keep_on_top_clear. Makes window behave like was set when creating Window
4.46.0.8
Added new constant BLANK_BASE64 that essentlly erases an Image element if assigned to it. It's 1x1 pixel and Alpha=0
4.46.0.9
Image element - New source parameter as the first parm. Can be a string or a bytestring. Backwards compatible because first was filename.
Works for both the init and the update. No need to specify any name at all... just pass in the thing you want to change to.
4.46.0.10
Element sizes, when being created, can be an int. If size=int, then it represents a size of (int, 1). GREATLY shortens layouts.
Sometimes this these things only become apparent later even though it seems obvious
4.46.0.11
Another tuple / int convenience change. Tired of typing pad=(0,0)? Yea, me too. Now we can type pad=0.
If an int is specified instead of a typle, then a tuple will be created to be same as the int ---> (int, int)
4.46.0.12
Add NEW upgrade from GitHub code. Thank you @israel-dryer!
Fix for Image.update docstring
Major changes are the size
and pad
parm change and the GitHub upgrade
I'm really into these new 1-dimensions size and pad parms. They're saving a TON of typing
Also, The new GitHub upgrade, written by the brilliant @israel-dryer is in this one. I've made it threaded in addition to his subprocess. The result is a nice, smooth output of the progress. Hopefuly not allowing the window to be closed until the operation is complete won't be a problem.... If you want to be a help testing, download from GitHub and then download it again so that you get the new upgrade code.
PySimpleGUI 2021-08-29T18:46:28Z
4.47.0 is right around the corner!
Just putting the finishing touches on the release. I really want to get Israel's new GitHub upgrade code into this release.
I'm excited about this release! Hmmm.... I guess I'm excited about all releases come to think of it.
It's the changes the simplify and cut down the work required that impacts a lot of users that really get me the most excited. This release has a number of those.
pad
and size
as ints
Both the pad
and size
parameters can be an int instead of a tuple. If you're entering in a bunch of sizes, it will cut down how much you type considerably., Same thing with pad=(0,0) in particular.
The Stretch
Element
Maybe the most impressive bit of luck was discovering the Stretch
element that's been SO helpful in the PySimpleGUIQt port works in the tkinter port when I simulated the effects using the new expand_x
parameter on a Text Element. IT feels like some of the things that happen in software aren't designed but rather they're discovered. That's how science works, often, right? There are discoveries rather than inventions.
Being able to right justify a single button on a row by writing a layout feels like how PySimpleGUI should be:
Previously it has more difficult and required Column elements, etc.
Centering a Button
is accomplished by adding a Stretch
on each side of a Button
AND, this is now portable code. Runs on PySimpleGUIQt without changes.
Why I Write and Read PySimpleGUI Programs
Fun
I write a lot of programs using PySimpleGUI for a variety of reasons. Maybe I should admit that one of the big reasons is that it's FUN. Being able to knock out a GUI in 9 lines that required 200 lines using another GUI framework is really gratifying because i know that I'm saving people a lot of time., That's time they can use for something else.
Tools
I also get to make my own tools for the first time. I've never been a GUI programmer in the past. I've made products but they didn't involve graphical user interfaces created by me. I was a system software person. I provided the APIs that the folks making the visual interfaces could use to paint pixels on the screen. I gave them frame buffers. The last time I Wrote dev tools for myself was in the 1980's when we were running Unix.
Education
Finally, I write them both as part of making the educational courses but also to help educate myself to where the pain is felt. It's helped me in the past get out ahead of other users. I'm able to find where the soft spots are, or gauge if something new is needed.
The User SEttings and the Execute API calls came out of this kind of effort. I noticed that almost all of my little programs needed to have settings. And, more and more of my programs were launching other programs.
Because launching programs and saving settings are so common with GUIs, I decided this year to add a couple more areas to simplify like PySimpleGUI simplified GUIs, there was an opportunity to simplify related components.
PySimpleGUI 2021-08-29T23:26:27Z
Troubles with Upgrade from GitHub features....
I'm sorry for the recent series of problems with upgrading from GitHub.
Trying to new method that's more standardized that utilizes pip.
It appears that at the moment, the version that is checked into GitHub is causing a bad __initi__.py
file to be generated. It's happening on my Windows 10 system. If it happens to you, then you can manually fix it by adding this code to a file named __initi__.py
that will be in your PySimpleGUI folder in your python/Lib/site-packages/PySimpleGUI folder.
You will need to add this code:
Stretch()
Element Goes Vertical!
A NEW element was added to aid in performing the same kind of "Stretch" operation except vertically instead of horizontally. To make it unique and stand out, it's called the VStretch
element.
By using the VStretch
, you'll be able to center things vertically by placing one of these on rows above and below the thing you want to center.
Stretch in action...
This code:
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Button('Go'), sg.Button('Exit')] ]
new_layout = [[sg.VStretch()],
[sg.Stretch(), sg.Col(layout), sg.Stretch()],
[sg.VStretch()]]
window = sg.Window('Window Title', new_layout, resizable=True)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
All I've done is taken a normal layout and surrounded it to Stretch Elements.
Initially produces this normal looking window:
If you grab a corner and enlarge the window, then what you'll find is the layout has been centered in the window.
All of the previously available justification options are still available to you. But now there's this additional one. I think this is going to be a LOT easier to work with. If you want something to be right-justified, simply toss a Stretch
element to the left of it.
PySimpleGUI 2021-08-30T19:32:22Z
4.47.0 PySimpleGUI 30-Aug-2021
Stretch & VStretch - A new era of element alignment!
Upgrade from GitHub - uses pip for real now
Image element - Simpler to use
size
and pad
parms can be ints in addition to tuples to speed up coding
-
rstrip
parm added toMultiline
element -
Combo.update
fixed bug added in 4.45.0 with disabled not working correctly when calling update -
Changed font type in all docstrings to be (str or (str, int[, str]) or None) (thank you Jason!!)
-
Added code from Jason (slightly modified) for _fixed_map
-
Fix for default element size was incorrectly using as the default for parm in Window.
- Needed to set it in the init code rather than using the parm to set it.
-
Window.location
gets a new parmmore_accurate
(defaults toFalse
). IfTrue
, uses window's geometry -
Added
Window.keep_on_top_set
andWindow.keep_on_top_clear
. Makes window behave like was set when creating Window -
Image Element
-
Added new constant
BLANK_BASE64
that essentially erases an Image element if assigned to it. It's 1x1 pixel and Alpha=0 -
Image element New
source
parameter as the first parm.-
Can be a string or a bytestring. Backwards compatible because first was filename.
-
Works for both the init and the update. No need to specify any name at all... just pass in the thing you want to change to. Greatly shortens code.
-
Ths idea is to not have to specify the parameter name.
sg.Image('filename')
andsg.Image(base64)
both work without using any parameter names.
-
-
Fix for
Image.update
docstring
-
-
Element sizes, when being created, can be an int. If
size=int
, then it represents asize=(int, 1)
. GREATLY shortens layouts.- Sometimes this these things only become apparent later even though it seems obvious
-
padding - Another tuple / int convenience change.
-
Tired of typing
pad=(0,0)
? Yea, me too. Now we can typepad=0
. -
If an int is specified instead of a tuple, then a tuple will be created to be same as the int.
pad=0
is the same aspad=(0,0)
-
-
Add NEW upgrade from GitHub code. Thank you @israel-dryer!
-
Change in ttk style naming to ensure more unique style names are used
-
Cast key to string when making a ttk style
-
Added
"___"
between unique counter and user's key when making a unique style string for ttk widgets. Fixed problem with elements from one window interfering with another window elements -
Changed Upgrade From GitHub Code
-
When upgrading, use the interpreter from the global settings for the upgrade! This could get tricky, but trying to make it logical
-
Output of the pip command shown in an upgrade window using a
Multiline
element so errors can be copied from it. -
Added printing of the value of
sys.executable
to the upgrade information
-
-
Stretch
andVStretch
Elements - a promising solution to element justification!-
Redefinition of the
Stretch
element. No longer returns an Error Element. It now returns a Text element that does the same kind of operation as the PySimpleGUIQt'sStretch
element! Very nice! -
VStretch
stretches vertically instead of horizontally
-
-
UserSettings APIs
- Changed the repr method of the user settings object to use the pretty printer to format the dictionary information into a nicer string
PySimpleGUI 2021-09-01T13:14:48Z
4.47.0 out.... really am going to try to stay away from support for a bit....
I have to focus on Udemy and it's SO easy for me to get back into reading issues and trying to help. Jason MORE than has this handled and has told me numerous times to go AWAY already and focus. So, it's all on me for making the mistakes I've been making in not focusing. Some things take time.
This morning I received a reminder...
No one is perfect.
This was from a friend that I was expressing remorse about how the person was treated online. It felt unfair to me. Rather than agreeing, or acting like a victim, their response was one of understanding, forgiveness, and a lesson right back at me to remember this too.
The result of the focus away from support is no doubt going to be that some of the issues are going to be related in fixing.
Qt Issues - Qt Alpha
Every day time is being spent on the PySimpleGUIQt Alpha and getting it out. Again, I'm sorry for the delay.
Thank you * 1_000_000
I get a lot of thank you emails, I see the messages included in the Issues being filed, and they are SO appreciated.
Gratitude is a big deal for me. Every morning I make a list of 3 things I'm thankful for. Jason is on that list a lot 😉 and so are the PySimpleGUI users. You guys and gals are the reason it's here and what I work for. This experience, the incredible gratitude I witness so many users expressing, having a rare vantage point where I get to see people falling in love with programming, and the overall vibe of positivity and pride of accomplishment is SO unique in my experiences of life until now.
FAR FAR from perfect
Circling back to the reminder I received, "No one is perfect". I tell the kids I mentor, often, that I make mistakes. I make a lot of them. I have terrible ideas too. But, mixed in there are some good actions, some great ideas. To make no mistakes means not doing anything at all.... at least for me.
The goals for this project
-
Fun
-
The User's Success
continue to be my focus. The programming field has become more and more extreme in teaching that there's only 1 way to do something. I believe this sucks the creativity right out of programmers.
There is No Best....
Just like there's no best GUI framework, there is no best way to code.
Some programs are not meant to be maintained. Some are never going to be extended. Some are meant to solve one problem, right now, and that's it. There are SO many variables in programming, including these maintenance and extendability ones. Take them all into consideration when you start your program and choose your languages, tools, libraries, etc.
There's the best we can do for the problem at hand.
See you soon..
And, with that, I'm off to do the best job I can at teaching PySimpleGUI. Thank you all for making this the experience of a lifetime.
PySimpleGUI 2021-09-01T13:24:09Z
Oh oh! ONE more funny thing
An artist friend sent me this representation of "Getting over the Python GUI Bar"... or "What happens when the bar is so low you can step over it?"
PySimpleGUI 2021-09-10T13:37:27Z
@jason990420 Appreciation Day!
SO much about this project has felt like good fortune pours from the sky onto me and the project. Jason is an excellent example of this. There was a 2 month period when Jason arrived along with several other people that have become some of my closest friends. A group of at least 4 that I can think of all arrived together in that group despite not knowing each other.
I wouldn't have dreamed of a better support engineer. I don't believe I could have even written a job description that encompasses all the things Jason does for us, and the way he does them.
I'll admit it.... he does support better than I do. I thought I do a pretty good job with support, but time and time and time again Jason comes through and saves people.
1,674 closed issues. That's more than 1 closed issue a day for the entire duration 3+ years on GitHub and the majority of those Jason fixed the situation. Even the currently open 691 issues have been addressed in some manner. That means 2,365 issues have been worked on, just here on GitHub.
Countless projects have gone from stopped, to back moving again and on to completion thanks to his constant effort. I swear he's a group of people. Somehow, and I seriously don't get how, but somehow he's answering questions over on StackOverflow in addition to answering them here. He cares so much about our users being successful that he's willing to go where they are.
There is no way I would be able to feel comfortable stopping working on support issues without knowing that Jason's got it covered. I never ever have to worry about how an issue that's posted will be handled by Jason. It'll be done right, with a great workaround, an honest answer, and in a courteous way.
He's THE face of PySimpleGUI when it comes to support. I couldn't have found a more perfect fit if I looked. Thankfully, I didn't have to. He just showed up.
I'm also really thankful that the PySimpleGUI user community is kind to @jason990420. It's clear he wants people to be successful and is patiently doing his absolute best to help. So many of you say 'thank you' directly to Jason. 💖 it! Really fortunate to have users like we've got and the world's best support engineer.
PySimpleGUI 2021-09-13T23:33:52Z
Quick Update
Stopped in for just a moment today. Jason, as usual, has the issues will under control while I'm off working on the Qt Alpha and Udemy... (Honest Jason, I'm not working issues, just peeking rarely). I met over the weekend on the Qt Alpha. I know this is taking forever, but it's being worked hard. There is a lot of effort, days, nights, weekends, going into it. I hope everyone's happy with it in the end. Time will tell. I'll certainly be posting the invite info when things are ready to open up for some wanting to give it a try.
Stretch
---> Push
---> P
The Stretch
element was initially introduced in the PySimpleGUIQt port as it's a Qt Widget concept.
With the recent addition of the expand_x
and expand_y
parms on elements, I saw an opportunity to implement something that acted much like this Stretch
element. And, it's turning out to be pretty handy.
Like many PySimpleGUI concepts, there are aliases. I will likely be calling this element the Push
in the future and will also add an alias on the PySimpleGUIQt port.
Lining Up Text and Inputs
So often there are the most simple of windows where you have a text label and a series of inputs. For complete beginners, they look like this:
I've seen a number of articles and tutorials with misaligned Inputs. I know it takes effort to add a size to the Text elements, but it's not that difficult.
Adding Size
If adding a size to the Text elements, you can get something like this:
layout = [ [sg.Text('My Window')],
[sg.T('Name', s=(15,1)), sg.Input(key='-NAME-')],
[sg.T('Address', s=(15,1)), sg.Input(key='-ADDRESS-')],
[sg.T('Phone', s=(15,1)), sg.Input(key='-PHONE-')],
[sg.T('Home Email Address', s=(15,1)), sg.Input(key='-EMAIL-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout).read(close=True)
And in 4.47.0 the size
parm can be an int so it can be further shortened to this:
layout = [ [sg.Text('My Window')],
[sg.T('Name', s=15), sg.Input(key='-NAME-')],
[sg.T('Address', s=15), sg.Input(key='-ADDRESS-')],
[sg.T('Phone', s=15), sg.Input(key='-PHONE-')],
[sg.T('Home Email Address', s=15), sg.Input(key='-EMAIL-')],
[sg.Button('Go'), sg.Button('Exit')] ]
The User Defined Element Way
That's the kind of construct I've used in the past and it's worked well. The drawback is when you're adding something that's longer and need to renumber multiple lines. That's when I drop into a "User Defined Element" and thus have only 1 place to make the change. Here's what I mean by using a User Defined Element (you'll find them discussed in the docs).
def Line(text, key):
return [sg.T(text), sg.Push(), sg.Input(key=key)]
layout = [ [sg.Text('My Window')],
Line('Name', '-NAME-'),
Line('Address', '-ADDRESS-'),
Line('Phone', '-PHONE-'),
Line('Home Email Address', '-EMAIL-'),
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout).read(close=True)
A couple of releases ago I added a change so that you can put these User Defined Elements inside of a list so that they don't look quite so out of place. In earlier versions of PySimpleGUI, this would have caused an error.
def Line(text, key):
return [sg.T(text), sg.Push(), sg.Input(key=key)]
layout = [ [sg.Text('My Window')],
[Line('Name', '-NAME-')],
[Line('Address', '-ADDRESS-')],
[Line('Phone', '-PHONE-')],
[Line('Home Email Address', '-EMAIL-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout).read(close=True)
The Push
Option
But, now with the Push
, there's a new option. You can put a Push
between them and it'll push apart the elements so that they line up. It's a way to get a nice end result without setting sizes and without using a Column
element.
Since it may be an element that gets a fair amount of use, it has a 1-letter alias, P
.
Here's the same result when using the Push
element in the layout.
layout = [ [sg.Text('My Window')],
[sg.T('Name'), sg.Push(), sg.Input(key='-NAME-')],
[sg.T('Address'), sg.Push(), sg.Input(key='-ADDRESS-')],
[sg.T('Phone'), sg.P(), sg.Input(key='-PHONE-')],
[sg.T('Home Email Address'), sg.P(), sg.Input(key='-EMAIL-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout).read(close=True)
To further illustrate what's actually happening, I've added one between the buttons in the last row:
layout = [ [sg.Text('My Window')],
[sg.T('Name'), sg.Push(), sg.Input(key='-NAME-')],
[sg.T('Address'), sg.Push(), sg.Input(key='-ADDRESS-')],
[sg.T('Phone'), sg.P(), sg.Input(key='-PHONE-')],
[sg.T('Home Email Address'), sg.P(), sg.Input(key='-EMAIL-')],
[sg.Button('Go'), sg.Push(), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout).read(close=True)
PySimpleGUI 2021-09-14T22:12:24Z
YouTube Ad-Free
For a brief period of a few days, I ran some tests on YouTube with ads. The channel is large enough to turn on "Monetization".....so I did.
And over those 2 days I've felt really bad about this decision. I don't like the idea of wasting anyone's time, at any price. You're there to learn, not watch some stupid ad. They're back to being ad-free.
In case you missed the lessons in the documentation, here is a link to the YouTube videos.
http://YouTube.PySimpleGUI.org
I've been trying to save user's time on the videos over the past year. Both the YouTube and the new course use a fantastic algorithm to compress out the silent bits. It saves you time & you miss nothing but dead air. The speed of the video is not changed so don't worry that things are going to be too fast-paced.
Here are the same lessons in both formats:
https://youtube.com/playlist?list=PLl8dD0doyrvF1nLakJJ7sl8OX2YSHclqn
https://youtube.com/playlist?list=PLl8dD0doyrvFfzzniWS7FXrZefWWExJ2e
An Example - Lesson 3
The original lesson length is 41:34
The compressed version is 33:48
That saves you 7 minutes 46 seconds.
The YouTube.PySimpleGUI.org
Destination Changed
I don't obsess over stats on YouTube. Viewers are kind with their comments. I see a good number of people watching them. I had assumed that the FAST version playlist was being used, but it appears that's not the case. Since I've not been watching that closely, I didn't realize that the fast versions were not the "default". I hope that these fast versions work out well. I've liked the results and the massive time savings.
PySimpleGUI 2021-09-23T17:00:30Z
New Doc Intro Coming....
I realized that the first part of the PySimpleGUI documentation was written in 2018 and not changed much since. As you long-term users know, SO MUCH has changed from 2018 to 2021.
Windows back then had a lot of limitations, including having only 1 window. Now PySimpleGUI is a multi-window solution with a complete complement of available Widgets including custom menu and titlebar.
I'll try to make the update brief so that it's not throwing all the other stuff off track, but does seem way overdue!
PySimpleGUI 2021-09-25T17:10:55Z
Getting that double-click experience....
Since I posted something on Twitter just now about this, want to make sure I duplicate them here since most users don't read them.
pythonw.exe
on Windows
I should have a section about this in the docs.... added it to the list.
In the meantime....
Using .pyw
files for no-console launching.
If you're after a pure "double-click my file in Explorer and I get a window" experience, all you need to do is to rename your .py file to .pyw. On Windows, explorer should already be set up to launch pythonw.exe when you double click a .pyw file. If not, you can set it up using the "Open With" right-click menu (the net will easily tell you good detailed instructions for associating filetypes with executables).
print
statements
With the "no console" problem solved, now you've lost your print capability. This is something I use a lot. Almost all Demo Programs have a print(event, values)
after window.read()
. It's how I code PySimpleGUI programs.
One way of getting them us to use the sg.Print
function instead of print
. This will solve many of the cases.
You can also integrate stdout into your GUI itself if you want to be more integrated.
Cookbook for print output
There has been quite a bit written about "print output". I strongly recommend using Multiline
elements over the Output
element now. You get a lot more for no extra cost.
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-printing
PySimpleGUI 2021-09-26T00:07:01Z
4.48.0 PySimpleGUI 25-Sept-2021
-
Highlights:
-
Table clicking
-
Push element
-
p = pad in layouts
-
-
Table Element - Feature expansion
-
enable_click_events - New parameter and associated events
-
If parm is True, then events will be generated that are tuples when a user clicks on the table and headers
-
The event format is a tuple: ('-TABLE KEY-', '+CICKED+', (3, 3)) 3 items in the tuple:
1. The Table's key 2. "An additional event name" in this case I've called it "+CLICKED+" 3. The (row, col)
-
The (row, col) will match the user's data unless one of these is clicked:
-
A header (will return a row of -1)
-
A row number (these are artificially generated numbers) and has a column of -1
-
-
-
set_options - new keep_on_top option. Makes all windows you create, including popups, have keep_on_top set to True
-
User Settings APIs
-
user_settings_object() - returns the UserSettings object that is used by the function interface for the user_settings APIs
-
Improved print by returning the pprint formattted dictionary rather than just the string version
-
-
Docstrings
-
set_clipboard takes str or bytes
-
ProgressBar - better size parm description
-
Fixed return type for Window.read_all_windows
-
-
ProgressBar - new size_px parameter allows you to specify your meter directly in pixels
-
pad alias! Lazy coders and those wanting ultra-compact layouts may like this one
-
You can use the parameter p just like the parameter pad
-
pad joins the parameters size (s) and key (k)
-
-
Push Element
-
Alias for Stretch - they are the exact same thing
-
Stretch was a term used by Qt.
-
Push "feels" more like what it does. It "pushes" other elements around
-
Alias is P - like many other Elements, it has a 1-letter alias that can be used to write more compact code
-
-
Removed printing of Mac warnings about global settings at the startup
-
Dedefined the Debug button to be a simple button with a the graphic as before
-
Added a right click menu to the SDK reference so the window can be closed if moved off the screen too far
PySimpleGUI 2021-09-26T00:19:53Z The official documentation is coming likely tomorrow. I wanted to get this posted so it can have a bit more time being tested over the weekend by users before Monday if possible.... Wanted to get these features available and get back to the other releases and lessons.
PySimpleGUI 2021-09-26T19:23:59Z
Cookbook Window.perform_long_operation
Example
A Twitter tip of the day today was this Window
method, perform_long_operation
.
https://twitter.com/PySimpleGUI/status/1442167345733062658
You'll find a new subsection in the Cookbook under the Multithreading section that describes this Window
method. It was released a ways back, and is in the call reference doc:
And there is a Demo Program that shows the usage:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Long_Operations.py
I found the demo using the Demo Browser (a grep basically).
But there was nothing in the Cookbook with some explanation. The Cookbook gets a lot of traffic so getting this one in there while it's on my clipboard.
https://pysimplegui.readthedocs.io/en/latest/cookbook/#pysimplegui-windowperform_long_operation
Code In GIF
Here is the code that is running in the GIF above.
import PySimpleGUI as sg
import time
# My function that takes a long time to do...
def my_long_operation():
time.sleep(15)
return 'My return value'
def main():
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Text(key='-OUT-')],
[sg.Button('Go'), sg.Button('Threaded'), sg.Button('Dummy')] ]
window = sg.Window('Window Title', layout, keep_on_top=True)
while True: # Event Loop
event, values = window.read()
if event == sg.WIN_CLOSED:
break
window['-OUT-'].update(f'{event, values}') # show the event and values in the window
window.refresh() # make sure it's shown immediately
if event == 'Go':
return_value = my_long_operation()
window['-OUT-'].update(f'direct return value = {return_value}')
elif event == 'Threaded':
# Let PySimpleGUI do the threading for you...
window.perform_long_operation(my_long_operation, '-OPERATION DONE-')
elif event == '-OPERATION DONE-':
window['-OUT-'].update(f'indirect return value = {values[event]}')
window.close()
if __name__ == '__main__':
main()
PySimpleGUI 2021-09-28T19:40:50Z
VPush
Element (Alias for VStretch
) is in 4.49.0
I thought I would have a positive title for this one. An alternate would be:
Release 4.49.0 coming ASAP.... I screwed up popup_get_file in 4.48.0 and have to jam this out quickly.
I dropped in an alias for VStretch
to match the alias Push
that I've been using for Stretch
Justifying Elements Made..... Simple
Justifying elements can be a pain. But I think with the addition of Push
and VPush
it will be MUCH easier.
Here's an example:
import PySimpleGUI as sg
layout = [
[sg.VPush()],
[sg.Push(), sg.T('Centered Element'), sg.Push()],
[sg.Push(), sg.B('Exit'), sg.Push()],
[sg.VPush()]
]
window = sg.Window('Window Title', layout, resizable=True)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
This is the Window you'll initially see.
If you grab a corner and resize it, you'll find that the elements stay centered in the window.
You'll need the GitHub version of PySimpleGUI.py in order to run it. Or you can replace VPush
with VStretch
.
Trinket Added
This one is nice enough to add to the educational materials which includes the Cookbook and an old favorite that's being updated to the new release..... Trinket.
Take a look at this page to run this example code.
https://pysimplegui.trinket.io/demo-programs#/layouts/push-and-vpush-elements
If you've not visited Trinket before, this is what the experience is like. You don't need Python installed. All you need to do is go there and run the code.
PySimpleGUI 2021-09-29T16:19:13Z
Open Source Credit in Readme
Last night I updated the readme to include a new section that is near the top.
We're all standing on the shoulders of giants, like computing has done since the early 20th century. We also have legal obligations to meet to many that have given so much and yet asking so little in return. I think the least I can do is what they have specifically asked.
Recognition has been scattered about for this project and I'll continue to do that most likely, but I also want a consolidated place too, where everyone has equal footing, big and small. The project size, number of people, time, cost, etc, don't play any role in this list. They all deserve recognition and thanks for their work. I'm really happy to finally be giving them a bit of this.
PySimpleGUI 2021-09-29T17:37:16Z
Thank You PySimpleGUI Users for Sharing What You're Making!
Well, I'm again shocked by the PySimpleGUI users. Once again a field added to the (painful to use) PySimpleGUI GitHub Issue form is being used when I didn't think it would be.
The field I'm talking about is the highly professionally labelled:
Watcha Makin?
Like the fields where you have been SO helpfully filling in your programming background, many are filling in this field that describes what you're making.
I'm going to share one here from the most recent issue posted.
The program will run on a user's computer to gather technical specs.
It's simple, but it's something. That little phrase adds so much depth to the issue being posted.
I struggle to find the words for how helpful and why it's helpful to hear these things, but they are helpful, and they're appreciated too.
Thank you for taking a moment to tell us what you're making! It's exciting to get to hear a little about what everyone's doing... that they're making real things, not just coding an exercise.
PySimpleGUI 2021-09-30T20:08:52Z
4.49.0 PySimpleGUI 30-Sept-2021
-
Highlights
-
popup_get_file bug fix (primary reason for a quick release)
-
VPush
-
popup_get_file fix
-
-
VPush = VP = VStretch
- Same concept as Push element except in the Vertical direction
-
Image.update_animation_no_buffering
bug fix wasn't checking timer between frames (DOH!) -
one_line_progress_meter
no longer returns a not OK when max reached. Makes the user if statements much easier to get only cancel as False- Note that this is a backward compatibility problem is you are relying on a False being returned when the counter reaches the maximum
-
popup_get_file
fixed bug whenshow_hidden
is set. Added to docstring -
Added
popup_get_file
, get_folder, get_data to the test harness under the popups tab -
Changed docstring for Multiline default value to Any and added a cast to string
-
Added more tests and information to the
sg.main()
test harness
PySimpleGUI 2021-10-01T18:03:16Z
New "Launcher" demo added
A few days ago I wrote about using the pythonw.exe program to easily launch your Python programs without a console.
There are several examples of "launchers" that have been made as Demo Programs over the past few years. It's felt like time to do another one that utilizes the Exec APIs and the User Settings APIs so that positioning can be remembered and that launching is trivial to perform.
This GIF and a couple of links was posted on Twitter this morning:
You'll find the demo here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Desktop_Widget_Launcher_Bar.py
And, there's a matching Trinket for you to try it out without having to do anything but visit the page:
https://pysimplegui.trinket.io/demo-programs#/multi-threaded/desktop-widget-launcher-bar
PySimpleGUI 2021-10-02T16:16:08Z
New Recipe - Launching .pyw
Files
I've been kinda surprised bordering on shocked at how difficult it is to make a Python file act like a windows program. It's not as easy as dragging the file onto the taskbar.
The new cookbook section you will find here:
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-no-console-launching
In it, you'll learn how to make a short-cut icon, the key to making it all work right. Once you have a shortcut to your .pyw file, you can then drag it to the taskbar for example to pin it. You can put it on your desktop and double click it like a normal icon.
Once one is made and pinned onto the taskbar, the experience is much more familiar:
Hopefully this will edge you a little closer to a console-less Python experience. It's rare that I type "python" in order to run python code.
PySimpleGUI 2021-10-03T08:04:13Z
New Demo - Create Shortcuts on Windows
Continuing the theme of getting a double-click experience for Python users, there's a new Demo Program this morning that will do for you what the Cookbook has explained.
You can get the demo here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Make_Windows_Shortcut.pyw
Enter your py or pyw file and you'll get a shortcut that you can then:
-
Drag to the taskbar to pin to taskbar
-
Put on your desktop
-
Doubleclick it from Windows Explorer or any other file manager
-
Pin to start menu
Additionally, there are optional controls:
-
Control the icon that's shown on the shortcut
-
Set a specific Python interpreter
-
Make a shorter/different from the .py/.pyw name for the shortcut
PySimpleGUI 2021-10-05T19:26:42Z
Expanded Exe-Maker Coming Very Soon!
Posted this on Twitter a few minutes ago:
EXCITED to share the new #PySimpleGUI Application Maker (known as EXE Maker previously) is almost through testing & being released soon.
It greatly expands the number of options, is threaded so it performs smoothly.
This was a Tanay creation 🙏 He keeps getting better & better!
Releasing As an Application
This particular PySimpleGUI program is going to be released a pip-installable application, something I've not done yet with PySimpleGUI projects. Since more standalone PySimpleGUI programs are coming, it makes sense to be able to distribute them to Python users easily using pip.
PySimpleGUI 2021-10-07T23:27:32Z
Pip Installing PySimpleGUI Applications
I forgot to post here what I posted on Twitter this morning. These are the only 2 places I post information. Trinket, REPLIT, YouTube, etc, also have info, but nothing in the way of new information updated regularly.
You can bet that quite of bit of this info will make its way into the Cookbook.
psgfiglet
A new application, psgfiglet
, was released to PyPI. This time I think it was done in a user friendly sort of way. The idea is simple
Distribute PySimpleGUI programs using PyPI.
The Application
Installation
If on Windows, then you can use pip and python.
pip install psgfiglet
python -m pip install psgfiglet
If you're on Linux or the Mac, then pip3 and python3 are typically used.
pip3 install psgfiglet
python3 -m pip install psgfiglet
Running
This is where things aren't quite as friendly.... at first....
Open a command prompt and type:
psgfiglet
BUT, now you've got an .exe file that you can make a shortcut to. You don't have to open a CMD window to launch the program.
The Repo
You'll find more about this program here:
https://github.com/PySimpleGUI/psgfiglet
Bug - Console Window Too
On Python versions 3.7, 3.8, 3.9 and 3.10, there is a second console application window that is opened. This is not happening for my Python 3.6 installation. I'll have to figure out what's up and why.
Overall
I'm feeling good about this overall flow for PySimpleGUI application distribution. It's a relatively easy way to distribute applications GUI applications.
Here's a screenshot of a Linux session
Inspired by @pamoroso 's Tweet
A Tweet that may launch 1,000's of applications:
https://twitter.com/amoroso/status/1442840403166760962
I was inspired by Paolo's post about using PyPI as a mechanism for distributing Python applications.
This Program Started with a PySimpleGUI User's Code
You'll find this comment at the top of the source to psgfiglet
Adapted from code originally from this fantastic repository:
https://github.com/nycynik/ascii-font-processor
Thank you nycynik for a fantastic headstart
I originally ran into this code some time back while looking through the latest batch of PySimpleGUI programs and liked it so much that I began to use it quite often and I did some customization to it for myself.
@nycynik gets credit for this great little Figlet maker.
I've been using Figlets more and more in the demo programs and longer Python programs that have sections. Plus... they're FUN!
Directly Accessing The Files
On Windows, use the console command:
where psgfiglet
to get the location of the .EXE file that will be run.
Also, recall that right-click "Edit" command that I tend to add to all of my programs? You'll find it in this program too. If you've set up an editor in your global PySimpleGUI settings, then you'll be able to right-click, choose Edit Me and the Python source code will be pulled up in your favorite IDE/Editor/Notepad
Here's the menu:
PySimpleGUI 2021-10-08T18:27:23Z
Table Header Clicking
A couple of releases back a new Table Element capability was added, but I failed to publish a Demo Program to demonstrate its use. The Table Element got a new parameter added enable_click_events
.
You'll find both a Demo Program and also a Trinket so that you can immediately run the program:
https://pysimplegui.trinket.io/demo-programs#/tables/table-element-getting-click-events
Hopefully all you Table users out there will find this to be a useful feature.
I'll add a section to the docs/cookbook on the new event.
Enjoy!
PySimpleGUI 2021-10-11T18:37:05Z
New UserSettings
Capability - INI files support
One final feature addition before back to finishing the video lessons!! (yes @jason990420 I'm back on them this morning... and the rest of the week)
Over the weekend I added support for "config files" to the UserSettings APIs.
To complete it, I'll make a Demo Program shortly. It's released in 4.49.0.10
The Basics
You've likely encountered these kinds of files before. They look something like this:
There are 2 pieces of information for an item.... the section and the setting. With the JSON based settings, there are no sections. It's just 1 large flat settings file.
INI files a more human-friendly to hand-edit than JSON files. You can include comments, but Python strips them out. I've started on code that will merge them back in but it's not complete.
UserSettings
Object
It is only through the object interface that you can use INI files. They've not been added to the function-based calls of the UserSettings feature.
Step 1... get a UserSettings
object
Reading values
Just like the JSON format, there are multiple ways to read and write values. I'm going to use the [ ] approach in these examples.
If I want to get the save_location
setting that is in the section named [Section 2]
, then it's written this way:
settings['Section2']['save_location']
Printing it is done simply a:
Side note - To see all of the settings in a section, just specify the section only:
This is the output from those 2 prints:
Changing a setting
Changing a setting or making a new one is as simple as looking one up and assigning the new value:
If I run this statement and exit the program, my config.ini file will look like this in notepad:
If I print the variable settings
then I get this output from PySimpleGUI:
-------------------- Settings ----------------------
Section 1 :
{'xyz': True}
Section 2 :
{'save_location': 'new location', 'newItem': 'NEW'}
-------------------- Settings End----------------------
Each section is shown as a dictionary.
The Convert True, False, None option - Default == True
One downside to .INI files is that everything is a string. It makes working with them in the code tricky if you want to transition your code from using JSON (which preserves the type) to INI (everything is a string).
To make life a little easier, I convert these 3 values into the Python values when reading and convert them back to strings when writing.
Note when the settings were printed that the value of Section 1's setting 'xyz'
is shown not as a string but actually True
.
If I create my settings object and turn off this feature, then you'll see strings for all of these uses in the file.
Will produce this output with strings instead of the Python constants:
-------------------- Settings ----------------------
Section 1 :
{'xyz': 'True', 'useConvert': 'True'}
Section 2 :
{'save_location': 'new location', 'newItem': 'NEW'}
-------------------- Settings End----------------------
Deleting a value
To delete the setting newItem
in Section 2, I would write:
When I look at my config.ini
file, I find this value has been removed from Section 2:
Deleting a Section
If you want to completely remove a section and all of the settings under it, then you will need to call the method delete_section
.
PySimpleGUI 2021-10-17T11:32:09Z
psgfiglet
Over the weekend I sent out some Tweets on the topic of psgfiglet
. Just finished up some testing on Linux to be sure it's working as designed. Happy to say it is!
Pip as a PySimpleGUI Distribution Mechanism
The purpose behind this project was to work out what is required to distribute PySimpleGUI programs via pip so that they can be installed and launched without any console interaction. For now, there is initial console interaction required as you do the pip install, find where your EXE ended up. After that, you can make a shortcut or copy the executable and run it directly using the normal GUI experience you're used to.
First of a Series of Tools
At the moment, the release process is cumbersome with a lot of fiddling with files, typing commands to upload to PyPI, etc, but that'll come to an end shortly with a few more utilities being released that will do all that for you.
The goal - you have a folder or a .py file you want to release, and can run a PySimpleGUI program to do just that.
How to install and run the first of these, psgfiglet
pip install psgfiglet
psgfiglet
If on Mac/Linux, you already know to use pip3
Launching from Console
From a command line, it's easy... type psgfiglet
Finding the Executable
To get the console out of the picture takes a little work, at the moment, on your part.
Pip makes an executable file as part of this process
To find where it is so that you can make a shortcut, copy it, or do whatever you wish to make it easy to launch it:
On windows, type:
where psgfiglet
On Linux
which psgfiglet
Here's a Linux demo:
What Does it Do?
It does the same thing as the Figlet Demo Program
Here's a Windows screenshot
PySimpleGUI 2021-10-17T12:24:36Z
psgfiglet
- Edit Me Use
You may recall that in 2021 most Demo Programs are being released with a standard right click menu that tends to minimally have an Edit Me and Exit. Some also include a Version entry.
This psgfiglet
program is no different. It too has an Edit Me right click menu.
Because I have set up an editor in my Global Settings, I'm able to edit the .py file implementing the psgfiglet program. In this case, the filename is gui.py that is running.
This screen capture shows on Windows how this works.
The exact same test was run on Linux and it took launched my PyCharm IDE, opening the gui.py file.
Here's the screen capture running on Linux:
PySimpleGUI 2021-10-17T21:14:52Z
4.50.0 PySimpleGUI 17-Oct-2021
UserSettings API - support for .INI files
Listbox horizontal scrollbar
Column Element allow None for 1 size direction
-
UserSettings API
-
INI File Support
- Read access:
settings[section][key]
Modify existing section and key:
settings[section][key] = new_value
Create a new key in an existing section:
settings[section][new_key] = new_value
Create a new section and key:
settings[new_section][new_key] = new_value
Delete a section:
settings.delete_section(section)
Save the INI file:
settings.save()
-
Available for UserSettings object only, not the function interface
-
Demo Program released specific to .ini features
-
Option to convert strings to Python values for True, False, None
- Read access:
-
Added checks for running on Trinket or Replit so path can be set to "." if on either
-
-
Added
running_replit
function. Returns True if environment is repl.it -
New option in set_options -
warn_button_key_duplicates
will show a warning if duplicate keys found on buttons. Defaults to OFF (duplicate key attempts on Buttons are common and OK) -
Right Click Menus
-
New Element method
Element.set_right_click_menu
-
Enables changing a right click menu after initial window is created
-
If none specified, uses the parent's menu
-
-
-
Added
Window.get_size_accurate()
to get the window's size based on the geometry string from tkinter -
Removed moving of the theme color swatch preview window and allowed to center now
-
Added check for bad value returned from tkinter when table clicked event happens
-
Removed print when 8.6.9 ttk treeview code is patched
-
Removed a debug print accidentally left in the bind code
-
Listbox - added horizontal scrollbar option
-
New
pin
layout helper function implementation (hopefully better, not worse) -
Column Element - Allow
None
to be used in any part of thesize
.-
If None used on width, then Column will default to width required by contents.
-
If None used on height, then Column will default to width required by contents divided by 2
-
These are same values as
(None, None)
today but can invidually control now.
-
-
Made
Window.LayoutAndRead
deprication more user friendly with a popup -
Added * to the
file_types
default so that files without an extension are shown (only a problem on non-Windows systems). Default is now(("ALL Files", "*.* *"),)
-
Changed
popup_get_file
, the Browse buttons, etc -
FILE_TYPES_ALL_FILES
is a new constant with this value
-
-
popup_scrolled
added 1 line per argument to fit the contents better in some cases
PySimpleGUI 2021-10-17T21:47:20Z
New Demo Released for UserSettings Config .INI Support
In addition to the 4.50.0 release today there was a new Demo Program added to help show you how to use the new interface.
You'll find the demo here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_User_Settings_Config_INI_Format.py
Documentation Updated
A new section was added to the main documentation that shows you exactly how to use the new APIs that support .INI files.
https://pysimplegui.readthedocs.io/en/latest/#config-ini-file-support
The Call Reference was updated as well
https://pysimplegui.readthedocs.io/en/latest/call%20reference/#usersettings-class-interface-to-user-settings-apis-can-also-use-the-function-call-interface
New eCookbook Recipe
You'll find a new recipe ready to run showing you how to use these calls.
https://pysimplegui.trinket.io/demo-programs#/user-settings/ini-files
PySimpleGUI 2021-10-18T18:51:30Z
4.51.0 PySimpleGUI 18-Oct-2021
relative_location
parameter for Window
-
New parameter for
Window
-relative_location
-
Locates the window at an offset from the normal location
-
Very useful for multi-window applications
-
Also works when you've set a default window location using the
set_options
call.
-
What? But.... there was just a release yesterday...
(Jason today.... after seeing 2 days of releases in a row)
Yea, well, sometimes this happens. I'm in need of this feature for a lesson and it's better in this case to release it and have it available to be pip installed by anyone and everyone.
New Parameter relative_location
This new parameter is great for multi-window applications where you want your window offset from the normal location.
I will propagate it through the popups in an upcoming release. For now, it's going just on Window. Perhaps as soon as the next release. Until then, we all know how easy it is to write your own popups.
Example Use
import PySimpleGUI as sg
def second_window():
layout = [[sg.Text('Window 2\nrelative_location=(0,-150)')],
[sg.Button('Exit')]]
window = sg.Window('Window 2', layout, relative_location=(0,-150), finalize=True)
return window
def main():
sg.set_options(font='_ 18', keep_on_top=True)
layout = [ [sg.Text('Window 1\nrelative_location=(0,150)')],
[sg.Button('Popup'), sg.Button('Exit')] ]
window = sg.Window('Window 1', layout, relative_location=(0,150), finalize=True)
window2 = second_window()
while True: # Event Loop
window, event, values = sg.read_all_windows()
if window == None: # If all windows were closed
break
if event == sg.WIN_CLOSED or event == 'Exit':
window.close()
if event == 'Popup':
sg.popup('Popups will go to the center of course!')
sg.popup_no_buttons('All windows closed... Bye!', background_color='red', text_color='white', auto_close_duration=3, auto_close=True, no_titlebar=True)
if __name__ == '__main__':
main()
PySimpleGUI 2021-10-19T01:01:52Z
psgshortcut
Another PySimpleGUI application rolls off the line and up to PyPI.
This one enables you to easily create shortcuts.
Why?
Why is having a shortcut useful?
Because with a shortcut, you can pin it to your taskbar, you can put it on your desktop, and best of all, you can double-click it. In other words, we're getting into real GUI applications rather than command line launched GUIs.
The assumption I'm making is that you're a user of GUIs and that you want a GUI experience. If you want a command-line experience, no problem, open up a command line window and start typing.
But, something tells me that if you're a PySimpleGUI user then you're ready to get off the command line and onto the screen.
This tool will make that leap easy.
Instructions
Instructions are included in the readme on PyPI.
https://pypi.org/project/psgshortcut/
Install
pip install psgshortcut
Run (hopefully only once)
psgshortcut
Your First Task - Make a Shortcut to psgshortcut
Once you have your shortcut then you can pin it to your taskbar and use it like any other Windows program.
Icon Included
Like the other PySimpleGUI applications that have been released to PyPI, this one includes a .ICO file so that you can use it to make your shortcut. It's the same icon that's embedded in the source. I've standardized them to be called gui.ico
so that they are consistent across all of these PyPI releases.
The psgfiglet
program, for example, has an icon included with it. Use this shortcut maker with the icon to make a shortcut to the figlet maker.
FUN!! Remember, this is all about having fun while getting stuff done!
Refresher goals of PySimpleGUI project - 1. Have fun. 2. Be successful with your code.
PySimpleGUI 2021-10-21T13:56:07Z
Control+Drag to Move ANY PySimpleGUI Window
I "snuck in" a change in 4.51.2.1 on GitHub this week.
I use a program on windows that is called KDE Mover Sizer. With it, I never have to touch the Titlebar of a window to move it.
There are times when I want a grab_anywhere on a window but it's not been set. This is important to be able to do when the screen is too small for the window being displayed.
How it Works
It's a simple thing to use.
-
Move your mouse over a PySimpleGUI window
-
Press and hold down control key
-
Press and hold the left mouse button
-
Move your mouse
-
Your window will magically move
Future Options
I may be adding the ability to change the key that's held. Like Alt or Shift or something else. At this point, I'm happy to be alpha-testing with the control key to see if it messes up any existing users.
Enjoy the new capability.... as always, no cost (but donations will certainly not be turned away)
PySimpleGUI 2021-10-21T15:12:56Z
4.52.0 21-Oct-2021
Surprise!
No release notes written and released just yet.
It was supposed to be a test, but I'm leaving it up.
The psg
commands continue
Not sure if everyone is following along the recent action on PyPI with PySimpleGUI. TWO applications were released:
-
psgfiglet
-
psgshortcut
Now, when you pip install PySimpleGUI you'll be getting more psg commands, this time they're coming from PySimpleGUI itself.
psgmain
This will launch sg.main for you.
psghelp
Shows the SDK help window
psgupgrade
(just for you @jason990420 )
Upgrades to the version of PySimpleGUI on github
More coming
Of course you can expect a LOT more of these commands coming.
Just like the other PySimpleGUI programs that are released via PyPI, you can make shortcuts to them and launch them. So, if you wanted an icon to upgrade to the PyPI version, then use psgshortcut to make one to psgupgrade.
Enjoy!
As always....
oo dP
88
.d8888b. 88d888b. dP .d8888b. dP dP 88
88ooood8 88' `88 88 88' `88 88 88 dP
88. ... 88 88 88 88. .88 88. .88
`88888P' dP dP 88 `88888P' `8888P88 oo
88 .88
dP d8888P
PySimpleGUI 2021-10-21T19:32:00Z
4.51.4
OK, well... now that I rushed out release was a lesson I didn't need to relearn... no, wait, evidently it was a lesson I needed to relearn.
The Column element changes I've backed out. 4.52.0 is not on PyPI.....
But, 4.51.4 is.
It has the changes from the last release minus the Column element changes.
AND, it has more commands you can enter.
When you install PySimpleGUI going forward, you'll have these commands you can enter from the command line, or, use the shortcut maker to make a shortcut to them.
psgissue - opens the GitHub issue GUI
psgmain - runs sg.main()
psgupgrade - Upgrade from github (still for @jason990420 but without the other problems)
psghelp - built-in GUI window with help info
psgver - get versions of stuff
psgsettings - open the system settings
In case you're not paying attention to the past couple of application releases, I've standardized on a prefix of psg
before PySimpleGUI applications and entry points you can run. These commands are simply entry points that you could do yourself... but when you can click an icon to do it for you? Or type a short command.
Still excited to get this out, but perhaps somewhat more cautious....
MM""""""""`M oo .d8888ba
MM mmmmmmmM `8' `8b
M` MMMM 88d888b. dP .d8888b. dP dP .d8'
MM MMMMMMMM 88' `88 88 88' `88 88 88 d8P'
MM MMMMMMMM 88 88 88 88. .88 88. .88 ""
MM .M dP dP 88 `88888P' `8888P88 oo
MMMMMMMMMMMM 88 .88
dP d8888P
PySimpleGUI 2021-10-21T21:47:50Z
psgmain
and psgupdate
problems....
So, as I'm learning more about using pip to install PySimpleGUI applications, I'm learning about some potential issues.
If you use one of the exe files to launch PySimpleGUI, then when you try to "upgrade from GitHub", pip gets an error as it tries to overwrite the EXE file.
I think I'll have to make a copy of the EXE file for the user and then use that EXE to actually do the upgrade.
Still working through the mechanics of all this.
We're inching our way forward.... it's still forward, but perhaps at an angle rather than straight ahead.
PySimpleGUI 2021-10-23T12:26:30Z
Weekend Release
There's a release coming this weekend to continue to fix the problems I've caused in the recent releases. There are also some new features that have snuck into the code due to recording the course. Many times while making a lesson, I review the element in detail and find some improvements.
Frame Sizes Fixed!
One example of what I want I want to get out there this weekend is the fix for the Frame element. There has always been a problem with setting a fixed size. Well, not anymore! You can not only set a fixed size, but the element_justification
parameter works correctly. You can set no title, the border width to 0 and end up with what appear to be a fixed-sized Column element that works with justifying the contents.
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Go'), sg.Button('Exit')] ]
layout = [[sg.Frame('', layout, size=(400,400), element_justification='c', border_width=0)]]
sg.Window('Window Title', layout).read(close=True)
Produces this window:
If I set the border width to 1, you can measure this image and see that the frame is indeed 400x400 pixels
If you wanted to center the entire layout in the middle of the Frame, then you can a "Vertical Push" to the top and bottom of the layout:
import PySimpleGUI as sg
layout = [ [sg.VPush()],
[sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Go'), sg.Button('Exit')],
[sg.VPush()]]
layout = [[sg.Frame('', layout, size=(400,400), element_justification='c', border_width=0)]]
sg.Window('Window Title', layout).read(close=True)
Resulting in this window:
More later once a release is together and TESTED.....
PySimpleGUI 2021-10-23T12:46:11Z
Updated Radio Button Simulation Demo
I've updated the Simulated Radio Button Demo Program. I tweeted a message about this yesterday.
The Demo is here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Radio_Buttons_Simulated.py
You'll find it running in the eCookbook as well here:
https://pysimplegui.trinket.io/demo-programs#/custom-elements-buttons-radio-buttons-etc/custom-radio-buttons
Often there's a comment posted on the net that tkinter is "SO ugly". PySimpleGUI makes it very easy to do something about the look of a Window, but it seems rarely done. Maybe this example will motivate others to do similar things.
There's nothing special going on here.
All I did was download a couple of radio button images from one of my favorite graphic design sites (I use a subscription service that I think is worth every penny).
Then I ran this demo program to resize them and encode into Base64 images.
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Image_Resize_and_Base64_Encode.pyw
that resized them down to the size you see in the program (25 x 25 pixels)
I pasted the images into the code and the rest you can see in the short program that resulted.
The entire demo in the cookbook is only 35 lines of code... and I didn't try to compress it at all. It was my first attempt (often I go with the first thing that works). I'm sure you can improve it.
Checkboxes are just as easy.
Sliders are a matter of using a Graph element.
Hmmmmm.... maybe that's worth doing a Demo Program for in the future.
You can completely redesign the look and feel of PySimpleGUI with not that much effort. I've seen a "non-professional" programmer do it, and you can too if you look in the User Screen Shots Issue.
The point is that you don't need to do any fancy subclassing to pull off these kinds of customizations. It's straightforward PySimpleGUI code using the same basic constructs you're used to using.
PySimpleGUI 2021-10-24T02:25:45Z
4.51.7 - Hoping to avoid another lesson in "Late Night Rushed Releases"
The recent changes on the GitHub version of PySimpleGUI have not yet been released to PyPI, but, I did upload a new version 4.51.7 in an attempt to get a bad problem with these new "psg commands" to work correctly.
Learning a LOT about the way GUI entry points work with pip installs.
In the previous recent releases on PyPI that included a psguprade
command there was a big problem. The problem was that if you ran psgupgrade
to upgrade your PySimpleGUI to match the one on GitHub, then it would fail because the program psgupgrade.exe was in use (due to you typing psgupgrade).
I think the problem has been fixed!
psgupgrade
should now work correctly, upgrade your PySimpleGUI to match the one on GitHub while also retaining the psg commands correctly.
To be safest, you may want to consider pip uninstalling PySimpleGUI prior to installing the 4.51.7 release from PyPI.
Growing Pains
This whole mess is due to adding these new EXE file based commands. This past week's of releases of 4.51.* have largely been due to these new psg commands.... it's a short-term pain for a long-term gain.... honest....
"It works for me"....
How much fun is it to hear those words when you're trying to get help from someone??
Hopefully you will the one saying them next.
This session shows:
-
installing 4.51.7 from PyPI
-
typing
psgmain
to veryify 4.51.7 was installed correctly from PyPI -
typing
pstupgrade
to get the latest version from GitHub to install -
typing
psgmain
to verify that the latest from GitHub was indeed installed
PySimpleGUI 2021-10-24T18:43:04Z
4.53.0 PySimpleGUI 24-Oct-2021
The "Mike's really excited about this release!" release
psg commands!
psgmain
psgupgrade
psghelp
psgver
psgsettings
Control Click window movement
Frame Elements with size
parameter
I really like this release. It pulls together a lot of work over the past week. It fixes some things that have bothered me for a long time and adds support for some things that have bothered users for a long time.... so here we go....
-
Added Commands that you can type or make shortcuts to
-
psgmain - Runs the sg.main() test harness. Your gateway to settings, version info, etc
-
psgupgrade - Upgrades PySimpleGUI to the latest version on GitHub
-
psghelp - view the SDK help window
-
psgver - view the version numbers
-
psgsettings - access the settings window (usually done via the main window)
-
Don't forget to use
sudo
if you're upgrading on Linux!
-
-
Control Key Dragging - move any PySimpleGUI window by holding down control key while holding the left mouse button down. Ignores the usual Grab Anywhere restrictions and allows dragging over Multiline elements for example
-
A new, shorter, version of the 1x1 pixel BLANK_BASE64 image
-
Image Element
-
New logic for the
Image.update()
(with no parms). This will delete an image and now will also shrink down to 1 pixel -
Set border width to 0 so that takes up even less space when empty
-
-
Frame Element
-
Can now use the
size
parameter to create a fixed size Frame -
element_justification
behaves properly - consider using aFrame
with border width=0 and no text instead of aColumn
element if you need both a hard coded size and to justify the elements inside
-
-
set_options
-
Added
dpi_awareness
setting to turn on DPI Awareness (currently only on Windows) -
Added
scaling
parameter for system-wide Window scaling
-
-
Window
-
Added
scaling
parameter - will scale the contents of the window. Takes a float value -
If need scaling for all windows then set using the
set_options
call
-
-
Better 3.4 compatibility
-
Previously has issues with subprocesses
-
Upgrade to GitHub version now works
-
The new psgcommands to work too so all you 3.4, 3.5 users out there aren't left behind!
-
The PySimpleGUI Tent was built to be big and has plans on staying that way
-
-
Exec APIs - improved ability to modify interpreter to use in other programs so that your program will then pick up the latest changes
-
Testing more thoroughly 3.4, 3.6, 3.7, 3.8, 3.9, 3.10 and tkinter 8.6.2 through 8.6.10
-
Doc updates to the Call Reference doc - Added
Sizer
element and reorganizing a bit. -
Special thanks to Jason for providing amazing support to the PySimpleGUI users. If you think PySimpleGUI is great... if you really want to see something impressive, try logging an issue on the GitHub and watch Jason do his thing.
PySimpleGUI 2021-10-25T19:57:51Z
psgresizer
Posted to PyPI
Another of the demo programs was released as a standalone application.
pip install psgresizer
Then typing psgresizer
will bring up this window:
Use psgshortcut
to really make it nice
If you're a Windows user, you can use psgshortcut
to make a shortcut to the program that you can then pin to your taskbar, move to your desktop to double-click, etc
Instructions on making a shortcut are in the readme for this PyPI release.
It goes something like this:
Here it is pinned to my taskbar:
Clicking it runs the program:
PySimpleGUI 2021-11-02T20:57:34Z
Tabs and Right Click Menus!
The change in version 4.53.0.14, just posted to GitHub, enables right click menus on Tabs to operate as you would expect them to.
Previously, when you clicked on a tab (the name at the top of the tab group), you would get the right click meny for the TAB GROUP, not the individual tab. It made them not nearly as useful as they will be now.
Now, when you click on a Tab, or inside of the tab too, you'll see the right click menu for THAT TAB.
This is the kind of interaction that's now possible:
BIG thank you to @jason990420 🙏 for showing me how to detect the tab being clicked. Often he's able to teach me what's needed so that this feature could be completed in a simple and intuitive way. This is much better than how it worked before.
Earlier this past week, I changed how right-click menus work in Tabs so that they propagate down to the elements inside as well as the blank areas. Now it all functions together in a nice way. Some days are winning days.
PySimpleGUI 2021-11-05T17:13:26Z
4.53.0.16 - Fixes a GitHub upgrade problem started in 4.53.0.9
If you upgraded from GitHub to version 4.53.0.9 through 4.53.0.15, the upgrade from GitHub code is broken in your version and you'll need to install 4.35.0 from PyPI and then do an upgrade to 4.53.0.16. Here you can see 0.16 upgrading itself:
PySimpleGUI 2021-11-05T17:21:45Z
4.54.0 This Weekend... maybe....
The changes have been piling up. Up to version 0.16 currently, so at least 16 changes.
There are some that may impact some applications. I don't make often make changes in functionality in a way that may break applications. Depending on how you write your code, you may have a problem with these 2 items from this release:
-
execute_command_subprocess
- by default the stdout and stderr streams are merged into stdout only. The risk - the subprocess object returned has stderr set to None when this setting is used. The PySimpleGUI upgrade from GitHub code broke as a result, so I know it can cause problems (I didn't check for None) -
Tab
andTabGroup
right click menus - The way right click menus functions for Tabs when you right click a tab title are now specified in theTab
element, not theTabGroup
element. Previously it wasn't possible to right click the tab title and get a unique right click menu. Now you will.
Really hoping no one is impacted! Backward compatibility is one of the highest priority features for PySimpleGUI to maintain.
PySimpleGUI 2021-11-06T17:32:15Z
New and Updated PySimpleGUI Repos - psgresizer
, psgshortcut
, psgtest
, psgfiglet
These applications have been on PyPI for a while. You can pip install any of them. To make it easier to see the source code that's installed, I've created matching repos. I'll update the PyPI releases shortly to point to these repos.
psgresizer is the latest one to be added to GitHub. It resizes images and base64 encodes them as well.
psgshortcut creates windows shortcuts to your Python files (and any other file you want to run)
psgfiglet makes figlets from your input text
psgtest launch Python programs using direct access to Python interpreters rather than using virtual environments. Capture the stdout/stderr in a tab for easy review/copying
PySimpleGUI 2021-11-06T21:06:54Z
4.54.0 PySimpleGUI 6-Nov-2021
Tabs - Are even better now
Right click menu better for Tabs, Frame, Columns
relative_location proliferation
-
Tab & TabGroup
-
Added image_source parameter, enabling file-based and Base64 images to be added to your tabs
-
image_subample parm added so images and be reduced in size
-
TabGroup.add_tab also got the image support
-
tab_border_width parm added to TabGroup to control the border around the tab labels
-
Added constants for Tab Location for easier code completion. All begin with TAB_LOCATION_
-
focus_color added to TabGroup
-
Significant change to right-click menus for Tabs. Now the Tab determines the right click menu shown when right clicking a tab title. Enables a right-click to close feature.
-
-
Frame Element
-
Better right click support in blank areas
-
Added grab parameter
-
Btter grab support in blank areas
-
-
VerticalSeperator - Improvement in expansion
-
VPush and Push - background_color parameter added
-
grab_any_where_on - unreported bug fixed
-
relative_location - a recent parameter to Window has been added to all popups and to Print
-
New Base64 images
-
Hearts (TWO types), green checkmark, red X
-
HEART_3D_BASE64
-
HEART_FLAT_BASE64
-
GREEN_CHECK_BASE64
-
RED_X_BASE64
-
-
Each are 90 x 90 pixels
-
Use image_subsample to reduce size to 45, 30, etc
-
-
bar_color added to ProgressMeter.update
-
visible parm added to all pre-defined buttons (FileBrowse, FolderBrowse, Ok, Cancel, etc)
-
Exec APIs stderr merge with stdout
-
merge_stderr_with_stdout added to execute_command_subprocess and execute_py_file
-
Default it TRUE
-
Stderr will be merged with stdout in 1 stream
-
-
Right click menus propagate down the container elements (Column, Frame, Tab) to the elements inside
-
Window.mouse_location() - returns tuple with mouse (x,y) location
-
SDK Help window now resizble
-
MENU_RIGHT_CLICK_DISABLED changed to match format of normal right click menus
-
psgmain and psgupgrade - changed version of Python used to relaunch to be the same as the one calling the function to invoke PySimpleGUI. Also changed the upgrade from GitHub logic to use Python interpreter for pip as used to invoke.
PySimpleGUI 2021-11-07T09:39:41Z
psgmain
& psgupgrade
seem to work again....
Seeing this window is always a sigh of relief for me
It's a screenshot from my Pi that's running Python 3.4, the oldest version of Python that PySimpleGUI supports.
It was a bit surprising to see the psgmain
command work even there. And, I could tell that the "relaunch" code is working correctly as the command immediately returned prior to the window appearing.
Python 3.4 and 3.5 support
One "problem" with 3.4 is that if I've accidentally left an f-string in the code from doing some tests, it will CRASH immediately upon import of PySimpleGUI with a syntax error. Nowhere in the code can there be an f-string. The PySimpleGUI.py file has to be 3.4 compatible which means, sadly, no f-strings in the core code.
The Demo Programs and other sample code do use f-strings with the minimum version of Python being 3.6 for these programs. I am a civilized programmer, but I am willing to make the f-string sacrifice to support 3.4 and 3.5 systems.
I've been asked a number of times why I don't cut off 3.4 and 3.5 and make PySimpleGUI run on 3.6+ only versions of python..... the reason is really simple. An unstated goal is to make the PySimpleGUI tent as large as possible. There are installs, daily, from users running 3.4 and 3.5. Let's look at the mix from yesterday:
I don't know who exactly these 4 individuals are from yesterday, but I think they're worth this minor inconvenience. Maybe they're working on the cure for cancer that will save my life someday. If so, they're totally worth using .format
instead of f-strings.
May Be a 4.54.1 release
I thought of a change I want to make to the Exec calls. If there is no interpreter set in the global settings, rather than invoking the "Default " python interpreter on the system, I think it would be better to invoke the version of python the code that is calling the Exec API call instead. This way if someone is running their application using 3.10, but their default Python on the system is 3.7, instead of using 3.7, the code will use 3.10.
I don't see a downside to this and it's likely to produce the results that users intend.
I'll ponder while waiting to see if 4.54.0 has any reported problems.
I also see from the break-out of versions above that I need to add 3.11 to the supported Python versions, assuming I can run 3.11, in the PyPI release so that's 2 good reasons for a 4.54.1 release.
Until then, enjoy!
It's back to the Udemy course for me! You're all in great hands with Jason providing the awesome support he provides.
PySimpleGUI 2021-11-07T10:27:19Z
4.55.0 PySimpleGUI 7-Nov-2021
Exec APIs - Use sys.executable as default
FIXED the install from GitHub problem with psgmain/psgupgrade!
-
Exec APIs Changes
-
If no interpreter is set in the global settings, then the interpreter running currently (sys.executable) will be used as the default rather than the system-wide default.
-
Use python NOT pythonw (if returned from sys.executable) for all upgrades from github. The pip command was running pythonw and that caused future psgmain, psgupgrade, etc, commands to fail
-
PySimpleGUI 2021-11-07T10:32:46Z
psgmain
and psgupgrade
now work correctly!
Love it when a release works out.
Decided to bump a whole version because this was a pretty sizable change despite being small.
The default Python interpreter will be the one that is currently running, rather than the one found in the system settings. You can still use the system settings one, but you'll need to directly read it. I'll perhaps add another call to the Exec APIs to get this value.
The Upgrade From GitHub code was changed to make SURE the python executable running pip is not pythonw. The problem with psgmain and psguprade getting corrupted was caused by sys.executable returning pythonw and then that used to run the pip command. When this happened, it screwed up the psg commands. Now, it all works!
FINALLY nailed this nagging problem and can move on from these releases.
The documentation was changed to include the new 4.55.0 release notes
https://pysimplegui.readthedocs.io/en/latest/#4550-pysimplegui-7-nov-2021
So..... DONE... now back to Udemy..... The Graph Element is the current lesson being recorded.....
PySimpleGUI 2021-11-07T19:01:55Z
4.55.1
It's been "release weekend" for the PySimpleGUI project. I don't believe I've done 3 releases back to back in a 2 day period.... well, maybe once before..... but I try not to make a habit of it 😀
I caught the problem with the Exec APIs earlier today and it's a big enough problem to have warranted a "dot release". The problem created was that the Global Setting for Python Interpreter to use by the Exec APIs was never used. The bug was that the sys.executable interpreter was always used. sys.executable should always be used for the GitHub upgrades, and when re-launching main when the psgmain
command or psgupgrade
command causes a "re-launch". sys.executable is also used if interpreter is chosen in the system settings.
It's not a bug I was wiling to leave up on PyPI, so I got 4.55.1 posted to PyPI and have updated the documentation to match.
Python 3.11
Here's a bit of good news to balance out the bug.... PySimpleGUI 4.55.1 is running on 3.11 without problems.....
PySimpleGUI 2021-11-09T14:10:25Z
psgtest
1.8.0
Released 1.8.0 to PyPI and to GitHub.
Release notes from the readme:
-
Support for Python 3.4, 3.5, 3.11 added to settings
-
Set the settings filename to be
psgtest
instead of the default filename. This is needed because the file for these psg projects on PyPI are all name gui.py and thus will have all point to the same settings file if not explicitly set -
Only show configured interpreters in the Combo in main window
PySimpleGUI 2021-11-11T11:54:48Z
Graph Element Example
I recorded the Graph element lesson for the Udemy course last night.
The examples need to be short for the lessons as I cover 3-6 examples in each lesson.
The first example was a bar chart. It was already really simple and basic since these lessons need to be compact, but still convey quite a bit about each element, the methods, and the parameters.
The first example I just played with a little to see if I could make it really short. This is a 6-line version. It's a bar chart. In the original I put the data points into a variable. It's more readable, etc. But for this message wanted to compress it down to these 6 lines to see how short it could be and still be somewhat readable.
Of course in a real program, you wouldn't put the definition of the data [50, 10, 20,80]
directly in a for-loop.
import PySimpleGUI as sg
window = sg.Window('Graph Element - Bar Chart', [[sg.Graph((600, 600), (0,0), (10, 100), k='-GRAPH-')]], finalize=True)
for i, data in enumerate([50, 10, 20,80]):
window['-GRAPH-'].draw_rectangle((i*2+1, data), (i*2+2, 0), fill_color='purple', line_color='white', line_width=2)
window['-GRAPH-'].draw_text(f' {data}', (i*2+1, data+2), color='white', font='_ 18')
window.read(close=True)
The result is this Bar Chart with labels above each bar showing the value of each.
The colors are seriously obnoxious, but I used most of the parms and made each rectangle & text figure stand out... while being ugly too.
You don't always need to resort to using Matplotlib for a Graph. Sometimes it's a handful of lines of code to draw a graph yourself.
PySimpleGUI 2021-11-14T13:11:51Z
psgcompiler
Coming Very Soon!
This program is already on PyPI, but it's there "secretly". The repo has not been made public. I was planning on running a brief "Alpha" on this program.
Here is the PyPI entry:
https://pypi.org/project/psgcompiler/
I'm still working on an update to the documentation and it's still being tested on the Mac, Linux and a multitude of Python versions from 3.6 through 3.11.
My 4-year Python Anniversary
Yesterday my 3.6 installation finally became so full, so many layers have built up that it got a little corrupted so that pyinstller didn't work correctly.
Today I'm rebuilding my 3.6 installation as a result. I was really surprised to see that it's been exactly 4 years since I installed and ran my first Python program.
What a long strange trip it's been....
I started learning Python in November 2017 to build a prototype of a video player. I had no clue at that time that not only would I build the video player, but the thrown together wrapper of tkinter would grow to become a package that has helped so many people also make GUIs.
Lots of firsts for me in this project... from the first Python program to first package to first OO design and first Class.
Thank you to Jason and Tanay!
There is no way that PySimpleGUI would be what it is today with the help of these 2 individuals and a few others that I've pointed out in the ReadMe. These 2 in particular have had a large and lasting impact.
The new psgcompiler
was written in its entirety by Tanay.
If you've posted an Issue here in the past many years, then you already have directly seen the huge impact that Jason has had.
Thank you to the PySimpleGUI users too....
It's been the PySimpleGUI user community that's been the surprise in many ways. You've all been really supportive despite this project being a bit different than other open source projects. I'm astonished that close to 100% of the comments, here, on YouTube, on Twitter, are all very positive and many users openly show gratitude and are thankful for getting help and for the package. What a delightfully positive experience, seemingly a rarity for the internet as a whole.
Udemy Work Continues.....
I've been absent from GitHub Issues, Twitter, etc, as I've been focused entirely on Udemy as THE top priority. Working with Tanay on a variety of other projects is the next priority and the Issues here on GitHub are the third. I like lists that stop at 3 😀. The PySimpleGUI Project's Goals are only 2 long. Simple == Good.
This past week the Graph and Pane elements were recorded. There are a few more elements to go, a few re-records of some lessons and then it'll be finally DONE. Really want it to be done for the holidays!!!!
PySimpleGUI 2021-11-16T14:24:49Z
New psgresizer
Version 1.3.0 Released
Both PyPI and GitHub have been updated.
https://pypi.org/project/psgresizer/
The source code for this utility is both in the Demo Programs folder as well as this standalone repo:
https://github.com/PySimpleGUI/psgresizer
This program is a good example of a utility that I wrote for myself, that's really been a huge time saver.
Shortcuts pinned to taskbar
I've been doing a lot of image processing lately, one image at a time. Sometimes it's to add a PNG as a Base64 byte-string to one of the Udemy courses. Other times I'm using it to make ICO files so that I can use psgshortcut to make shortcuts that I have pinned on my taskbar:
Here you can see I'm running the Resizer and that I've pinned another 5 PySimpleGUI applications.
The 2 "Home" icons launch PySimpleGUI's main test harness for Python 3.10 and Python 3.11 so that I can do quick and easy testing of my PySimpleGUI>py file. Note that they both are picking up the PySimpleGUI.py file from the same location.
psgcompiler
The pink icon you see pinned to my taskbar launches the psgcompiler
program.
I wasn't quite ready to release it and had the GitHub repo set to private. I mentioned I thought casually, here that it was was available, thinking that a handful of people would try it....where a handful is 20.
When I looked yesterday, I was stunned to see that over 1,000 people had installed it! Yikes!
Here are the last 3 days of pip installs:
As a result, I went ahead and made public the GitHub repo:
https://github.com/PySimpleGUI/psgcompiler
We're still working on it, so I would perhaps consider it a "Beta" release right now, at least on the Mac and Linux.
Tanay has been working on some changes that we'll be releasing soon.
Linux/Mac Users Wanted!
It would be great if a few Mac users could give it a go and see how it works.
I have not been successful in getting an executable made using PyInstaller on Linux. I've not spent a massive amount of time trying.
If you run into problems, there is a link on the main window that will open the PyInstaller documentation's Troubleshooting section. One way to test psgcompiler is to copy the parameter that are shown in the main window and paste them onto a command-line run of PyInstaller.
Udemy Update
The Udemy course is shaping up to be about 60 lessons. SIXTY. It's been a full year of work so far and I'm pushing to get it completed very soon.
It's a lot better than the free YouTube course! This is the 4th generation of making PySimpleGUI video courses. I've learned a little bit about making PySimpleGUI lessons as a result of the previous attempts. I'm doing the best job I can, so hopefully, everyone that watches them will find them helpful and enjoyable.
I'm surprised when I listen to them how well they turned out. LOL... Like most people, I'm not the biggest fan of my own voice/videos, but if I switch off who it is that's teaching and focus on what's being said, it feels like the right kind of course to me. I shoot for 15 minutes per lesson. Most are about 15 minutes, but a few are longer because of the particular topic. Some of these elements are tricky and have a lot of parameters and options.
Keep Making STUFF!
I'm thoroughly enjoying seeing the awesome creations you're all making. At the end of the day, I sometimes browse GitHub to see what's out there being posted, especially beginner projects. You're a very creative bunch! Also unusually positive & grateful. It's really motivating and enjoyable to see what you're accomplishing. Thank you for posting screenshots in your readme's!
PySimpleGUI 2021-11-27T12:24:43Z
Scaling - Did you miss this feature's release?
This feature slipped past most users I believe. It was added in 4.53.0
You may have missed it as it has not been well-promoted.
I had a use for it this morning and thought I would share how amazingly handy it is. First, proper "thanks" is owed to Jason for championing the DPI awareness and scaling features for over a year.
This morning I am using my countdown timer that I use when I have phone calls with friends that last a couple of hours. If a timer isn't set, we go past 2 hours with relative ease.
Here is how the timer normally looks:
I wanted to make it more visible so that I would be more aware of how much time before the call. I added one line of code to transform the window to this:
The scaling
Parameter
You can scale UP or DOWN using the scaling parameter when you create your Window. You can also call set_options
, which is what I did this morning. I added this line of code at the top of my program:
The result was that not only is my timer window larger, but the popup call used to get the starting number of minutes was also enlarged 3X.
Try it!
Next time your window feels too big or too small and you don't want to go back and change all the fonts, etc, try adding this parameter.
A value of 0.7 produced this tiny window:
Note that not everything is enlarged
For elements that you specify size using pixels, it will likely not be enlarged. A Graph Element is a good example. An 800 x 600 pixel Graph Element will remain 800x600 pixels.
Some pieces of elements are also not enlarged.
The whole point here is for you to experiment to see if it may help you in certain situations.
PySimpleGUI 2021-12-04T18:18:38Z
Update - Udemy, Ads, Music.....
Music
If you're a subscriber to the PySimpleGUI YouTube channel, then you've likely seen my piano videos. I posted one this morning
https://youtu.be/2ku6ocjnisc
The description describes why I post them. It's embarrassing in many ways as I'm not a good piano player, not a musician, but that's entirely the point.
Udemy
Getting down to the final lessons being recorded. The ones I was dreading the most from the start, the Table and the Tree elements were completed this week. The target is DONE well before Christmas with the entire course.
Ads
In addition to the Udemy effort I'll be raising awareness of this project's financial problem. I realized that only the readme, not the main documentation has this information.
More on this in the coming weeks. A new ad campaign is being developed.
Udemy and the new ad campaign are "make or break the project" efforts. If by March 2022 the project is still unable to generate enough income to pay for this project, then the PySimpleGUI project will close.
It's been a fun 4 years and very satisfying to get to see so many things people are building. But, I'm not willing to lose my home for this project, and continuing to fund this effort will have this result.
I'm hopeful that the situation will change and the project will live on. If not, that's OK too. Life goes on either way.
PySimpleGUI 2021-12-07T12:00:17Z Let's keep the "Announcements Issue" open so that it remains visible to visitors to the project....
PySimpleGUI 2021-12-16T11:43:44Z
Wikipedia-Style Banner in the Documentation
I'm at a place in the PySimpleGUI project that I never dreamed I would be at, but sometimes the paths we choose don't lead to where we thought they would.
Over the past 88 days, I've watched 5,400 companies and people from 291 universities using PySimpleGUI, a fraction of the actual number of users over that period. The number of users is growing at a rate I never thought it would ever hit despite not promoting the project any longer.
As I see panels popping up at conferences about the "Sustainability of Open Source" I can offer a fantastic case study that even with an incredibly "successful" project, it's not possible for an individual to survive with this model.
The FSF
“free software” is a matter of liberty, not price.
mantra is a myth. "If it can be used for free, it will be" is the more accurate assessment based on the evidence I've seen over the past several years.
These 291 Universities have student users that I'm sure have purchased video games in the past year or faculty members that can afford to toss the project $5 a month. But, they haven't.
I hope the project is ultimately kept open, but have been preparing myself for its close. A number of friends have urged me to try the Wikipedia banner so that's what I'm giving a try. Commercialization has been on the table for a while and I've fought going down that road. It may be the only viable route for the project to survive. The coming weeks and months will determine the next steps.
🙏 I can't express the thanks I have to SO many of you using words. Showing the gratification I have and sharing in the happiness I have for all of you is something I strive to do daily. I'm fortunate beyond my dreams, but I have the reality of needing to provide food and shelter for myself, and that, I cannot do at the moment using PySimpleGUI.
Aalto University
Aalto University Student Union
Adelphi University
Alabama A&M University
Aoyama Gakuin University
Arizona Tri University Network
Auburn University
Auckland University of Technology
Baekseok University
Bangladesh University of Engineering and Technolog
Baylor University
BelWue University Network
Belmont University
Binghamton University
Bogazici University
Boise State University
Brigham Young University
Brigham Young University - Idaho
Brigham Young University Hawaii
Brno University of Technology
Bucknell University
California State University at Fresno
Carnegie Mellon University
Case Western Reserve University
Catholic University of DAEGU
Central Methodist University
Chalmers University of Technology
Chiang Mai University
Chubu University
Chulalongkorn University
Chung-Ang University
City University of Hong Kong
City University of New York
Clemson University
Colorado State University
Columbia University
Cornell University
Curtin University
Daegu University
Dalhousie University
Dong-eui University
Dongseo University
Doshisha University
Drexel University
Eastern Kentucky University
European University at Saint Petersburg
Florida State University
George Mason University
Georgetown University
Gifu University
Gonzaga University
Hanbat National University
Hanyang University
Harvard University
Hebrew University Wireless AP nets
Hong Kong University of Science and Technology
ITMO University
Ihsan Dogramaci Bilkent University
Indiana University
Iowa State University
Iqra University
Iran University Of Science and Technology
Israel InterUniversity Computation Center
James Cook University
Janet University Network
Johns Hopkins University Applied Physics Laborator
KOGAKUIN University
Kagawa University
Kanazawa University
Kansas State University
Keio University
Kennesaw State University
Kielce University of Technology
Korea Aerospace University
Korea University
Kum oh National University of Technology KNUT
Kuwait University
Kyiv National Taras Shevchenko University
Kyoto Sangyo University
Kyoto University
Kyushu University
LeTourneau University
Liberty University
Loyola Marymount University
Loyola University Chicago
Lund University
Lviv Polytechnic National University
Maria Curie-Sklodowska University
Marshall University
Massey University
McGill University
McMaster University
Meiji University
Memorial University of Newfoundland
Michigan Technological University
Ministry of University Affairs
Missouri University of Science and Technology
Monash University Sunway Campus Malaysia
Montana State University
Moscow State Technical University named NE Bouwman
Murray State University
Nanyang Technological University
National Central University
National Cheng Kung University
National Chiao Tung University
National Sun Yat-sen University
National Taiwan Normal University
National Taiwan University
National Technical University of Athens
National Tsing-Hua University
National University Corporation ,Ehime University
National University Corporation Shizuoka Universit
National University of Singapore
New York University
Nicolaus Copernicus University in Torun
Nihon University
North Carolina State University
Northeastern University
Northwestern University
Ohio State University
Ohio University
Opole University
Osaka University
Oxford University
Perm National Research Polytechnic University
Plekhanov Russian University of Economics
Princeton University
Pukyong National University
Purdue University
Pusan National University
RWTH Aachen University
Rangsit University
Rice University
Ritsumeikan University
Rowan University
Rutgers University
Sacred Heart University
Saginaw Valley State University
Saint John's University - College of Saint Benedic
Saint Petersburg State University
Samara National Research University
Saratov State Tehnical University
Seoul National University
Sharif University Of Technology
Siberian Federal University
Silesian University of Technology, Computer Centre
Simon Fraser University
Soon Chun Hyang University
South Africa University Network
Southern Illinois University at Edwardsville
Stanford University
State University of New York at Buffalo
State University of New York, Health Science Cente
Suranaree University of Technology
Swedish University Network
Swinburne University of Technology
Synergy University
TUTNET TUT Autonomous System Tampere University of
Takushoku University
Technical University of Gdansk, Academic Computer
Technical University of Koszalin
Technical University of Lodz Computer Centre
Technical University of Sofia
Tehran University of Medical Science
Telkom University
Texas A&M University
Texas Tech University
The Chinese University of Hong Kong
The Pennsylvania State University
The Rockefeller University
The Singapore University of Technology and Design
The University of Adelaide
The University of Alabama
The University of Hong Kong
The University of Manchester
The University of Memphis
The University of Otago
The University of Tokyo
The University of Western Ontario
The-University-Of-Cape-Coast
Tokyo University of Science
Tomsk State University
Towson State University
Toyo University
Tufts University
Tula State University
Umea University
University College Dublin
University Linz
University Malaysia Pahang
University Of Incheon
University Of Ioannina
University Of South Florida
University Public Corporation Osaka
University System of New Hampshire
University at Albany, State University of New York
University of Advancing Technology
University of Alabama in Huntsville
University of Arizona
University of Bristol
University of British Columbia
University of Calgary
University of California San Francisco
University of California at Berkeley
University of California at Davis
University of California, Irvine
University of California, Los Angeles
University of California, Merced
University of California, San Diego
University of California, Santa Barbara
University of California, Santa Cruz
University of Cambridge
University of Canterbury
University of Central Florida
University of Chicago
University of Cincinnati
University of Colorado Denver
University of Colorado at Boulder
University of Connecticut
University of Delaware
University of Edinburgh
University of Florida
University of Georgia
University of Glasgow
University of Illinois
University of Illinois at Chicago
University of Illinois at Springfield
University of Innsbruck
University of Kentucky
University of Lancaster
University of Latvia
University of Lethbridge
University of Liverpool
University of Louisiana at Lafayette
University of Maine System
University of Maryland
University of Maryland Baltimore County (UMBC)
University of Massachusetts - Lowell
University of Massachusetts Dartmouth
University of Michigan
University of Minnesota
University of Montana
University of Nebraska-Lincoln
University of New Mexico Health Sciences Center
University of New South Wales
University of North Carolina at Charlotte
University of North Carolina at Greensboro
University of North Texas
University of Oregon
University of Ottawa
University of Pennsylvania
University of Pittsburgh
University of Queensland
University of Rochester
University of Saskatchewan
University of Sheffield
University of South Carolina
University of Southern California
University of St. Thomas
University of Sydney
University of Szeged
University of Tennessee
University of Texas Rio Grande Valley
University of Texas at Arlington
University of Texas at Austin
University of Texas at San Antonio
University of Toledo
University of Toronto
University of Tsukuba
University of Utah
University of Vermont
University of Victoria
University of Virginia
University of Washington
University of Waterloo
University of Western Australia
University of Wisconsin Madison
University of Wisconsin System
University of the Ryukyus
Utah State University
Vanderbilt University Medical Center
Victoria University of Wellington
Virginia Commonwealth University
Wakayama University
Washington University
West Chester University of Pennsylvania
Western Kentucky University
Yale University
Yamagata University
Yeltsin UrFU, Ural Federal University
York University
PySimpleGUI 2021-12-20T15:14:15Z
Thank you everyone!!
The outpouring of support and words of encouragement have been amazing over the past several days. They're arriving at the perfect time. I've been working so hard to get this Udemy course done by Christmas and your messages and donations are making the long hours shorter.
There have been so many unusual things about this project... it's the gratitude and kindness that have been the most shocking part. So many times users have said "thank you" when opening a GitHub issue.... or thanking Jason for his help. The emails I receive are overwhelming at times. It's hard to describe the soaring feeling of hearing that I've made a positive difference in someone's life.
I'm so very very fortunate to have the kind of users that we have. I look around the internet and I don't see many other projects that are so lucky. Even on YouTube users leave kind comments, not the ugly ones that so often appear online.
I'm not trying to get rich from this project. I'm simply wanting to be able to survive doing it. So many of you are stepping up to help make that possible. I wanted to take a moment and say how much I value, no, cherish, these messages and how impactful they are to me and the rest of the team.
OK, I gotta get back to working! I want to announce this course as done by Christmas!
PySimpleGUI 2021-12-23T14:25:23Z
Udemy ALMOST There.... WATCH for more later today!
I've finally completed the Udemy course!
There are 61 Lectures in the course totaling 11 hours 30 minutes.
I'll post a message about it and a coupon too!
THANK YOU for the support!
The support so many of you are sending along with the course may rescue this project! I'm so excited that it may make it yet!!
I've never seen a more grateful group of people for any project I've worked on. It's so touching to see that there are many grateful and positive people all over the world. I know how massively fortunate I am to be surrounded by thankful people. What a warm and wonderful holiday gift.
PySimpleGUI 2021-12-23T23:47:10Z
Udemy tomorrow maybe!
Hoping for a Christmas miracle and will be able to post a link tomorrow. The course almost made it through the review process. Only a small change was needed which means it could happen pretty quickly.
Again thank you to everyone for the support. The kindness, gratitude, show of support that so many are expressing has been an incredible experience. Heartwarming words. Wishing for happiness and peace for everyone 🙏
PySimpleGUI 2021-12-24T16:31:28Z
Udemy Course is now open and available!
This is a coupon for 50% off:
https://www.udemy.com/course/pysimplegui/?couponCode=2E43BB0C9E0997247E30
The normal link for the course is
Thank you for everyone's patience during the past year. The first recording was completed on Dec 26th 2020. It's been a full year (minus 2 days) in the making.
It wouldn't have been possible to do this without the help of Christian, Tanay, and Jason. 🙏 I'm really fortunate to have their help.
PySimpleGUI 2021-12-25T13:51:48Z
The Treasure in Programming
So much about programming is discussed that falls in the realm of "science" or technology. Very rarely are the emotions and softer parts of programming discussed.
As I read the messages that have been pouring in... messages of gratitude & joy... I have been pondering what about all this that makes me feel the way that I do... the joyfulness of working on this project. Why am I rewarded with these feelings?
I don't know why this diagram popped into my head this morning, but it did. Not sure what to call the red-shaded region, so I've named it The Treasure since it does feel valuable to me.
It's not about skill
Notice in the diagram there is no mention of technical skill, experience, or investment of time. Nothing about doing things right or wrong.
Each category can be defined uniquely by you. That's the secret magic behind this. You can set it up so that this treasure is not only achievable but happens frequently.
Beauty
Beauty can be found in code itself. It can be in the user interface created. There is beautify in witnessing someone be successful. It's everywhere but sometimes has to be searched for. It's rarely far, but can be hidden.
Joy
Joy is for me a short-term experience and one that I'm highly aware of at the time. It can come from seeing something work for the first time. It often arrives quickly, sometimes unexpectedly. "OH! It ran!?"
Satisfaction
This is the deeper, long-lasting part of "The Treasure". It's the part that sticks around.
I truly do treasure this experience that you all are participating in. I'm fortunate to hear from so many grateful people. There is beauty I see daily. I get to share in your happiness, so thank you all for sharing and coming along for this journey of fun and discovery.
PySimpleGUI 2021-12-26T16:01:29Z
The Messages
I read every paypal message, every email, every buy me a coffee comment...
It's been SO helpful. They got me through the difficult part of getting the Udemy course done and they're lifting my spirits considerably.
Your donations are helping and will help in the future! Those that are sending small amounts with an apology or explanation why it's not more need not worry about the size. They all add up. Every bit is helpful. You don't need to apologize, but I don't mind at all reading that you're being so incredibly generous by supporting the project despite not having a lot of wealth to draw from. They're touching stories.
The Banner
I will be changing the banner early in January. Like Wikipedia's banner, it wasn't meant to be something that remains up for forever. I genuinely wasn't sure when I posted it if the project was going to get financial support as a result of it. It was as much a "notice for users to prepare their projects for the impact of the project closing" as it was a "plea for help."
I truly did not expect the response it generated. It's been yet another incredible experience that this project has given me. Rather than being upset and depressed about the future of PySimpleGUI, I'm again excited and much more hopeful.
What's with the strange emotional posts like "The Treasure in Programming" above?
It's a counter-balance. There is so much material posted, written, published about disciplined programming. Paradigms, Pythonic, extensibility, maintainability, refactoring, building-for-the-future, the one right way of writing a piece of code (see Zen of Python).
Coming back to programming after being away from hands-on development has been somewhat of a shock. Coding standards, solid best practices, testability, maintainability were certainly serious topics throughout my career, but it feels extreme to me today. There's a level of seriousness and an almost militant tone that I've seen, even for the beginner programmer that doesn't want to pursue programming as a career.
All this touchy-feely-emotional, fun as a goal part of PySimpleGUI is my attempt to shine a light on the other aspect of programming than the serious, approaching robotic way programming is taught.... the fun part... and that the fun part is a very very important part.
Passion & Ignorance
The "fun" can sometimes grow until it becomes "passion."
I've said here dozens of times that I enjoy browsing GitHub repos and seeing the work of beginners.
The reasons are:
-
often beginners exhibit passion. They're downright ecstatic at the simple things... at discovering programming. They're passionate about learning & creating.
-
they don't know "the right way" (yet)
Ignorance is a good thing sometimes. I don't mean stupidity... I mean uninformed. Not exposed to a deeper education. What I am looking for is someone that's "thinking outside the box", and, if you don't know any better, if you're ignorant on a topic, you don't even know a box exists. You're free to explore, experiment, and innovate.
I love quotes and this one from Picasso (one of those "love the art, hate the artist" painters) I think embodies what I'm trying to explain:
It took me four years to paint like Raphael, but a lifetime to paint like a child.
-- Pablo Picasso
It's this child-like passion, innocence, lack of knowing where the boundaries of "correct" are that I seek both personally and when looking through projects.
PySimpleGUI was born from my ignorance of how GUIs "should work". I avoided them my entire career because of the pages of code involved. I was not only a complete beginner in Python but GUIs too when I wrote PySimpleGUI. That ignorance led to a new approach.
Thank you for the Inspiration
PySimpleGUI users inspire me! I think that's what I'm also trying to say. You do it in your words, your code, and sharing with others what you make. I don't recall seeing any GitHub repo where a new programmer had the courage to share their creation and was then criticized in their Issues. Trust me.... you inspire when you share even the most simple of creations.
Parting thought.... Screenshots in your readme!!
A YouTube comment left earlier today reminded me of this trick....
This video teaches how to use GitHub Issues to store images:
https://youtu.be/C4PVKW756fo
Be sure to include a screenshot of your GUI in your readme! You've done something highly unusual in the Python world... you created a GUI for your application. That means you can share a picture of it... humans ❤ pictures! OK, maybe it's for my own guilty pleasure of seeing all these wonderful creations that I see posted, but I'm sure others enjoy seeing your work too!
PySimpleGUI 2021-12-27T11:49:19Z
Taking Some Time Off
Udemy is done.... help is coming in to rescue the project... things feel a little more stable.
I need to recharge my batteries for a tiny stretch as well as tend to life's mundane tasks that are required to simply exist today.
To do this, I need to unplug, turn off, tune out, and take a break. It'll be good for everyone.
The longest I see being away is through the end of the year, which is in 5 days.
I again thank all of you for making this project one of the most incredible experiences of my life. It's been one of the most challenging too, but maybe the two are required to be present. Your kindness and generosity have been wonderfully overwhelming.
I hope that others helping the project take a break as well. Everyone deserves a break, a period of reflection, rejuvenation, renewal. For me, much of my recharging comes from the fuel provided by all of you. Your kind words echo in my head frequently. It's a very positive message to replay.
See you soon!
PySimpleGUI 2022-01-03T19:06:27Z
2022 - Off to a great start!
Down came the "banner of desperation" today.
The response has been an overwhelming experience. The words of encouragement helped immensely! The donations and sponsorship paid the bills and combined with the Udemy course are going to perhaps keep this project running. I'm very hopeful feeling about the future despite not being able to predict it.
Every Bit Helps
A number of users donated and included a note that was apologetic.... it was all they could afford. A $4 donation pays for the GitHub account for the month. There is nothing to be embarrassed about nor apologize for when you've donated and helped in any manner.
I don't want to discourage telling me your stories, if your donation is difficult to make, or any other message you care to send. They're all read, re-read, written down, shared with team members. They're cherished, appreciated and really demonstrated what a remarkable group of users
Sponsoring Other Developers
Now that the PySimpleGUI project has sponsors and was able to pay the bills this past month, I felt like I can sponsor other developers that I look up to or inspire me. I'm thrilled to be able to give to other people also writing software. We're all doing the best we can with what we've got and it's really great to be able to help these other developers.
"Pledge Drive"?
Raising awareness of the funding problem certainly brought out a big response just as it does for Wikipedia. I'm wondering if this may be the way PySimpleGUI can continue to function in the long run. I don't want to keep focusing the financial piece all the time, so maybe a periodic drive would be a way to. The Udemy course may be the recurring income that can keep these kinds of events minimal.
75/25 Time
I'm splitting my time up between being back here in the GitHub Issues in an active way and releasing software for 3/4 the time. The other 25% is spent in adding to the Udemy course materials to help make it better. With Udemy being the only income source I would like the course to be as good as I can make it. Udemy makes it possible for code quizzes to be a part of the course but they don't support GUIs so I'm having to be a bit creative for that part.
Mike Driscoll's Excel Book
In late November Mike Driscoll released his latest Python book titled:
Automating Excel with Python: Processing Spreadsheets with OpenPyXL and Python
You'll find it on Gumroad:
https://driscollis.gumroad.com/l/openpyxl/tenoff
And on Amazon:
https://read.amazon.com/kp/embed?asin=B09MG2SC9V&preview=newtab&linkCode=kpe&ref_=cm_sw_r_kb_dp_RWRYZG79F0NRSYJJDHBE
You can always find out the latest happenings with Mike's books on his blog located at:
https://www.blog.pythonlibrary.org/
I got my copy via Kickstarter and it's an excellent book.
Education
Speaking of all this education....
I wanted to follow up on a post just before the holidays and make sure the right message was being sent. I wrote about "ignorance" and how it can be an advantage.
The message was not that being ignorant is something to strive for or that not getting educated is a good thing. The point was that if you're still getting started and feel frustrated that you haven't learned as much as you would like, that a slightly different point of view may help. Your lack of knowledge doesn't have to be a negative thing and at times can be an advantage.
Hopeful About 2022
The outpouring of gratitude I've seen by PySimpleGUI users over the past month has had a big and positive impact. Thank you all so much for the help!
I hope all of you have a fantastic 2022 and that the large number of people that struggled last year won't so much this year... that it's a better year for everyone. 🙏
PySimpleGUI 2022-01-03T19:57:38Z
Pirated Course
A kind user just informed me of a copy of the PySimpleGUI Udemy course being offered for sale elsewhere. There's only 1 place at the moment to get the Udemy course, and that's on Udemy.
The New Banner
This is what the top of the documentation (http://www.PySimpleGUI.org) now displays instead of the "help" banner. It's much more pleasant looking.
PySimpleGUI 2022-01-05T13:09:21Z
Working on 4.56.0 release...
The near-term work is to get the changes that have been piling up on GitHub released to PyPI. But first I want to address the 8.6.12 tooltip problem so that fix is in there. A scan through the issues may turn up other critical problems, but I also don't want to take too many changes. The goal is to get these changes that have been on GitHub for a while out to the wider user base.
It's great to be back to the day-to-day project work.
The background work of adding exercises to the course has been also happening this week.
PySimpleGUI 2022-01-05T21:42:17Z
4.56.0 PySimpleGUI 5-Jan-2022
The "It's been a minute" & "Welcome to 2022!" release
-
Addition of stdin parm to execute_command_subprocess. This is to fix problem when pyinstaller is used to make an EXE from a psg program that calls this function
-
Changed getargspec call in the SDK Reference window to getfullargspec. In 3.11 getargspec is no longer supported and thus crashes
-
Added try to SDK Reference event loop to catch any additional problems that may pop up in 3.11
-
Added Window.move_to_center moves a window to the center of the screen. Good for when your window changes size or you want to recenter it
-
Disable debugger when installing from github
-
Better error reporting when a problem with the layout detected
-
Removed import of site and now get the information from os.path.dirname(sys.executable). I like simpler!
-
Combo added parameters to control the colors on the button used to display the items. Parms are button_background_color and button_arrow_color
- Default values continue to be the same the theme's button color if nothing is set.
-
Fixed missing docstring item for Table value so that the new documentation will be accurate
-
(Maybe temporarily) added print to the Text element. Was an easy addition, but is limited in how colors are controlled, scrolling, etc. May be very short-lived addition.
-
New Table Element parameter right_click_selects. Default is False. If True, then will select a row using the right mouse button, but only if
-
zero or one rows are selected. If multiple rows are already selected, then the right click will not change the selection. This feature enables
-
a right-click-menu to be combined with table selection for features such as "delete row" using a right click menu.
-
-
Fixed bug in Column element was incorrectly checking background color for None or COLOR_SYSTEM_DEFAULT
-
Changed docstring for Table.get_last_clicked_postition to indicate what's returned now. Was not useful for tkinter port until recently when cell clicks added.
-
Better auto-sizing of Columns for Tables.
-
Better sizing of the row number column using the font for the header in the calculation
-
Use the column heading font to help determine if the header will be what determines the width instead of the data in the column
-
-
Don't print the error message about wm_overrideredirect while hiding the master root if running on a Mac.
-
Fix for Tree Element not setting the row height if none is specified. Needed to set to value based on the font used.
-
Tree Element
-
Always left justify the first column. This is how it's always worked. tkinter 8.6.12 changed the behavior of the first col. This changes it back
-
Better auto-size column. Uses the data as well as the Column header to determine size of column
-
-
Table Element fix case when tables have too many headers, thus not matching the data columns
-
Tree element addition of a heading for the Column 0 (the main column shown in the Tree). Default is '' which is what's shown today.
-
Graph Element Experimental addition of parm motion_events If True then mouse motion over the Graph returns event of key '+MOVE' or (key, '+MOVE')
-
ButtonMenu Element
-
New init parm image_source Use instead of the filename and data parms. This parm is a unified one and is how several other elements work now too.
-
New update parms image_source, image_size, image_subsample enables the initial image to be changed to a new one
-
-
Fix in sdk_help crashed if asked for summary view of Titlebar or MenubarCustom because they're not classes
-
Fix in open github issue the python experience and overall experience values were swapped.
-
UserSettings delete_entry will show popup error now with traceback like almost all PySimpleGUI errors (can be silenced)
-
TTK Button wraplen fix, height padding fix? (thank you Jason for another fix!)
-
Button fix for wraplen on non-TTK buttons.
-
Layout reuse error message
-
Fix for set_options checking for "not None" instead of "True" for the dpi_awareness setting. Note that once turned on, there is no option to turn off.
-
Docstring changes for all Element.update methods to indicate that the change will not be visible until Window.refresh or Window.read is called
-
Enabled the Text class methods that measure strings and characters to be called prior to any windows being created. Method list:
-
string_width_in_pixels, char_height_in_pixels, char_width_in_pixels
-
Replaced the error messages that were being printed with a poper error popup
-
-
Removed destruction of hidden master root from popup_get_file and popup_get_folder
PySimpleGUI 2022-01-08T20:39:03Z
Python f-string / Formatting Cheat Sheets
f-strings are one of the most brilliant programming designs I've ever seen. They were definitely one of those "finally done right!" kinds of features. Being able to both write the text to be printed with the variables and expressions in-line with them has been an elusive problem that I had never felt happy about until I saw f-strings.
The wonderful things about f-strings are the options they provide for formatting, in particular the date/time formatting. For the past few years, I've needed to search every time I take advantage of f-string formatting. I've never saved a link that I was happy with. Until this week...
The wikipython.com site is filled with incredible cheat-sheet formatted Python goodness. I've mentioned them here before. These new ones that cover formatting are now built into my personal tools. I'm a button press away from this information and it saves a lot of time.
This link is the webpage view:
https://www.wikipython.com/big-daddys-toolboxes/output-toolbox-in-progress/
If you want to download a high resolution 600 dpi version, you can get it from John's GitHub page:
https://github.com/GitHubJohn2/TB3-Format-Options/blob/master/Format%202022b%20600dpi.pdf
The Toolbox Starting Point
If you're just starting with Python or looking for a place to start looking through the information available, the Toolbox page is a good way to start:
https://www.wikipython.com/big-daddys-toolboxes/
He's got numerous reference pages including this subset - The Raspberry Pi GPIO information, many pages of tkinter material (SIXTEEN pages of densely packed, carefully formatted reference info), Data-On-Disk (Pathlib, CSV, JSON, pickle, etc)
Opening Files Using PySimpleGUI - Tip of the day....
These reference pages are so handy that I've added them to my desktop launcher.
If you want to open a file using the standard program associated with that file then you only need to call execute_command_subprocess
. The Operating System will launch the appropriate program that's associated with the filetype.
For example, to open the formatting PDF I call the PySimpleGUI function execute_command_subprocess
and pass in the file to open. In this case:
If you have extracted the images from the PDF and want to open the individual page, then instead of passing in the PDF filename, you would pass in the image filename:
PySimpleGUI 2022-01-13T13:55:24Z
Course Piracy, Security, Malware
The proliferation of pirated PySimpleGUI Udemy course videos continues to spread.
My concern is less of piracy and one of security. Of course, piracy financially impacts all authors, but the person that has the most potential exposure is the user of these pirated materials.
If you see sites like itlearndl.com offering the "Python GUIs – The Official PySimpleGUI Course" available for download, please understand that this is not a site affiliated with the PySimpleGUI project and that you may be exposed to malware as a result of downloading materials.
This kind of thing will happen for any course, book, ebook, etc, so it's not surprising and I have no plans on constantly drawing attention to these sites. But since the course was released only 19 days ago, it seems reasonable to mention words of caution a couple of times.
Cooking up some recipes
I'm working on documentation and more materials for the Udemy course as mentioned earlier. The Push and VPush elements are the focus for the one I'm working today for the Cookbook.
I hope everyone is having an awesome 2022 so far. I love what you're making and sharing! It's truly exciting to see so many creative projects.
PySimpleGUI 2022-01-14T17:44:21Z
Hot Push, VPush Recipe in the Cookbook!
Added a lengthy Recipe to the Cookbook that shows using the Push
and VPush
elements so you can see an easier way to find justification and alignments.
You'll find the new Recipe here:
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-element-justification-and-alignment
Here's a small sample of one of the example pieces of code.
Multiple Monitors
Also added the code that was released as a Demo Program some time ago. I use this tool to help determine the (x,y) location tkinter uses. Really handy if you want to locate something at a specific spot on the screen.
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-positioning-windows-on-a-multi-monitor-setup-tkinter-version-of-pysimplegui-only
Demo code is located here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Window_Location_Finder.py
PySimpleGUI 2022-01-16T17:19:33Z
New Emojis and Demo!
With some luck, this announcement will work correctly...
The PySimpleGUI Emojis have been a nice addition to the overall experience. I use them personally when communicating on all sorts of platforms, not just GitHub.
I just added a new Demo Program that includes these new emojis. I've been using the demo for some time on my computer, but never posted it as an official demo until now. You can use it for your own custom emojis. Instructions are in the demo program on how to go about adding them.
You'll find the Demo Program here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Emoji_Toolbar_PIL.py
It pops up a window at the location of your cursor, you click an emoji, it's placed onto the clipboard, and then the window closes.
At this point, you can paste your emoji into whatever program or webpage you want.
I use PySimpleHotkey to control launching the toolbar.
They're integrated into PySimpleGUI on GitHub and will be posted to PyPI in the next release. A huge thank you to @snaiel (an awesome PySimpleGUI team member) for making these happen. He worked with an artist to get the original set made and we just got this second batch in this week.
Hoping these add to the "Fun" goal of PySimpleGUI.
PySimpleGUI 2022-01-22T20:53:44Z
New YouTube Video - The 2022 Update
I added a new YouTube video yesterday that you'll find here:
https://youtu.be/lRuvKfilJnA
The purpose of the video is to inform visitors to the PySimpleGUI YouTube channel that the "PySimpleGUI 2020" videos that are there now represent a snapshot of PySimpleGUI capabilities as of 2020 and that development has continued for the years following those videos.
There have been 3 different YouTube video lessons
-
Oct 2018 - 5 basic lessons
-
Nov 2018 - 7 additional lessons to make it a "complete" course
-
April/May 2020 - "PySimpleGUI 2020"
The new 61 lesson Udemy course is the 4th video course I've recorded for PySimpleGUI and covers the features that were added after May 2020 when the YouTube videos were recorded.
A lot has happened in those couple of years and wanted to have something posted in the channel that reflected this as well as where to get the latest documentation, tools like the Demo Browser, and that the Udemy course is now available.
One of my favorite parts of that video was scrolling through issue 10, the User Screenshots. It's so much fun to see what users are creating. I'm working on a new feature that will make sharing screenshots easier. It's still early in the development process.
PySimpleGUI 2022-01-23T00:42:37Z
Spotlighted User @DuesAres...
It's infrequent but I've pointed out interesting projects on occasion. Issue #10 I eagerly read posts right away. Sometimes I look through repos that GitHub reports on the main page:
I find myself frequently requesting an upload of a screenshot so visitors can immediately see what they've created. Sorry if you've been a recipient of one of these requests. I don't mean to create more work for you.
Of course, users that file issues are of interest. One such user recently was @DeusAres. He envisioned flat, rounded corner buttons that highlighted when they're moused over.
That's exactly what he created.
This is a fantastic example of doing whatever is required in order to make a GUI that's attractive and follows a design theme that's different than the default. Beautiful in a non-default way doesn't just happen. Sometimes it takes a little work, but it's possible. Can't help but have respect and admiration for @DeusAresfor putting in the time and effort.
PySimpleGUI 2022-01-23T22:19:39Z
Beginners, again....
I love quotes.
Circling back to a post a while back where I've been fumbling around about being ignorant is sometimes a good thing, and then trying to explain what that meant. This quote are the words I was looking for.
[EDIT] - The image may not come through email.... it reads:
'In the beginner's mind, there are many possibilities, but in the expert's mind there are few.'
-- Shunryu Suzuki
PySimpleGUI 2022-01-24T19:50:22Z
New Coupon Code...
Not having created a Udemy course in the past, I didn't know their coupon codes were, well, kinda weird.
Here's a new coupon good for the same discount as the previous. However, unlike the last one that was good for 30 days, this one is only good for 5 days. I'm not able to re-use older codes and they have unusual restrictions on what the amount can be set to. They wanted me to change an additional $39 more if I wanted a coupon good for 30 days like the previous coupon.
The documentation and the PySimpleGUI code have been updated with the new coupon code. I'll keep trying every day to set up a longer-term coupon and see if they end up letting one go through.
THANK YOU Students, Sponsors, Donors!!
I so very very very very very very much appreciate users that are signing up for the course!
The Udemy Students, GitHub sponsors, and ButMeACoffee Donors are literally keeping PySimpleGUI alive.... making it possible for me to continue to work on this project by helping to cover the expenses. I'm grateful for your help and fortunate to have such kind users that say encouraging words that keep me motivated to push forward.
PySimpleGUI 2022-01-26T11:48:22Z
Readme Screenshots
I've mentioned them here before, but looking back I don't see where I pointed out that there's a Cookbook Recipe describing ways to add screenshots to your readme files in your GitHub repo (or any markdown document).
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-post-your-screen-shots-please
I'm working on a Gallery feature that will hopefully help in numerous ways. More info in the not too distant future.
GIFs
If you want to add a GIF to your readme, then you may be interested in a free tool called ShareX that creates GIFs that are quite compact. I've been amazed at being able to get multiple seconds of a large screen in a few MBs and for smaller moving images they're often in 100's of K.
Take a look... you may like it...
https://getsharex.com/
It's what I use to make all of the GIFs you'll find associated with this project. This one if from the readme:
PySimpleGUI 2022-01-27T16:15:25Z
Tip - Getting update
Call Signatures
I use PyCharm so this post will be PyCharm specific.... you can likely apply it to your preferred IDE however.
The Problem - Elements are "looked up"
When you want to call the update
method for an element, you typically perform a "lookup" of that element and then call update. They are generally of the format:
The problem is that the IDE doesn't know exactly which type of element will be returned from the lookup as you're writing your code.
There are 2 ways you can get some help with this.
An example program
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Go':
window['-OUT-'].update(values['-IN-'])
window.close()
Method 1 - Use a temp variable and a type annotation
I'm replacing this line:
With 2 lines of code:
You can also use the comment type of type annotation which will enable you to use earlier versions of Python
Method 2 - Type annotation using comment with 1 line of code
This one is my favorite as it doesn't require an extra variable but I'm still able to get the code completion. The important piece of this technique is that the parameter documentation is not provided for the code portion, it's provided in the comment portion.
Screenshots
In PyCharm, the keystrokes that are helpful for getting the documentation and parameters are:
Control+P - Shows the parameters (press with cursor between the parenthesis of the call)
Control+Q - Shows call reference (press with the cursor on the method being called
Here you can see I've pressed Control P in the comment portion and I'm shown the parameters.
And this is the view you get when pressing Control Q. I typically prefer this one.
If all else fails, use the documentation
Don't forget that these call signatures can be found in the call reference portion of the documentation
http://Calls.PySimpleGUI.org
We've been looking at the Text element above. If you check the call reference for the Text element, you'll find this nicely formatted list of the parameters:
PySimpleGUI 2022-01-27T16:27:38Z
Tip - update
Call Signatures (Part 2)
If your IDE doesn't support docstrings and you don't have access to the internet to get the online documentation, then you can fall back on the "SDK API Call Reference" window built into PySimpleGUI.
Here is the Call Reference window with the Text.update
documentation shown:
Note the link at the bottom of the window will take you to the online documentation for the information being shown.
There are 3 ways to get this window
1. Type psghelp
from the command line
2. Type psgmain
from the command line or call sg.main()
from your code
This will bring up the PySimpleGUI Test Harness
From here click the "SDK Reference" button
3. Call sg.main_sdk_help()
from your code
The result is the same as if you typed psghelp
from the command line.
Summary Mode
If you click the checkbox at the bottom "Summary Only" then you'll get an abbreviated view that makes seeing the init and update parms easy:
PySimpleGUI 2022-01-27T17:11:14Z
Tip - update
Call Signatures (Part 3)
I just released two tools that are used in the Udemy Course.
They weren't meant to be released tools. They were simply teaching aids. But you may find them helpful, so I'm releasing them as Demo Programs.
Demo Browser
I recommend the Demo Browser to interact with the Demo Programs. It's the only way I'm able to keep track of, search, and interact with the now 330 Demo Programs. If you search for SDK (once you have the newest copies of the demos) you'll find the new Demo Programs:
Element Init and Update Parameters
One of the tools focuses on the Init and Update parameters for the elements.
Choose the element you wish to view using the Combo box at the top. Sticking with the Text element I've been discussing in the past 2 posts, we can see the init and update parameters are displayed in the window with the pink parameters representing "Common Parameters" (parameters that are commonly found in many of the elements).
Function Parameters
The second of these SDK Parameter Viewer demos show the parms for functions found in PySimpleGUI.
The default view is only functions that are all lower case. Some functions are used to implement elements such as the Push
element. To see these functions, right click and choose: Upper Case Too
This will populate the combo with all functions.
A word of CAUTION
These were not designed to be released publicly, so you'll find Functions listed that are perhaps not user callable or have been imported from another module like tkinter.
ENJOY!
My hope is that these will maybe save you from looking like this:
And maybe instead look like this:
PySimpleGUI 2022-01-27T23:02:15Z
popup_get_text
- Heads-up if using font
parameter
Just checked into GitHub a fix for popup_get_text
. The font
parameter was incorrectly only being applied to the Text portion of the window. All of the other popups apply the font parameter to the entire window.
It's a fix that is not backward compatible visibly and thus the announcement. It's a rare situation. Thank you goes to @resnbl for finding one of the oldest bugs I can recall. Then again, I can't recall much about last week.
PySimpleGUI 2022-01-28T14:32:09Z
psgtray
- Package That Adds System Tray to PySimpleGUI (tkinter)
To say I'm a user of PySimpleGUI is an understatement. I'm hooked. My efficiency as a developer has improved, my overall Windows experience is better. In some ways, it's a selfish project as I'm enjoying the benefits perhaps more than most.
I count 21 PySimpleGUI programs running at the moment. Most of the PySimpleGUI programs that run continuously in the background are "Desktop Widgets" (like Rainmeter). The two highlights on this Taskmanager are "running in the system tray".
There are 3 ways of getting a system tray icon to work with PySimpleGUI:
-
Use PySimpleGUIQt
-
Use PySimpleGUIWx
-
Use PySimpleGUI (tkinter) with the package psgtray (the technique I use the most)
The psgtray package has a matching GitHub repo.
I use it at the moment for 2 programs. One is a hotkey manager and the other is "pingmote", a program that enables me to use custom emojis in Discord. HUGE thank you to @dchen327 for writing the initial version pingmote that I modified a bit.
The nice thing about the way psgtray
is architected is that it is not written in a polled manner. There is a single window.read()
call with no timeout. That means it'll block until something happens. Of course if you do want to poll some resource then you can simply add a timeout to your read call.
If you've got code that runs in the background all the time and want to be able to interact with it without having a window open all the time like a desktop widget, then this may be an excellent design for you. If your code runs in the background and you currently have to kill it with task manager or don't have an easy way of stopping your code, then this may be an excellent solution.
Here are a few screenshots from my version of Pingmote to give you an idea of what you can do.
When I first startup, I show a message:
Right-clicking brings up a menu and this is where you could add the ability to exit your background program.
The ubiquitous "Edit Me" choice I've added so that I can easily change the program without knowing exactly where the source code is on my system.
Pairing with a GUI.... or not
The beauty of psgtray
is that you don't HAVE to have a GUI if you don't need one. You can use it to simply control your background program.
But if you do want a GUI to go with it, that's easy to do too. I've got my Hotkey program setup to operate as a traditional system tray program - double-click shows the GUI window. Closing the GUI window "minimizes to the system tray" instead of closing.
I hope you're having as much FUN with PySimpleGUI as I am... it really is fun to get to build my own tools for a change.
PySimpleGUI 2022-01-31T14:11:05Z
Demo Program Monday!!
Just finished posting a new pip installable version of all of the demo programs and the Demo Program Browser!
What's the big deal, you might ask?
Well... it makes installing and using the Demo Programs and the Demo Program Browser much easier.
pip install psgdemos
To get the Demo Browser and the Demo Programs in 1 easy step, you can now install them via pip
.... and you can launch the demo browser by simply typing: psgdemos
(after you've pip installed)
Version 1.2.1
The "initial version" is 1.2.1. I don't seem to be capable of making a 1.0 version that stays 1.0 for very long. Setuptools forces an ever-increasing version number... and I truly did believe I was "done" at each of the prior versions.
Was Not Heavily Tested
I wasn't planning on making this release today, or any day... it just struck me this morning that it would be a good thing to have, so prior to starting the normal work-day, I snuck this project in.
Documentation Updates Coming
The Cookbook and other documentation that references the Demo Browser will be updated right away to indicate this new and easy way of installing the demos.
Fun!
Hoping this will make your PySimpleGUI experience all the more fun! Gotta keep working on that primary goal.
PySimpleGUI 2022-02-01T13:42:28Z
psgdemos
- Video Soon...
I run the Demo Browser at least 30 times a day, likely more. I have extra keys on my keyboard and one of them launches the Demo Browser. It was, like PySimpleGUI itself, written for me first. I found it was required to manage so many programs and so much information. Without a standalone graphical "Grep" of the > 300 programs, it made it difficult to search through these programs. I needed something like PyCharm's folder search and that gets old very quickly.
The trend I notice is that as have a need, it's initially filled by an existing tool. If I find I use that capability frequently and the interface to the existing tool would be better if expanded, then it's time to consider writing my own tool.
Install Stats
This morning, what I'm finding puzzling about yesterday's release of the project psgdemos
on PyPI is that downloads of the project began almost immediately, prior to announcing anything. The 1.0.0 release and others was installed by other people.
There is no matching GitHub repo to the project so I'm scratching my head a little on how this is happening other than maybe there being a "Watch" set up by some folks that will automatically download new posts to PyPI.
Other releases to PyPI, like the psgcompiler, didn't have the same explosive numbers as the release yesterday, so I'm discounting the automated download theory a little. Someday I'll find an answer, in the meantime, it doesn't actually matter. It's a curiosity and not worth spending any time on.
YouTube Video Planned
As stated numerous times, the Demo Programs are one of the "Pillars" of the PySimpleGUI project. They are every bit as important as the documentation. If you've taken the Udemy course, then you know that nearly every lesson starts with me using the Demo Browser to show how to locate Demo Programs that may be helpful to the topic being taught.
Because it's such an important part of the project, it has a number of features interesting features that are maybe not immediately obvious (like it can be used with ANY project that has a tree of files, not just PySimpleGUI Demos), I think it could benefit from a YouTube video. I'll try to get one posted over the weekend.
Release of 4.57.0 Soon
As usual, the changes on GitHub have been piling up and need to get released to PyPI. Currently, 16 changes have gone in according to the change notes. Nothing huge, but I get nervous when there are a lot of changes in a single release. There are some features and enhancements I wanted to get in there first, but the Udemy Exercise project is soaking up the majority of my time.
Thank you supporters!!!
I really can't stress enough the gratitude for the help from the PySimpleGUI community.
Your financial help is enabling the project to keep moving forward and alive. I'm so grateful for the generosity. It truly is enabling the project to continue. PySimpleGUI can finally, to some degree, stand on its own.
Your kind words have been a joy to read from the July 2018 initial release date. Thank you for taking a moment to recognize the help Jason is providing. I'm sure he appreciates it, and I certainly do!
PySimpleGUI 2022-02-01T18:15:45Z
Updated Documentation
Made changes to the first part of the PySimpleGUI documentation to freshen things up a little and finish up the Table of Elements.
Learning Resources
https://pysimplegui.readthedocs.io/en/latest/#learning-resources
The first portion of the main documentation has been updated to include the latest information about learning resources. Some items, like the eCookbook, were not shown in the list.
Screenshots
Added new screenshots using the Titlebar
element.
https://pysimplegui.readthedocs.io/en/latest/#some-examples
Table of Elements
Completed filling in the Table of Elements. This table lists the elements and their underlying Tkinter widget. It also lists the shortcuts/aliases for each element should you want to make your layouts even more compact / quicker to type. I frequently use sg.T
and sg.B
for quick little examples of throw-away code.
https://pysimplegui.readthedocs.io/en/latest/#table-of-elements-in-tkinter-port
Here is the table copied directly from the documentation.
| Element Name | Aliases | tkinter Widget | Description |
| :------------------ | :----------------------------- | :-------------------------------------- | :----------------------------------------------------------- |
| Text | T, Txt | tk.Label | One or more lines of Text |
| Input | I, In, InputText | tk.Entry | Single line text input |
| Combo | DD, Drop, DropDown, InputCombo | ttk.Combobox | A "Dropdown" list that can be edited too |
| OptionMenu | InputOptionMenu | tk.OptionMenu | Like a Combo |
| Multiline | ML, MLine | tk.Text or tk.scrolledtext.ScrolledText | Multiple lines of text for input or output |
| Output | | tk.Text (sorta) | Not suggested. Multiline is better choice. Re-routes stdout |
| Radio | R, Rad | tk.Radiobutton | Radio Buttons - choose 1 from several |
| Checkbox | CB, CBox, Check | tk.Checkbutton | Checkbox - binary choice Yes/No |
| Spin | Sp | tk.Spinbox | Choose 1 by using arrows. Can manually enter also |
| Button | B, Btn | tk.Button or ttk.Button | Button - plain or with image |
| Image | Im | tk.Label | A PNG or GIF image |
| Canvas | | tk.Canvas | A drawing area. Graph may be batter to use |
| Column | Col | Combination Canvas & Frame | Embeds layouts inside layouts |
| Frame | Fr | tk.LabelFrame | A frame with a title and a border |
| Tab | | tk.Frame | Container used with TabGroup |
| TabGroup | | ttk.Notebook | Holds Tabs in layouts |
| Pane | | tk.PanedWindow | Sliding columns (it's kinda weird but useful) |
| Graph | G | tk.Canvas | A drawing area with primitives |
| Slider | Sl | tk.Scale | Slider to choose from range of choices |
| Listbox | LB, LBox | tk.Listbox | Listbox - a list of choices |
| Menu | MenuBar, Menubar | tk.Menu | A standard Menubar |
| MenubarCustom | | Combined Elements | Custom colors and font for menubar |
| ButtonMenu | BM, BMenu | tk.Menubutton | Button that shows a menu |
| Titlebar | | Combined Elements | Custom colors for a titlebar |
| ProgressBar | PBar, Prog, Progress | ttk.Progressbar | |
| Table | | ttk.Treeview | A table with clickible cells and headers |
| Tree | | ttk.Treeview | A tree with collapsible sections |
| VerticalSeparator | VSep, VSeparator | ttk.Separator | Vertical line |
| HorizontalSeparator | HSep, HSeparator | ttk.Separator | Horizontal line |
| StatusBar | SBar | tk.Label | Statusbar for bottom of window |
| Sizegrip | SGrip | ttk.Sizegrip | A grip for the bottom right corner of a window |
| Push | P, Stretch | PySimpleGUI Elements | Pushes elements horizontally |
| VPush | VP, VStretch | PySimpleGUI Elements | Pushes rows vertically |
| Sizer | | Column Element | Creates a Width x Height number of pixels for padding/sizing |
PySimpleGUI 2022-02-02T21:12:13Z
Tip - Move Windows With Control + Left Mouse Drag
Here's a little secret / tip that you may find handy. It's in the release notes under version 4.53.0 from Oct 2021
Sometimes it's possible to end up with a window's titlebar that's offscreen and thus you can't grab it and move it. Or, maybe you've created a window without a titlebar and you need to move it, but didn't get grab_anywhere
. If so, you're in luck!
You can move any PySimpleGUI window by:
-
holding the control key
-
clicking and holding anywhere in the window
-
and then dragging.
It's like a temporary "grab anywhere".
Here you can see it in action. The Window was created with no_titlebar
and with keep_on_top
, but it does not have grab_anywhere
set. I tried to grab it at the beginning of the video clip with just the left mouse button. Then I held the Control key and tried again, this time moving the window.
PySimpleGUI 2022-02-03T14:03:27Z
New Demo - Demo_All_Elements_Simple.py
Seeing the table of elements posted above 2 days ago triggered an idea for another demo.... one that has a list of the elements shown menu-style and one line of code per element. It's simpler in every aspect than the previous "all elements" demos done. The Demo_All_Elements is good because it puts them all together into context.
This one is a little different. It's an inventory. Here's how it looks....
It's also a handy Theme-Previewer.
psgdemos
The psgdemos
PyPI project is such a great way to easily distribute these demos AND more importantly the demo browser. But it also means keeping it up to date. This new demo needs to be added to that PyPI release, the version number bumped, etc etc.
I'm writing a PySimpleGUI program that will take care of that for me so that it's not such a manual process. I can't really complain about the 1 or 2 minutes it takes now, but I think a tiny bit of automation will reduce lag-time and the potential for errors.
If it's not apparent by now, I'm perhaps the heaviest user of PySimpleGUI on the net. It's "what I do" and I wrote it for myself, so it's only natural to keep being selfish and using it for my own fun. Despite it being 4 years in Feb since I finished writing PySimpleGUI for internal use, it's still a lot of fun to use and expand.
I appreciate all of you that are helping make this possible to do.
Building stuff like this keeps me cognizant of what users are experiencing too.
PySimpleGUI 2022-02-05T13:36:19Z
Latest All Elements Simple Demo
I wanted to also be able to show the Custom Titlebar and Custom Menubar elements in the newest All Elements demo, so it was updated this week with an option to switch back and forth between the OS-provided title & menu bars and the custom ones.
It's perhaps one of the best Theme Previewers among the demos, especially if you're going to use a custom titlebar.
Weekend Release?
The changes have been accumulating a little bit and I get ancy when that happens. While most are minor, there are still 18 of them. With the addition of the Udemy Course, it's adding a bit of pressure to ensure the releases are more thoroughly tested.
I've always felt like there's ONE and only one opportunity to acquire a new user, "The 5 Minute Challenge", the 5 minutes required from "I would like to make a GUI" until PySimpleGUI is installed and you've got a GUI on your monitor. Blow that experience and that user is long gone.
It just means a bit more testing prior to releasing and perhaps more automation around releases, especially the new psgdemos
package. There are now 2 copies of Demo Programs as result of this package, those here in the Repo and those that are on PyPI. Automating this part isn't the highest priority at the moment though. There are several other projects that are ahead. It only takes a couple of minutes currently as the building of the package and uploading are already done using a batch file.
Emoji's and images
Some of the "features" are indeed a bit frivolous or fun in nature, but with Fun being the number 1 project goal, that makes these just as important in my mind.
A special "Thank you" to @DAFEX6390 for the Python-colored-hearts idea that he used in a conversation this week. You're a creative and motivating bunch of users. Thank you all!
PySimpleGUI 2022-02-07T13:47:37Z
"Don't Google PySimpleGUI...."
This is the title of a new YouTube video I've been writing the script for.
I thought I would jot down a few notes here first because I see comments frequently that tell me there's a problem.
From the beginning of the project and documentation, there has been a caution about using StackOverflow in particular. This should have been and will be expanded to include "Google".
The problem is that PySimpleGUI is not a static project. It changes and in fact has changed dramatically in the past 2 years alone. It's no longer the completely static, no threading possible, etc, package it was when much of what's posted on the internet would lead you to believe.
Ideal Method of Information Acquisition for PySimpleGUI
Start with http://www.PySimpleGUI.org - the primary documentation.
If you've hit a problem, search the issues http://Issues.PySimpleGUI.org to see if someone else has already seen the problem and it's been solved.
If you're looking for sample code, which is one of the most frequent uses for Google by software engineers, then use the Demo Browser. pip install psgdemos
and run psgdemos
to do searches of the > 300 Demo Progams. The Demo Programs are kept up to date. StackOverslow answers, tutorials others have written, etc, are not kept up to date, or worse yet, are answers that are just plain wrong.
Thankfully, Jason, the AI support bot for PySimpleGUI seems to be absolutely everywhere questions are being asked. StackOverflow answers are often posted by Jason. Even these, over time, become obsolete. The answers are no longer "correct" a limitation that was there is now gone, or a technique that was right when it was answered is no longer the preferred way.
Read the Docs
This is an old concept, but just as valid today as it was in the 1970s. The documentation was written by the software's author. RTFM is an old term because this is an old problem.
Admittedly the docs and the eCookbook aren't always completely current. The Call-Reference document is because it's generated.
The "Ecosystem" for PySimpleGUI was established right upfront. The docs, cookbook, the demo programs, and the GitHub support were meant to fit together to form a uniform solution. I don't particularly care for the term "Ecosystem". I used a less precocious "System" term. It was designed to be a set of puzzle pieces that fit together to form a unified solution for users. A one-stop shop.
I'm Guilty Too....
This week I was alerted to a number of Gists that a user kindly replied to. They were over 2 years old and Google returned them in the user's search results. I had no clue I had posted these things and they were still out there. So, I'm not always helping the problem and am far far FAR from perfect in any of this.
The YouTube Videos are Old
This is a big concern. Programming Videos are a popular for some people to learn. While they're the 3rd generation of PySimpleGUI instructional videos, they are teaching a PySimpleGUI was existed in 2020, not the one that's in 2022.
The Udemy course is completely up to date. It's the best video course I've made to date. Sorry if this sounds like an ad... it's not meant to be. It's a caution is all.
I did post a "2022" update video not long ago that is quite popular so I know users are at least getting the point here that PySimpleGUI is not just revolutionary, it's evolutionary too. As your successes and needs change and my ideas broaden, so does the PySimpleGUI code.
If You Google, Follow-it-up
I think this is the conclusion I would like to propose. When you get information from a non-PySimpleGUI official source, come and check to make sure it's still true. If you're a senior developer, you already know that understanding what you copy and paste is critical. If you're a beginner, you need to understand it even better, especially if it comes from a non-PySimpleGUI site source.
Why?
This is all about The PySimpleGUI Project Goal Number 2.... "Your Success". That's it.
I want you to have the best experience possible and ultimately be successful in an as efficient and enjoyable way as possible. If you get led down a path that causes you to spend hours banging your head against the wall because of old information, then, well, that just plain sucks.
Less of this:
And more of this:
Thank you!
I can't help but add a thank you to these messages. You're a wonderful group of users! You are appeciated.
PySimpleGUI 2022-02-13T20:25:49Z
Demo Program - Circular Progress Meter
How not to get a release out the door in 6 easy steps:
-
See a shiny GUI object (a circular progress meter in this case) on GitHub
-
Ponder what it would take do in PySimpleGUI
-
Write the code
-
Clean it up a little
-
Post to Demo Programs
-
Write this message
I used a trick in this demo that I'm not sure if I've used before in an official Demo Program, but I'm sure to use more now.
window.read(timeout=10)
Instead of time.sleeep(.01)
Sometimes you want to simulate work and that's usually done by calling sleep
. GUIs and time.sleep
don't mix very well. As mentioned in the docs, the tutorials, etc, you don't want to have a sleep in your event loop because while you're sleeping, your user is experiencing a user interface that's non-responsive.
Using a window.read
call with a timeout value is a really good replacement. It provides these advantages:
-
You don't need to import time
-
Your GUI remains active the entire time you would normally be "sleeping"
Here's the entire demo for reference since it's so short. It's a little bit on the "hacky" side as it was hastily thrown together. Hopefully, it'll be "good enough" to get the idea across that the Graph element is your gateway to custom elements.
import PySimpleGUI as sg
# Settings for you to modify are the size of the element, the circle width & color and the font for the % complete
GRAPH_SIZE = (300 , 300) # this one setting drives the other settings
CIRCLE_LINE_WIDTH, LINE_COLOR = 20, 'yellow'
TEXT_FONT = 'Courier'
# Computations based on your settings above
TEXT_HEIGHT = GRAPH_SIZE[0]//4
TEXT_LOCATION = (GRAPH_SIZE[0]//2, GRAPH_SIZE[1]//2)
TEXT_COLOR = LINE_COLOR
def update_meter(graph_elem, percent_complete):
"""
Update a circular progress meter
:param graph_elem: The Graph element being drawn in
:type graph_elem: sg.Graph
:param percent_complete: Percentage to show complete from 0 to 100
:type percent_complete: float | int
"""
graph_elem.erase()
arc_length = percent_complete/100*360+.9
if arc_length >= 360:
arc_length = 359.9
graph_elem.draw_arc((CIRCLE_LINE_WIDTH, GRAPH_SIZE[1] - CIRCLE_LINE_WIDTH), (GRAPH_SIZE[0] - CIRCLE_LINE_WIDTH, CIRCLE_LINE_WIDTH),
arc_length, 0, 'arc', arc_color=LINE_COLOR, line_width=CIRCLE_LINE_WIDTH)
percent = percent_complete
graph_elem.draw_text(f'{percent:.0f}%', TEXT_LOCATION, font=(TEXT_FONT, -TEXT_HEIGHT), color=TEXT_COLOR)
def main():
layout = [ [sg.Graph(GRAPH_SIZE, (0,0), GRAPH_SIZE, key='-GRAPH-')],
[sg.Button('Go')]]
window = sg.Window('Circlular Meter', layout, finalize=True)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
for i in range(500):
update_meter(window['-GRAPH-'], i/500*100)
window.read(timeout=5) # an easy way to make a loop that acts like it has a "sleep" in it
window.close()
if __name__ == '__main__':
main()
Still in Udemy-World
Most of my time is spent working on the Udemy exercises. It's moving along quite well and I'm shooting to deploy this month. As is often the case, I'm getting excellent help from @Chr0nicT and @Snaiel. The course, and PySimpleGUI itself, wouldn't be nearly what it is today without the help of these brilliant young engineers.
Gallery Project
Another project being worked on is a better Gallery solution for us all. I'm really excited about this project. I'm sure it's going to be a popular feature.... at least with me it will be.
This is planned to be a feature in PySimpleGUI itself, much like the GitHub Issue GUI is built-in.
PySimpleGUI 2022-02-13T21:53:30Z
4.57.0 PySimpleGUI 13-Feb 2022
A little of this, a little of that
New Emojis for 2022... collect them all!
-
set_options added disable_modal_windows option to provide a single call to disable the modal feature globally (including popups)
-
Added OptionMenu to the list of tkinter widgets that are ignored when the grab anywhere feature is used
-
Slider update the range FIRST and then the value in the update method (thank you Jason for the fix)
-
Updated docstrings for all Element.update methods to indicate that the helper function "pin" need to be used to keep an element in place if visibility changes
-
Replaced sponsor tab with a tab about the udemy course as well as the buy me a coffee link
-
Fixed event generation for Spin element. Also changed to use the "command" parameter to get the event. NOTE still need to handle manual entry
-
New Emojis for 2022!
-
New base64 image PYTHON_COLORED_HEARTS_BASE64 (yes, more hearts... apologies to the heart-haters)
-
Changed +CICKEDto +CLICKED(typo) in the table header
-
Added constant TABLE_CLICKED_INDICATOR that is the value '+CLICKED+' so that it can be referenced instead of user's hard cording a string
-
Added class method Text.fonts_installed_list returns list of fonts as reported by tkinter
-
Horizontal scrollbar for Multiline element (long awaited). New parameter added to control just this one scrollbar. The no_scrollbar existing parm refers to the vertical scrollbar
-
Fix for font parameter only being applied to Text portion of popup_get_text. Should have been to the entire window.
-
Updated the internal keys to use the -KEY- coding convention. Was using the really old KEY coding convention.
-
Added check for bad Image filename in Image.update. Will show an error popup now like the initial Image element creation error popup
-
Addition of parameter paste (bool) to Input.update. Inserts as if the value was pasted rather than replacing entirely
-
Fix for Listbox scrollbar not behaving correctly when making element invisible / visible
-
Docstring update for Window.perform_long_operation warns users that Thread are used and thus no PySimpleGUI calls are allowed. Also added description of exactly what happens when the user's function completes.
PySimpleGUI 2022-02-13T23:33:11Z
psgdemos
1.5.0 Released
Updated the psgdemos PyPI release to include the new circular progress meter demo posted earlier today and an updated version of the PIL Emoji Toolbar to include the newest images that were released today in 4.57.0
Now you too can easily add Python colored hearts or the PSG Hero to your messages...
PySimpleGUI 2022-02-14T16:10:04Z
The road ahead....
Bear with me for a long post..... It's a rare glimpse behind the curtain that I feel is appropriate right now.
The release got out over the weekend, as can be seen from the announcement as well as a new psgdemos
release. The overall project activity appears to be slowing considerably, but this is only because the work that's being done is all behind the scenes right now.
Udemy
For the time being, I'm firmly rooted in Udemy-world and expect to get this part wrapped up by month's end. The new part being added is an interactive exercise site that fits with each lesson. Watch a lesson, then complete one or more exercises using a live-in-browser PySimpleGUI program. The architecture is up and running so my biggest time sync is simply creating each of the exercises for the 61 lessons. Just like writing and recording those lessons, these take time.
I think this is a critical portion of the overall PySimpleGUI education. It's by programming that one learns to program. You gotta write the code in order to learn to write code. I'm not content with videos of me writing code. It needs to be you writing the code and this new site is going to fill that void. "Programming is not a spectator sport", I think I said in the closing lesson of the course.
Enhancements
The next priority for PySimpleGUI itself are some enhancements that I've got queued up. The Table Update enhancement is at the top of the queue. There are plenty to choose from given there are 643 open issues at the moment.
Screenshot / Animated Screenshot Gallery
This feature is in active development. Issue number 10 has clearly demonstrated that there's much to be gained by all of us seeing what the PySimpleGUI users and the PySimpleGUI team are creating. Unfortunately, the current mechanism isn't a great experience for VIEWERS. It's easy to post an image and information, but GitHub does a terrible job with Issue viewing because of how it paginates. In the middle of the page you'll find a "Load More" link with a note that 245 of the 253 comments are HIDDEN....
The posts suddenly jump from Nov 2018 to Jan 27 2022... all those great screenshots are not visible. Gee, thanks GitHub!
I also want to make the submission process easier and built directly into PySimpleGUI so that you can submit a screenshot by pressing a key combination.
More on this feature as it all comes together.
The fuzzier future
I don't like to publish "Roadmaps". I feel boxed in the moment something like that is publicly published and it's not the smartest thing to do in business.
One of the biggest obstacles to future features, and indeed the future of the project, is funding. The Udemy course and the fund-raiser in December have provided "breathing room". They help with operational costs, but aren't yet at a level that's capable of sustaining the project in the long-term.
I do want to be very clear on this - I am hopeful, upbeat, have a positive outlook on the PySimpleGUI project.... "It'll all work out". This I have always believed or I wouldn't have dove in head first.
There are 3 larger areas I would like to provide some information on:
-
PySimpleGUIQt
-
The PySimpleGUI Designer
-
PySimpleGUI Mobile
PySimpleGUIQt
The PySimpleGUIQt project was going to enter an Alpha trial last year. That work is on hold. There have been a lot of changes to the tkinter port that are not yet ported. As a result, there needs to be a restart of that work. I'm really sorry to break this not so great news to the PySimpleGUIQt users. It's not the way I wanted things to go, but sometimes projects don't always work out as desired.
PySimpleGUI "Designer"
There's been a desire for a "designer" by users going back to the first month PySimpleGUI was released.
Last year a friend and I prototyped a PySimpleGUI "designer". Why am I using the "designer" in quotes?... well.... because it's not your typical GUI Designer.
Like PySimpleGUI departed from the traditional GUI architecture, so did this piece of software. It uses some AI magic to transform sketches you make on paper into a working PySimpleGUI program.... so, the designer you'll find in the PySimpleGUI documentation truly is the PySimpleGUI "Designer".
https://pysimplegui.readthedocs.io/en/latest/#the-window-designer
While it works really well I'm not releasing the code at this time. There are 2 reasons for this:
-
The need isn't all THAT great - PySimpleGUI is easy to use.... and while this program does make creating GUIs even more trivial, it's not crippling the growth of the project by not having the designer available. You're all cranking out GUIs at a record pace.
-
Licensing - It's a valuable piece of code/Intellectual Property. With the PySimpleGUI project having the funding issues it has, releasing this designer will be done in a very purposeful and careful way. It's not something to toss out onto GitHub without great care.
So..... yea.... in a holding pattern for just a bit as some of the legal and financial problems get addressed.... Your patience is appreciated and I'm sure you'll be quite happy after the wait.
PySimpleGUI Mobile
This one has me the most excited.
It will be explosive.
I can't wait to see the kinds of things kids do with PySimpleGUI on their phones. I've zero doubt of how powerful and popular it will be.
I've had a long-time dream of empowering disadvantaged youths using the phone in their pocket.
Not many kids can afford a board to build a robotics kit or buy a piece of hardware with blinking LEDs, a trend I've noted in teaching young kids to program. Requiring this hardware leaves behind a large number of people.
I think kids don't need flashing LEDs in order to entice them to learn to program. I believe a kid that hands their phone to a friend with "hey, check out what I wrote" is much more powerful of a motivator than a blinking LED.
The PySimpleGUI tent is HUGE and global. I have every intention of it remaining that way and by inviting in all the mobile devices on the planet, it's going to grow even larger.
Subject to change....
The PySimpleGUI project is fluid. These are not promises, they're peeks, whispers of what's happening. Where this all leads is part of the fun.
I 💗 quotes, so I'll leave you with one of my favorites
“All journeys have secret destinations of which the traveler is unaware.”
- Martin Buber
Travel safe everyone! Thank you for making this ride a once in a lifetime adventure
PySimpleGUI 2022-02-14T20:13:15Z
A Demo is Born.... Demo_Fonts_Using_pyglet.py
New Demo Program released today. I've released it both here on the PySimpleGUI GitHub and also in the psgdemos
PyPI package.
It's a good example of how some of these come to be. Jason answered a GitHub Issue with some code that was really clear, and a great example of how pyglet
can be used with PySimpleGUI to pull in custom fonts. Those are the kinds of capabilities that are an instant addition to demo programs. Short, simple, does something really compelling/powerful.
The code is here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Fonts_Using_pyglet.py
Since it's short, I'll go ahead and include the entire program and a screenshot....
import pyglet
import PySimpleGUI as sg
"""
Demo - Using pyglet to get custom fonts into PySimpleGUI
Original code by @jason990420
Copyright 2022 PySimpleGUI
Font information:
Copyright (c) 2020, Walter E Stewart,
with Reserved Font Name Open Flame.
https://www.1001freefonts.com/open-flame.font
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
"""
pyglet.font.add_file(r".\OpenFlame.ttf")
font1 = ("Open Flame", 40) # Note - use the font "face name" not the filename when specifying the font
font2 = ("Courier New", 40)
font3 = ("Helvetica", 40)
text_string = "ABCDEFG abcdefg 1234567890"
layout = [ [sg.Text(text_string, font=font1)],
[sg.Text(text_string, font=font2)],
[sg.Text(text_string, font=font3)] ]
window = sg.Window('Adding Fonts', layout)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
window.close()
There's so much to like about a little piece of code like this! It's short, simple, trivial to add a capability to PySimpleGUI. Tasty stuff!
PySimpleGUI 2022-02-26T12:52:30Z
Demo - Class Wrapper
Just posted a very simple Demo Program that shows one way that a class can be used with PySimpleGUI.
I tend to use classes as a way to create "new data types". For example, the Elements I think of as data types.
You can also think of classes as an encapsulation mechanism that gives you an environment that looks like it has global variables. What I mean by that is that if you look at a class method, like the one in the Demo, it looks like it's accessing a "global variable":
In this case, values
is what I think of as a "global variable" in this context. There is no "global" statement, yet the function can read and write the values
variable. Of course, the catch is that the prefix self.
needs to be added. It's a bit of a warped lens to view classes through, but it's one way to interpret them.
In the demo, I've broken the typical PySimpleGUI program up into 2 methods:
-
init - The class init method in this demo defines the layout and creates the window
-
run
- This method runs the event loop
The primary program is 2 lines of code
-
Create the object -
SampleGUI()
-
Call the
run
method
The button_go
method shown above is called from the event loop when a button is clicked.
There are numerous ways you can architect your code, with and without classes. Most of the time you'll find examples posted by the PySimpleGUI project don't use classes. This is to keep them simple and understandable by users that may not have been exposed to classes yet.
You can always go from simple to more complex when you write your code.... so feel free to experiment with using classes to find the way of architecting your code that fits the problem you're solving. They're a very useful construct and can also be used to simplify very complex programs (yea, I know, it's the reverse of what I just said...all problems are unique, so it's hard to be so overly generalized).
It's a short demo, so there's the entire program....
import PySimpleGUI as sg
"""
Demo - Class wrapper
Using a class to encapsulate PySimpleGUI Window creation & event loop
Copyright 2022 PySimpleGUI
"""
class SampleGUI():
def __init__(self):
self.layout = [ [sg.Text('My layout')],
[sg.Input(key='-IN-')],
[sg.Button('Go'), sg.Button('Exit')] ]
self.window = sg.Window('My new window', self.layout)
def run(self):
while True: # Event Loop
self.event, self.values = self.window.read()
if self.event in (sg.WIN_CLOSED, 'Exit'):
break
if self.event == 'Go':
self.button_go()
self.window.close()
def button_go(self):
sg.popup('Go button clicked', 'Input value:', self.values['-IN-'])
# Create the class
my_gui = SampleGUI()
# run the event loop
my_gui.run()
PySimpleGUI 2022-02-27T18:22:50Z
Sample Udemy Exercises
These links will get you to sample Exercises from the Udemy course. I'm still working my way through writing them. The final look and feel aren't done yet. It's a simple interface at the moment. The overall design of the pages will be the same with the hints and solution being hidden until you click them. We're getting towards the end of development, so polishing them up is happening soon. The focus has been on getting everything working end to end, which is done.
The Exercises are much like the individual lessons. They stand on their own. The point of each lesson is to teach you a specific topic in a narrow fashion. This allows students to skip around within the course as one lesson generally doesn't require the knowledge of other lessons. If some prior knowledge is needed, I tended to point it out in the lesson and briefly review it.
Lesson 37 - Image Element
This is the Image Element's exercise.
https://pysimpleguiudemy.herokuapp.com/Demo/Lesson37.php?password=demo
This exercise is a bit more complicated than some of the others. They all vary in the number of exercises and the complexity. This one was fun and I ended up expanding it into a Demo Program.
Lesson 15 - Output Popups
Some lessons have multiple exercises for you to do. There are tabs across the top of the page to allow you to access each.
https://pysimpleguiudemy.herokuapp.com/Demo/Lesson15.php?password=demo
Update soon....
Have been shooting to get the course updated by the end of the month. I'm going to be a few days late.
I think students will like these. They're not very difficult, but they're fun and teach you what you'll need in order to make your application. That's goal # 2 for PySimpleGUI... "You're successful".
Trying to hit both the fun and success goals.. and I think these do that.
BIG BIG Thank you to everything that's taken the course!! It's incredibly helpful to get some help with the project expenses. And thank you for the donations, the kind messages, and for being such a wonderful group of users! I read all the messages eagerly and I pass them along to the team.
Spanish Readme
A generous user offered to translate the Readme into Spanish! 🙏
PySimpleGUI has a global user base. The 3rd (sometimes 2nd depending on how you count) largest country using PySimpleGUI is Brazil. The United States is only a tiny sliver of the total community. Most PySimpleGUI users do not speak English as their first language. I'm thrilled to have some help in making PySimpleGUI more accessible and expanding the PySimpleGUI tent!
PySimpleGUI 2022-03-05T16:10:02Z
Back Soon....
I've been away from working on Issues and new features, still, as I work on the Udemy exercises and some business-related stuff. I'm anxious to get back to the core features and the new project additions. Sorry for such a long delay in dealing with support and new features. Lots I want to get done. Just have to get over a couple of hurdles to return. There's progress being made, just not in a visible way at the moment.
Thank you for your patience and of course, I'm always appreciative of the help Jason provides us all. I've never worked with a support engineer so talented.
The PySimpleGUI Catalog
One of the new additions to the project is what I'm calling "The Catalog". This is designed to replace Issue 10, the user screenshots. This feature is being added directly to PySimpleGUI via a PySimpleGUI utility being written called psgscreenshot
. This utility takes a screenshot of your application and "submits" it to the Catalog. Your submission is checked and if all looks good will be added to the Catalog. The check is to stop spam... It's not meant to discourage submissions.
If left completely open, I've no doubts that it would be flooded with spam or obscene material.... "this is why we can't have nice things" comes to mind.
Not a big deal... it's just how it is on the Internet.
Issue 10 is GREAT but suffers from GitHub's awful pagination problem. The Catalog also enables "Categories" for screenshots. If your application is a Game, you can submit it in the Games category. Then visitors can filter based on Category.
Wordle Demo
I was working on a Wordle exercise for the Udemy course, but it was turning out to be a little too complex. I decided to go ahead and make a GUI implementation and release it as a demo program. I would like to get more wanna-be-game-programmers giving PySimpleGUI a try to make games. I thought maybe this may catch the eye of a few users.
You'll find it in the Demo Programs section. It will be in the next release of psgdemos
as well. Maybe this weekend.
I've also added added it to the eCookbook on Trinket:
https://pysimplegui.trinket.io/demo-programs#/games/wordle
Disclaimer... I've never played this game so I may very well have it completely wrong. I went to the official NY Times site and played with the interface for a few minutes and then gave it a go. I realize now that I released it that there are probably a million Python implementations floating around out there, some likely written by Python experts. I'm not a Python expert. I'm a beginner so it's not going to be the shortest, slickest, most-Pythonic version you'll find. Hopefully, it meets my criteria of "it works".
You'll Need to Add Words
The Wordle demo only does the GUI portion. It takes input and checks against A WORD. Remainder of the game is left as an exercise for the reader.
If you make a full game, please post a screenshot in Issue 10, the user screenshots.
Udemy Exercises
The progress has been steady and I'm going to start releasing them this weekend. Not all 61 lessons have exercises for them, but over 2/3 do, so I think they're going to be a great addition even if they're not 100% complete.
Thank you to everyone that's taking and learning from the course! I'm been so happy that students have been happy. Thrilled to read the comments that it's been a helpful course. It's helping keep the project alive and thriving... again, thank you so so much for the support!
PySimpleGUI 2022-03-05T17:25:47Z
python
Versus pythonw
When Using Exec APIs
I noticed something this week that I've not seen before. It's likely because of how I start programs using PySimpleGUI and the Exec APIs.
The Exec APIs are a wrapper for the subprocess.Popen
call.
Disclaimer - I'm not a Popen expert.... I don't claim to be an expert in much of anything TBH (I suppose PySimpleGUI would be the thing I know the best). Maybe there's an option to Popen
that I'm not aware of that will get around this situation...
The Problem.... Running Subprocesses in the Background
I have over 20 PySimpleGUI programs that are running in the background at all times and launch numerous others throughout the day. I usually start these background programs by clicking on a button from one of my "Launcher" programs that are running all the time. I decided to break out these startups into a separate Python file this week so that I can start them from my taskbar. And that's when I noticed something I've not hit before.
If you startup a Python program using python
and that program starts subprocesses, it will not exit the program until the subprocesses exit ... I think this is the case because the program doesn't exit. If I double-click the .py file, I am shown a command window that stays open despite the program completing. If I close this window, ALL of the subprocesses it started then exit.
However, if I start this same program using pythonw
, then there is no command window that's opened. There's nothing shown at all because it's pythonw
which doesn't show a command window. This is what you want to use if you're launching programs from your Python program much like a batch file.
TLDR:
If you have programs you want to start using a Python program in a way that will not leave a shell window open, launch with pythonw
. It's particularly important if your program starts subprocesses.
PySimpleGUI 2022-03-06T13:26:04Z
Udemy Exercises Posted
Thrilled to finally get the interactive exercises posted to the Udemy course!
You will find a link to them under "Resources". It will take you to the exercises for that lesson.
Clicking the link will take you to a webpage with one or more exercises that focus on that lesson's content.
Not all lessons have exercises, but most do. Getting the remaining exercises completed and into the course is my top priority.
I think you'll find them to be unique among Python courses. I'm not aware of any that have in-browser exercises for GUI applications. PySimpleGUI is built into Trinket so it's an ideal platform for use with the course.
You can also use your local machine to write and run the exercises. The advantage to using an IDE like PyCharm is the code completion and docstrings. I tried to write them in a way that doesn't require a lot of typing of tedious boilerplate code and instead provide that code for you, leaving the important bit for you to write.
Enjoy! Thank you again for supporting the project. It's really appreciated.
PySimpleGUI 2022-03-06T16:03:31Z
Headsup - Closing Repl.it Account
I'm going to be closing my repl.it account. I've been a paying customer for quite some time and have been trying to get a rather serious bug fixed from them for a year. The bug reporting and tracking were simply non-existant when I started working with them on the problem. It was simply emails going around between people. It's been a disappointment as they seemed so promising. PySimpleGUI used to run quite well on their platform.... until it didn't.... and once it got to that state, it stayed there.
Trinket - The Preferred Platform for PySimpleGUI Projects
I'm also paying for a subscription to Trinket. Trinket is the winner in this case. They've provided excellent customer service. If I report a problem, it's been handled professionally and the communication has been consistent.
PySimpleGUI is part of the Trinket standard library now so all you need to do is import it. No setup at all required. It's why the Udemy exercises are all Trinket based... they work and I don't have to worry about users struggling because of bugs on their platform.
The PySimpleGUI eCookbook is hosted on Trinket as well as consisting of a series of Trinkets.
Unsure of Use
I can't tell if any of my project on Repl.it are being used. It's why I'm posting an announcement about it since I can't really tell if anyone is actively using my projects.
On Trinket, I can tell if anyone is accessing the Trinkets
It's always been shocking to go to the Trinket site, and without failure, every single time I've checked, someone has looked at many of the Trinkets within the past hour. Someone is always using them, a very good sign that it's a worthy investment. They're an incredible bargain. If you're looking for an online platform for teaching Python, Trinket's a winner.
Open a GitHub Issue if You're Impacted (or drop me an email)
I can't imagine anyone will actually be impacted by closing the account. If you are, please let me know by opening an issue or simply dropping me an email.
PySimpleGUI 2022-03-09T19:59:12Z
Threading Tip
I re-discovered using Window.perform_long_operation
as a way to easily start threads. What I had not really though through was the use of lambda for the thread target
parameter if the function has parameters. I haven't found many examples of people doing this. I've always used the separate args
parameter to specify the arguments. But for perform_long_operation
I don't supply an args
parameter and I wrote the documentation and example with the suggestion that a lambda be used.
One advantage of using a lambda is type checking / auto completion.
An Example from the "Top" CPU Desktop Widget
This is the code you'll find in one of the Demo Programs.
def CPU_thread(window:sg.Window):
while True:
cpu_percent = psutil.cpu_percent(interval=g_interval)
procs = psutil.process_iter()
window.write_event_value('-CPU UPDATE FROM THREAD-', (cpu_percent, procs))
I start this thread using this code:
The parameter window
is specified in the lambda.
Unpacking write_event_value
Easily
The way threads communicate with the event loop is by using the method Window.write_event_value
. Because only a single parameter is provided, I find myself using tuples to pass information back to the event loop.
Here's a technique to make getting those values unpacked easily.
In the example above, the call that communicate with the event loop is:
In my event loop, added this code to process the events from the thread:
elif event == '-CPU UPDATE FROM THREAD-': # indicates data from the thread has arrived
cpu_percent, procs = values[event]
If you use the expression values[event]
, then you'll get the data that the thread is sending to the event loop. You an easily unpack the tuple in the one line of code that has values[event]
on the right side. It matches up nicely with the call to write_event_value
PySimpleGUI 2022-03-22T13:50:32Z
Hoping for Weekend Release... Sorry for the Slowdown...
You may have noticed a slowdown in the normal rate of output for the project in the past few weeks. I've been experiencing some medical problems that has had an impact on my ability to work. I'm doing all I can to keep things going as much as I can at the moment and hope to get back to "normal" soon. I'm sorry that the pace has slowed, temporarily.
A weekend release would be a nice thing to get accomplished as well as fixing up some of the repos that are part of the project. It's a high priority to get those cleaned up. I've been working on them but haven't pushed my changes up yet.
Temp Window Changes
There are a number of changes that could use some runtime to ensure they're working OK before the next release.
One change was in how temporary windows are handled. Some tkinter calls require a window be created before they can be called. These include:
Text.fonts_installed_list()
Text.char_width_in_pixels()
Text.char_height_in_pixels()
Text.string_width_in_pixels()
Window.,get_screen_size()
clipboard_set()
clipboard_get()
popup_get_folder() - When using the no_window parm
popup_get_file() - When using the no_window parm
The Mac had a problem with the way PySimpleGUI made these temp windows. The summary is that you cannot create a Tk()
object, destroy it, and then create another one. This causes the Mac to crash. It's a really bad bug to have, but one they clearly have and thankfully there's a workaround in the code now.
Instead of destroying the Tk
object it is now used as the "Hidden Master Root" so that one and only one of them is created in a single PySimpleGUI application.
Window.start_thread
is a New Alias for Window.perform_long_operation
It made sense to expose what the method is actually doing, which is starting a thread on the user's behalf. Both names will work equally well.
Thanks for the support
And, as always, thank you, everyone, for the kind messages, thank you for helping fund the project through the Udemy course, a huge thank you to Jason for providing the best support of any product I've been a part of 🧙♂️, and thank you to everyone that says "thank you" for the help he's providing to all of us 🙏.
The PySimpleGUI users have made this experience far far beyond anything I could have imagined. You make it easy to want to work as hard as I can.
PySimpleGUI 2022-04-01T10:57:20Z
Udemy Sale
The past 8 days there's been a $99 sale for the Udemy course. As always, the coupons are available at the top of the readme and documentation.
Udemy makes running promotions more difficult than it could be. There is a limit of 3 coupons per month and at a $99 price, they only allow me to create one that lasts for FIVE days. I'm able to get a 31 day coupon if I price it at $139.
It takes a bit of time to update the coupons as there are multiple markdown documents as well as the PySimpleGUI code itself that must be updated. It's not a huge problem, but it does get a little time consuming. Doing my best to make sure the coupons don't expire entirely by adding them to my calendar.
There are a couple days left on the current coupon. I'll run another $99 after it expires since I got a new batch of coupons this morning.
Slowed Progress
I'm really sorry about the pace being slow again this week. I'm hoping to get past these medical problems so that I can spend more time dedicated to the project. I've been too ill to maintain the normal pace. I really miss working and interacting with our incredible users! Really hoping to get the pace up to something reasonable this weekend.
"It's Circular"
I find myself saying this phrase more and more when users say they've been inspired by something related to PySimpleGUI. I get inspiration from hearing others are inspired. I believe motivation really is a feedback loop.... that's been one of the discoveries that's accompanied this project.
I know I've said it many times, but your messages, however small they may seem to you, have a large and lasting impact. I think this is true not just for me, but for everyone that you take a moment to thank or show appreciation for something they've done. I share the messages with the other PySimpleGUI team members too since they've earned compliments as much as I have. My friends get copies on occasion too. You're a remarkable user community! It's exciting to share the experience.
So, if there's a co-worker, a friend, a stranger that's done something nice that you've wanted to say "thank you" to but maybe are shy or hesitated for some reason, understand that your message can really have a big impact. It doesn't have to be a long over-the-top message. I got a simple compliment on YouTube this morning that said:
This Python module saved my life in a project I'm doing. Thank you so much
I've been high-on-happiness since I read it. It'll stick with me the rest of the day, and likely tomorrow too.
Gratitude is one of life's secret weapons. You'll get something from speaking up too. There have been numerous studies that show a link between happiness and gratitude. Once I learned that, I began a habit of take a moment every morning to write a list of things I'm thankful for. It's had a positive impact on me. Maybe it will you too.!
Improved Scrollbars!
One of the areas that PySimpleGUI can be visually improved is scrollbars. There has been a lot of work done in the past to make it easier for you to create custom buttons, easily add custom elements using a Graph
element, but scrollbars are not currently something that PySimpleGUI enables you to easily change the appearance of. That's going to change.
Tanay has been investigating the use of TTK scrollbars rather than TK scrollbars, so hopefully, it's a feature I'll be able to get into the code soon!! One Demo Program that I've been designing recreates the Discord GUI. Until the CustomTitlebar element was added, it wasn't possible to get close to a match. The next biggest problem area is the scrollbar... thus the work Tanay's been doing on getting us better looking windows.
PySimpleGUI 2022-04-01T17:29:14Z
Udemy Updated Pricing
Sorry for all the Udemy coupon and pricing announcements. This change will help with cutting down on all the activities required. The pricing of the course has been changed to $139 all the time now rather than using coupons for that price. This enables me to make $99 coupons that are good for a month at a time so that I don't run into this funny situation where I run out of coupons every month.
You'll always find the latest coupon in the readme, cookbook, documentation, call reference.... and in the PySimpleGUI code itself.
I really appreciate the students and the many individuals that are sponsoring and donating to the project. You're making it possible for the project to stay afloat and I'm able to sponsor some of the projects that PySimpleGUI uses in the demo programs.
PySimpleGUI 2022-04-02T22:10:37Z
4.58.0 Tomorrow
Really really hoping to get 4.58.0 released tomorrow!
I'm excited about the features in this one (I think I've said that about the previous 57 releases too). It's nice to be able to contribute again.
As always, you can access the latest set of changes right here on GitHub. Type psgupgrade
from the command line if you pip installed PySimpleGUI or you can use the red upgrade button when typing psgmain
from the command line or by calling sg.main()
from your code.
bind
Has a New propagate
Parameter
Added today is a handy new propagate
parameter to both Element.bind
and Window.bind
. The default is True
. By setting it to False
, you can intercept events prior to them reaching the underlying tkinter widget.
The example that prompted this enhancement was the desire for the Tab key to move the focus from a Multiline
element to the next element. If you don't set the propagate
parameter to False
, then the Tab will be added to your Multiline
element in addition to you getting an event for the Tab key is pressed. It'll be interesting to see what new creations will come from this.
Focus Features and more
There are a number of new Element methods that were added that help with focus control.
Fixes for the Mac and Windows and plenty of other changes that I'll put into the release notes tomorrow (assuming I get through all the testing and don't hit any big problems)
PySimpleGUI tip of the day.... keys
Don't have to be strings!
Every now and then I spot some code that has a string split call in order to differentiate between 2 keys... that a string is used to encode multiple keys. For example CB-1, CB-2, CB-3 for 3 checkboxes. Of course strings will work, but there's a simpler and easier way...... tuples.
Instead of strings that need to be split, use a tuple that already is a split. "CB-1" and "CB-2" become ("CB", 1) and ("CB", 2).
They're particularly good to use when you've got a list comprehension in your layout
import PySimpleGUI as sg
layout = [ [sg.Checkbox(f'Choice {i}', key=('CB', i)) for i in range(1,3)],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Go':
print(values[('CB', 1)])
window.close()
Tip 2 - Extra Nesting in Layouts is OK
While on the subject of list comprehensions.... last year I relaxed the nesting rules around layouts. Previously layouts had to be a list of lists. It made a couple of constructs a little more difficult than they needed to be.
For example, if you wanted to instead of having checkboxes on the same row, as in the example above, wanted to have them on separate rows, then you would need to do some tricks to make that happen. You could use the star (unpack) operatator, but that's not always possible depending on the version of Python you're using.
Now you can simply have an extra set of brackets and they'll be ignored.
This is a valid layout:
layout = [ [[sg.Checkbox(f'Choice {i}', key=('CB', i))] for i in range(1,3)],
[sg.Button('Go'), sg.Button('Exit')]]
It produces this window:
Thank you for the support!
I can count of PySimpleGUI users to be positive and supportive. Time and time again I see words of encouragement right here on GitHub inside bug reports. I've never experienced anything like this project before and it's been such a wonderful part of my life. Thank you for making it the magical and unbelievable experience it's been.
PySimpleGUI 2022-04-04T00:20:03Z
Tomorrow....
4.58.0 is going to be posted tomorrow.
I've got the release notes done and have been testing the release today. The hangup has been the Linux window location problem that's shown up this week.
https://github.com/PySimpleGUI/PySimpleGUI/issues/5309
I've spend today experimenting with ways to create and move the window in ways that are "stealthy". The problem is that Linux doesn't behave the same as Windows, of course. I've not been able to get the window size when the window is withdrawn. I have been relying on the Alpha channel was a way to get around the difference, but that seems to be broken now and I've not been able to find a way around it. If the window is withdrawn, then the geometry returned by tkinter is 0,0 on Linux.
On Windows I get:
738x626+338+338
And on Linux:
1x1+0+0
Rather than continuing to hold up the release, I'm going to go ahead and post it with this problem left unresolved. Sorry for the continued slips in getting the new code released.
PySimpleGUI 2022-04-04T22:08:43Z
4.58.0 PySimpleGUI 3-Apr-2022
A little of this and that release
More focus on focus
bind
methods improved with propagate
parm
Visibility losing settings fix
-
execute_get_results
Added checking for timeout error to instead of showing an error popup as it's not truly an error in this case -
Checkbox
Added cast to bool of default parm in case user passes in an incorrect type -
ButtonMenu.update
addition of button_text parameter. Enables changing text displayed on the ButtonMenu. Should have been an original feature. -
Open GitHub Issue GUI Tabs use 2 lines now. Added tab asking where found PSG.
-
New symbols
SYMBOL_CHECKMARK_SMALL
&SYMBOL_X_SMALL
-
ButtonMenu.Click
- Added click PEP8 aliasButtonMenu.click
-
Automatically add timeouts to user reads if a debugger window is opened. Debugger for multi-window applications still needs to be added
-
Window.start_thread
a simple alias forWindow.perform_long_operation
. It's clearer what's happening with this alias. -
bind_return_key
parm added to Spin element. If element has focus and the return key is pressed, then an event is generated. -
Event generation for disabled elements
-
If an element is disabled, then don't generate events (fixed specifically for Input element). However, if a Browse button fills in a disabled element, then an event should still be generated
-
Don't generate events if no files / folders selected using File or Folder Browse buttons. If cancel is clicked then no longer generates an event.
-
-
Fix docstring for image in the Titlebar element. Incorrectly said an ICO file can be used. Must be PNG or GIF
-
Windows-specific code that enables the PySimpleGUI supplied icon to be shown rather than the python.exe logo
-
Removed all temporary Tk() window creation calls
-
Instead create the hidden master root.
-
These were required for operations like getting the list of fonts from tkinter, the screensize, character width and height. This way one and only one Tk window will ever be creeated
-
The reason for the change is that the Mac crashes if multiple Tk() objects are created, even if only 1 at a time is active.
-
-
image_source
parm added toButton
-
It can be either a filename or a base64 string.
-
This is like the Image elements parms
-
-
Graph element doc string improvement. Describes the mouse up event.
-
Improved support for focus
-
Element.get_next_focus
added. Returns the element that should get the focus after the indicated element -
Element.get_previous_focus
added. Returns the element that should get the focus after the indicated element -
Better exception error reporting for the Element focus methods. Uses popups with tracebacks now instead of prints
-
-
Window.widget_to_element
returns the element that a tkinter widget is used to implement (it's a reverse lookup) -
Element.widget
added. It's a PEP8 compliant property that returnsElement.Widget
-
Element.key
added. It's a PEP8 compliant property that returnsElement.Key
-
Simplified Radio, Checkbox, Slider creation. Moved the command parm outside the creation and instead made a config call.
-
Visibility fix
- Expand and other settings were being lost when element is made invisible and visible again.
-
propagate
parameter to the bind methods. Used to tell tkinter whether or not to propagate the event to the element / or window -
Canvas.update
method added so that aCanvas
can be made visible/invisible -
Removed the need for
tk.scrolledtext.ScrolledText
by adding a vertical scrollbar to a Text widget. Getting ready for addition of ttk scrollbars! -
tooltip_offset
parm added toset_options
as a way to set tooltip location (a hack to get around an 8.6.12 bug) -
Table
andTree
elements new parameters-
border_width
- the border width for the element -
header_border_width
- the width of the border for the header -
header_relief
- the type of header relief to use
-
-
Table
andTree
elements are now excluded from grab-anywhere so that headers can be resized without moving the window
Finally got the 4.58.0 release posted!
But.... victory was quickly dashed when I discovered the WORDL demo program stopped functioning.
I'm trying to find what I broke and quickly get a dot release posted. The day is quickly coming to an end so it may be tomorrow before a fix is found and a patch is added.
PySimpleGUI 2022-04-05T14:19:59Z
The psg
Commands
A tip-of-the-day for you....
When you pip install PySimpleGUI, you get not only the PySimpleGUI package to import into your code, but your system has several command-line utilities added. These include:
-
psgmain
-
psgissue
-
psgupgrade
-
psghelp
-
psgver
-
psgsettings
Note that you must be using version of PySimpleGUI that not local to your application. It need to be the one that's been pip installed. This is because of how the command-line applications are installed. If there's a PySimpleGUI.py file found that's not the pip installed one, then the command will appear to do nothing.
Let's run through these
psgmain
- Launches sg.main()
The same as calling sg.main()
from your code. You'll see the PySimpleGUI Test Harness, your gateway to PySimpleGUI goodness.
psgissue
- Opens the GitHub Issue GUI
A GUI front-end for submitting a GitHub issue.
This GUI is much easier to work with than the online form. It fills in all of the version information for you.
psgupgrade
- Update your pip installed version of PySimpleGUI to the one on GitHub
This command is equivalent to clicking the red "Upgrade PySimpleGUI from GitHub" button that's found in the main test harness.
Your pip installed version will be replaced with the latest and greatest version that's on GitHub.
psghelp
- Display the SDK Call Reference Help Window
This window is also available by using the main test harness.
psgver
- Display a window with version numbers
If you're asked for the version numbers of your system, then this is an easy way to get them. The values are shown in a scrolled popup and they're also placed on the clipboard so that you can immediately paste them into an issue or elsewhere.
This is another window the is accessible through the test harness.
In the screenshot I pasted the value of the clipboard so that you can see that it contains the same text as oringally displayed.
psgsettings
- Access the global PySimpleGUI settings
Another window that's accessible through the test harness, but made easier to access using thie command. It's where you can see your gloabel default theme for example. In the screenshot I changed the global theme and then ran the main test harness so you can see that it changed it for all windows (unless a window didn't use the default. The Mac settings are one that don't use the default and why you saw a dark red window instead)
Collect them all!
These are the basic list of commands the accompany PySimpleGUI itself.
The psg*
naming convention is used for utilities that the PySimpleGUI project creates and publishes.
psagresizer
- One example is the psgresizer
utility.
I never have program icons and most all other graphics outside of the main utility. The problem with this strategy is the requirement to encode the images in base64. This utility makes it trivial to convert your image to PNG, resize it, and then leave a Base64 encoded version on the clipboard, ready for you to paste into your application.
psgdemos
- THE most important of these, the Demo Browser
By far the PySimpleGUI utility I use the most is the psgdemos
Demo Browser. I use it many times a day. I can't remember exactly which of the 300+ demo programs use specific elements or options, so I rely on this tool to do searches and enable me to edit and run the programs easily.
PySimpleGUI 2022-04-06T01:32:54Z
4.59.0 PySimpleGUI 5-Apr-2022
An oh sh*t release due to yesterday's bug
New force modal Windows option
Test harness forces all windows to be modal and is no longer keep-on-top
-
Removed ttk theme from the test harness. Forgot that I had changed it for testing.
-
Fixed bug where disabled state was not correctly saved in update methods, causing events to not be generated (Thank you Jason, again!)
- Changed numerous elements, not just the
Input
element that demonstrated the problem
- Changed numerous elements, not just the
-
New
force_modal_windows
parm added toset_options
-
Forces all windows to be modal
-
Overrides the
disable_modal_windows
option -
Used in the
main()
test harness to ensure all windows are modal so no window is accidentally lost
-
-
Test Harness changes
-
Set
keep_on_top=True
for all popups and windows created by test harness -
Set the main window
keep_on_top=False
. Ensures that all windows created by it should never be hidden. This is a somewhat experimental change. Let's hope for the best! -
Forced all windows except for 1 non-modal popup to be modal. This also should ensure no windows are "lost" behind the main window
-
Let's Hope ....
REALLY hoping I didn't mess things up further than yesterday's release which is why there's a 4.59.0 release posted today.
It's been a long day, I'm really tired, and thus the odds of something going badly go up as well.
Linux... the new Mac?
The Mac has been the problem child of PySimpleGUI in the past few years. Linux is starting to "feel" to me like a similar situation.
Much of the time today was spent getting hung up on a number of Linux problems. I purchased a license for a Linux distribution this evening with the hopes of it providing for a better experience for both me and the PySimpleGUI users in the future. More on this in the next couple of weeks as I work with the developers a bit more. I don't want to make any kind of announcements until a few more unknowns are known.
One problem I'm trying to come to terms with is the fact that "Linux" is much more difficult to define than "Windows" or "Mac".
It's a complex landscape as was just demonstrated with the "Jumping window" problem that started to happen on "Ubuntu". I'm seeing a problem on a system that has had no upgrades to Ubuntu nor PySimpleGUI, but a problem has suddenly appeared. I suspect that something was auto-upgraded, silently. I suspect it's got something to do with GNOME as that's the area that is in common among the failing systems.
Thank You!
Every day there is at least one remarkable interaction with a user. It's wonderfully strange in a positive way. The reason I say "thank you" so often is because it's deserved and I truly am grateful. The support, the interactions, the kindness are unlike anything I've experienced in my life.. It's hard not to be grateful. It's appreciated and you're the reason I look forward to working on this project every day. If it wasn't so enjoyable, I wouldn't look forward to every day the way I do. I have you all to thank for that
PySimpleGUI 2022-04-06T19:34:28Z
'blocking' Parameter Added To sg.Print
(The Debug Output Window)
I'm excited to say that a new parameter has been added to the "Debug Window"! Yea, I know, I'm easily excited or amused.... but this one really is good!
I've had this crazy dream of a generation of Python programmers in the future that never sees one of these:
Like most developers, I love being able to simply print information to help with debugging. I rely on them as much as anyone else. The print
equivalent in PySimpleGUI is the call sg.Print
. You'll find a large section in the Cookbook dedicated to character output
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-printing
A quick summary is that sg.Print
is equivalent to print
. Familiar parameters like end
and sep
are there and work as you would expect them to work. You get a number of bonuses like color output.
In the past, if you wanted to use sg.Print
as the only way information is shown to the user, then you would need to add a popup as the line of code to ensure that your program didn't end and thus close the window, losing the information. Now you'll add a blocking
parameter to the last sg.Print
call you make.
This program prints the number 0 to 200 in the Debug output window. If a number is prime, it is printed in red.
import PySimpleGUI as sg
def prime(num):
a=[]
for i in range (1, num+1):
if (num/i).is_integer():
a.append(i)
if len(a)==2:
return True
else:
return False
for i in range(200):
sg.Print(i, c='white on red' if prime(i) else None, end='')
sg.Print(', ', end='')
sg.Print('Finished!', c='green', blocking=True)
Notice the last line of the program sets the parameter blocking=True
so that execution is blocked until the user takes an action.
Just like before this parameter was added, you can close the Debug Window at any time. The next time sg.Print
is called, a new window is created and the printing continues.
I hope this helps ease us to a more modern world world that still has the convenience of a print
statement.
PySimpleGUI 2022-04-08T01:36:39Z
An "It's about time..." feature
This week Tanay and I have been looking at the TTK Scrollbars. I want to upgrade. This time Tanay learned and then taught me TTK. It's been a difficult set of Widgets for me, but I'm getting there....
I think these new scrollbars are going to be a fantastic addition.
I just got them working today with the Multline
element and have been designing the changes to the SDK. I'm excited!
I'm providing as much control as possible, in a super-simple, easy to use PySimpleGUI way. As you can see, by default they tie into the theme, but you'll not be limited. I'm ready to see what can be done. This will improve the overall quality of the programs considerably.
Discord GUI
I'm an "applied computing" kinda person. I need a goal that's concrete.
One of those goals has been to build a Discord clone. This scrollbar was a missing piece.
If you look at the right 1/2 of a Discord window, you'll see something like this:
Example from previous comment....
Here's is how the program I posted in the previous comment looks using the new themed scrollbars.
PySimpleGUI 2022-04-09T02:11:53Z
New Scrollbars for Multiline
, Listbox
, Table
and Tree
I just checked in version 4.59.0.3. It contains changes to these 4 elements. All of them use ttk Scrollbars rather than TIK Scrollbars.
It's an experimental start. There are 10 new parameters for each element that care just for the scrollbars. The plan is to also have these parameters available a the wWindow
and overall system (via set_options
) levels.
I'm out of time tonight to document and explain how a small portion of it all works. I wanted to get a release posted so users can play with it over the weekend as I continue working on the feature.
The default values for the settings are roughly:
## TTK Scrollbar Settings
if sbar_trough_color is not None:
self.scroll_trough_color = sbar_trough_color
else:
self.scroll_trough_color = theme_slider_color()
if sbar_background_color is not None:
self.scroll_background_color = sbar_background_color
else:
self.scroll_background_color = theme_button_color()[1]
if sbar_thumb_color is not None:
self.scroll_thumb_color = sbar_thumb_color
else:
self.scroll_thumb_color = theme_button_color()[1]
if sbar_thumb_depressed is not None:
self.scroll_thumb_color_depressed = sbar_thumb_depressed
else:
self.scroll_thumb_color_depressed = theme_button_color()[0]
if sbar_arrow_color is not None:
self.scroll_arrow_color = sbar_arrow_color
else:
self.scroll_arrow_color = theme_button_color()[0]
if sbar_arrow_background_color is not None:
self.scroll_arrow_background_color = sbar_arrow_background_color
else:
self.scroll_arrow_background_color = theme_button_color()[1]
if sbar_width is not None:
self.scroll_width = sbar_width
else:
self.scroll_width = 10
if sbar_arrow_width is not None:
self.scroll_arrow_width = sbar_arrow_width
else:
self.scroll_arrow_width = self.scroll_width
if sbar_frame_color is not None:
self.scroll_frame_color = sbar_frame_color
else:
self.scroll_frame_color = theme_background_color()
if sbar_relief is not None:
self.scroll_relief = sbar_relief
else:
self.scroll_relief = RELIEF_RAISED
Sorry that that default is really skinny scrollbars (10 pixels).
I would describe TTK as........ "strange". No offense meant to all to the tkinter team and what they do to make the magic happen I have so much respect for that team.
One of the oddities is that not all parameters are available. Your choice of the TTK Theme determines which parameters are available for you to modify. This table tells you which of the ttk scrollbar settings can be modified depending on the TTK Theme you've chosen.
Sorry for being brief and perhaps sloppy with the code tonight. I want to I've users a chance to play with this code so I'm posting what I've gotten done so far. I'm burnt toast tonight, so this is the best I've got to offer at the moment. If I can put in enough time this weekend and can figure out how to do some of the operations I want to do, then I may be able to release the final code very soon.
Let's hope for the best!
Special Thanks
An extra special "Thank you" today to Tanay (@Chr0nicT) for his help in not just these TTK scrollbars, but in helping me with a number of Linux problems.
Not only do I ~~think~~ know that PySimpleGUI users are exceptional, the project's team members are also really special people. I'm lucky to have brilliant and talented help. Brovo on a job well-done!
PySimpleGUI 2022-04-10T02:58:17Z
Experimental Screen (Window) Capture
Version ~~4.59.0.4~~ 4.59.0.5 was just posted and has the result of today's work on the screenshot feature.
It's FAR from perfect as it has some positioning errors, but it's got the basics of a built-in screen capture capability. "The Catalog" is the bigger feature. I'm taking an evolutionary approach to the feature.
It's late and I need to stop for the day. I wanted to give everyone something to experiment with even though it's far from complete.
Use the "Global Settings" to set up the "Window Snapshot" settings.
There are 3 things you'll be interested in in this window.
-
The "hotkey" that will trigger the snapshot
-
The folder to store the screenshot
-
The filename to store the image
Settings Reworked
I reworked the window in general, using frames to store each section. Also used expand_x on all sections and like the way it turned out as a result. It's a little larger than before, but I thnk it looks nicer.
Specifying the HotKey
You've got a choice of manually creating the banding string of using a series of Combo elements to make the string for you. The screenshot shows the Left Windows Key combined with F9 to trigger the capture. The new propoagate
parameter for the bind
methods played a critical role in this whole effort. It's wonderful to be able to disconnect key presses from the rest of window!
Filename and Foler
The fiulename's extension will determine the format the that image is saved in. You don't need to do anything further to specify the format. The "Auto-number" feature is not yet implemented. The idea here is that you'll sppeciy a starting number and filename. Each capture will increment the counter and add it to your filename
The First Step
This is the first step in implementing The PySimpleGUI Catalog and in providing a screen-capture capability. We're still in the very early stages.
Rather than wait until a standalone utility is written that will do the capture and uploading of the image, I decided to do a quick-ish implementation
A Word About PIL
I want to stress while PUL is being used by PySimpleGUI directly in this test, PIL is not, nor will it be, a requirement for PySimpleGUI to function. Even in this est, PIL is imported only when a capture is attempted. this will keep the overall startup time for PySimpleGUI as low as possible.
I expect that I'll be adding a clipboard integration as well for my own personal use. One of the benefits of working on my own tools is that I get to benefit just like the rest of you do. My saved images folder for PySimpleGUI has over 5,500 images in it. I probably copy and paste 10 for every 1 images I save locally.
I could see having a feature that's controlled through the clobal settings that will place a copy of the window onto the clipboard every time the program starts up so that pressing a hot key to copy the window can be eliminated.
OK.... that's enough for one day.... have a good night everyone!
PySimpleGUI 2022-04-10T12:31:02Z
Mentors, Managers, and Tools
I've debated about this announcement for a while. I want these to be factual, topical, and not too much of an opinion. I also don't want t come across as a know-it-all because I'm FAR FAR FAR from that. I know a few things, but am clueless about plenty.
I don't know how many nor what type of people read these posts and I would likely be mortified if I knew, so I generally pretend that it's not many people and that they're the same, kind, compassionate people that post everyday in the issues.
Ageism is a thing, particularly in tech in Silicon Valley. I've seen it first hand. One of the side effects of this problem is that young managers don't get the benefits that I got working on startups.... exposure to mentors and good, older managers.
I've got the best mentor I've ever had at the moment. He's different in that I don't work for him directly or in his organization. It's more of a friendship. Mentors are magical people.
Managers can be too. Before I got off of social media, almost entirely, I saw a lot of advice about managers. One article revealed that the big secret about software engineering in companies is that "no one cares". It was troubling and sad to read.
It's said that "students remember their favorite teacher". I think the same is true for managers.
My background is smaller startups. Some had 5 people when I joined. What I like about these is that they're like families. You also are expered to "do whatever it takes". If the door needs answering, you answer the door. You don't do it because you have to, you do it because you want to.
At one of these companies a much older person was in charge of engineering. He wasn't the same kind of hands-on person that the rest of us were. At first, I didn't get it. I didn't understand why he was there. Within a couple months I more than got it. He was "Head of Wisdom". If it happens in software organizations, he's seen it at one time or another. Today many companies are missing these types of people in leadership positions.
Spot Bonuses - A Tool
The reason for this message is specifically to talk about this tool that managers have that few use. I had a good manager that I worked for that taught all of us that worked for him to use this tool.
The concept is simple... if someone does something outstanding, you, on the spot, reward them. It's usually a little bit of cash, maybe a few hundred dollars, and definitely recognition (publicly or privately, but something should be said). Money's a tricky thing that I don't want to dive into. It can be nice though to be able to grab a few things from Amazon for having done something good to help your team.
Most of us came up through the ranks to become managers. We were once junior software engineers and over the years worked our way up. If you're lucky, your manager is teaching you about these simple but effective tools. But perhaps now with a vacume of great leaders in companies, these tools are not taught.
My experience is that these simple tools work. They get the message across that you care enough about the person and their contribution that you recognize it and want to celebrate their good deed. I'm being sincere here.... it's not a cheap parlor trick. I truly want the person to feel valued. I know what it's like personally to feel valued and I want the other person to experience that feeling because they deserve it.
I really hope this message is received in the way it's intended... as a way to share one of the things that I learned that's helped me over the years.
There are companies that care... there are engineering managers that care. Sure, there are some terrible ones, but they don't represent 100% of the organizations. If you're a new manager, use these simple tools to demonstrate that you value your team members.
PySimpleGUI 2022-04-11T07:29:29Z
Today's Wrap-up
The past few days I've gone down some paths that I really didn't expect, but this happens from time to time.
A few have bugs, some have interfaces to the system settings to complete. There are 3 primary ones
-
TTK Scrollbars
-
Debug Print features
-
Screencapture
Screencapture
Part of "The Catalog" project, this one has been on the the table for quite a while. It took an unexpected turn that I like. More soon
It includes an exhaustive list of tkinter stings that can be used for mapping, tkinter_keysyms
. I'll be sure and add this to the docs. Here's a print of it using the Debug Print:
Here's the new system settings that shows entering the bind manually and the same bind using the combo boxes with these keysyms
Debug Print
I've wanted the blocking
parameter for a while now.
That was added several days back. What I didn't see coming was this "pause" feature that popped up yesterday as I was debuggs. Information was going past faster than I could keep up. Being able to simply "pase" the entire program while I look at the output was exactly what I needed so it was added.
You'll find it is used in the changes to the system settings for the screen capture keystroke specifiction.
More on this feature later
TTK Scrollbars
This came out of left field after Tanay did a bunch of research on TTK. Sometimes feature happen like this.
I would like to add these to the system settings screen so that you can define them there and not have to set them in your app every time. Maybe you're a fan of a 10 pixel wide scrollbar. I think it would be nice to set that once in the system settings. More work is needed to finish this feature... including making it possible to GO BACK to the tk scrollbars!
Thanks for your patience
I know there are a number of import bugs to fix. I'm working on those too. I'm not talking here about the hours / days I spent setting up several Linux environments.... on purpose....
Just know that your requests for help and enhancements as not put on indefinite hold. They're being worked too.
Hope everyone had a wonderful weekend!
PySimpleGUI 2022-04-11T17:02:21Z
Bit off quite a bit....
It's been so fun to be able to work on PySimpleGUI again. There was a period when I had to slow down quite a lot and it's been fantastic to be able to do anything.
However, the result was that instead of taking on ONE feature change while supplying support, I done in and did 3 simultaneously and was a bit overly ambitious at the same time. I am adding some of these settings to the Global System Settings so that you don't have to call set_options at the start of every program or always set a setting in your Window call. The ttk scrollbars are one of those. I am making it so you can enabled them from the system settings so that all windows you create, including popups, will have these new scrollbars.
The previous announcement mentioned the 3 big items on the current work queue. As I'm adding the ttk scrollbars to the Column element, I'll also take a look at the problem recently opened for the column element.
The Catalog
Once the Screenshot work is completed, then the hook into the Catalog project can be added.
PySimpleGUI 2022-04-12T17:43:08Z
Screenshot Checked In....
https://user-images.githubusercontent.com/46163555/163019353-2730bfb5-fa93-4197-8deb-12d49f968520.mp4
I've got the basic screenshot functionality into the PySimpleGUI code. Here you can see a demo of it.
I'm moving frustratingly slow today having woke with a high fever this morning. Taking lots of breaks, but determined to keep moving forward. It's been fun to get back to working on the code again.
Thankfully Jason, the best support engineer on the planet, has been taking excellent care of everyone.
Debug Print
I've got a known problem with the Debug Print. It works OK if using the original features. The 2 new features are the blocking
parameter and a new "pause" button that allow you to pause the output. I know where and what needs fixing up. It's just a matter of time.
TTK Scrollbars
No new news except I've determined that there will be a system setting to control this feature overall, much like there's a system-wide Theme setting. This way you won't have to specify in every one of your PySimpleGUI programs if you want the new ttk scrollbars or the old tk scrollbars. I'll have a set_options
call available as well should you want to control it in each program.
Honestly do like to make you the center of the attention with this project. "You're my customer now" wasn't just a readme phrase, it's how I view the project. If your life is easier, there's less chance of errors/problems and higher chance of success. It's also more fun if you don't have to set stuff every single time... so, both of the project goals are met... fun and your success.
Thanks for the messages!
I've gotten lots of really great messages the past week. Some with a donation, some in email, some elsewhere on the net. It's nice. Certainly is motivating for me and the other team members. It works with other people too 😉
Fantastic Repos!
Thanks for posting screenshots! I try to take a quick look at some repos on GitHub every now and then and they're so impressive to see. Your experience / skill level plays no role in how impressed I am. I like the complete beginners as much as veterine engineers. I've written about that a number of times here that I often find some of the most innovative and unique ideas from beginners. Thank you for sharing with the world! I know others get a kick out of seeing your work too.
The reason for the screenshot feature and "The Catalog" project is so that you can share easier and with an even wider audience.
Taking another break... hopefully back in a short while today.
PySimpleGUI 2022-04-13T08:27:29Z
PySimpleGUI Developer Tip of the Day
This one isn't going to benefit your user as much as it will you the developer.
All of the new programs I write now have these 2 features in them that have made life programming PySimpleGUI applications SO MUCH better!
This feature is all about understanding what's running and editing your code.
The Steps
Here are the steps you'll take are:
-
Place this parameter into your
Window
creation:right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_VER_EXIT
-
Add these 4 lines to your event loop:
elif event == 'Edit Me':
sg.execute_editor(__file__)
elif event == 'Version':
sg.popup_scrolled(sg.get_versions(), keep_on_top=True, non_blocking=True)
That's it.
What Does It Do? (hint - right click menu)
Here's a sample program that's been modified:
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout, right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_VER_EXIT)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
elif event == 'Edit Me':
sg.execute_editor(__file__)
elif event == 'Version':
sg.popup_scrolled(sg.get_versions(), keep_on_top=True, non_blocking=True)
window.close()
The window itself doesn't change the appearance... the magic is the right-click menu
Version
The version choice pops up a window that's non-blocking so your program will carry on as if nothing's happened. The way I've coded it in the example, I see this:
I run with versions of Python 3.6 through 3.11 and on my system at any one time there are at least 21 PySimpleGUI programs running in the background. If something goes wrong with something I've launched from the demo browser or PyCharm or ??? Who knows what version of what is going to be used. I use both local copies of PySimpleGUI.py as well as pip installed ones. I need this popup to understand what's running.
Edit Me
Choose this and "magically" this code shows up in my PyCharm editor. No other action is
needed than right click and choose "Edit me". It saves me SO MUCH TIME! It doesn't matter if I've copied the file somewhere because I'm using __file__
to get the filename to edit.
Setting Up Your Editor
You9 will need to open the PySimpleGUI system settings to set up your editor. It won't take more than 2 minutes.
If you pip installed, then you can use psgsettings
to go right to the settings window. If not, just add a call to sg.main()
to the top of your program. and then choose the button "Global Settings" from the main test harness.
You'll end up with something like this:
Or if you're running the newer unreleased 4.59.0.x
Look for the Editor Settings section and fill in the command to launch your editor. Also fill in the "For Format String" so that if you ever get a PySimpleGUI error popup, you can click the "Take me to error" button, a feature I use a LOT.
These Lines of Code "Close the Development Loop"
The reason I built all this is to remove the need for the command line, for searching for files or doing any work at all. We're using a computer, damnit, and I want it to do that kind of busy-work. I've got things to do, features to write!
These features, the editing, the error popups, the version informal keep you in the PySimpleGUI ecosystem at all times. I don't see a need to leave it except using your editor/IDE.
The lines of code are always the same.. just copy and paste them. Once your editor is setup in the PySimpleGUI System Settings, you never have to touch that part.
PySimpleGUI-guy/gal says "TRY IT"
PySimpleGUI 2022-04-16T12:50:30Z
Zig-zaggy Path
The path forward has had some zigs and zag but the direction remains forward.
New Demo Program - A user's master Settings file
While adding a new Demo Program yesterday I created a new PySimpleGUI theme to test it. The concept of the demo is to provide a design pattern that mimics the PySimpleGUI "Global Settings" since the PySimpleGUI one is meant for internal data and is administered through the Global Settings window (see below).
I liked the theme enough to add it to the standard themes. It's called "Dark Grey 15".
Here's how it looks in the Demo Browser
And this is the "Demo All Elements Simple"
I had completely forgotten about setting my global theme to this new built-in theme until I launched a few of my standard utilities and they all looked different!
Global Settings
The Global settings window is getting a rework since the number of options is greatly expanding. Here's how it looks with Tabs. The screenshot I posted in the last announcement used Frames
One thing that I've found to be so much fun when using PySimpleGUI container elements is how downright trivial it is to move among them. Going from Frames to Tabs took under 2 minutes to switch. I changed the word "Frame" to "Tab", added a TabGroup with a list of those Tabs and that's it.
Got lucky
I would like to say that all these different ease-of-use / trivialization of certain development activities was planned right from the start, but I can't say that with any honesty. Sometimes you just get lucky with designs. One of my early mentors used to say
"I would rather be lucky than good"
I find I say it a fair amount too. Dunno why, but having a stock of these quotes has been a common trait among all the mentors I've had. Some are serious lessons presented in humorous form
Quotes About Schedules
Here are 2 quotes from 2 different people, but address the same development issue.... schedules.
"If you have to eat sh*t, take big bites"
and a closely related one
"Nibbled to death by ducks"
They're saying a similar thing that I agree with. If you've made a mistake with a schedule, and you're going to have to slip the date, slip it ONCE. Make the new date far enough out that you are going to nail it. That's the big-bites part.
A date that's 3 weeks out is gonna hurt, people are going to be upset, but being truthful and giving you and your team enough time to finish is going to be so much better for everyone than if you go into mode of slipping the schedule 1 week at a time (nibbled to death by ducks). You lose credibility when working in this mode.
Sorry about the, uhm ramble....
TTK Scrollbars
You may have noticed from the above screenshots that all elements (except for the Output element) in the "All Elements" demo have skinny, matching scrollbars. These are the TTK Scrollbars that I keep rambling on about.
And check it out, they do cool things when you mouse over them. (NOTE - I've been posting .MP4 files instead of GIF into GitHub issues now as they give you playback controls.. I hope these come through correctly in email and that everyone likes them more the old GIFs that there was no controls with)
https://user-images.githubusercontent.com/46163555/163675056-76d24da5-95b4-4524-972c-38869617e484.mp4
Here's the first draft of the Global Settings changes to support these TTK scrollbars
The concept here is that you can choose the combination of pieces of the PySimpleGUI themes that go into these ttk scrollbars. Even though the Elements have a long list of parameters that you can use to control these pieces of scrollbars, it will make for some really ugly layouts if you had to specify them every time or even if you used the parms that are in the Window Object or will be in the set_options call. It's a "fire and forget" approach where it "just works".
I hope that like on many elements, the defaults I choose work out. Many elements take the same approach...for example, the Table and Tree headers get their colors from pieces of the theme colors. I've gotten lucky so far.
(see why I say "I would rather be lucky than good" ... I do try to make good designs, but sometimes a pinch of luck makes a difference)
Snapshots / The Catalog
Along with the TTK Scrollbar stuff, in this current release I'm also working on the built-in screenshot feature. It's in the code, working, and is hooked into the Global Settings to set the hotkey. I've already mentioned all this in previous announcements .
There is some error checking, auto numbering, and potentially the ability to leave the image on the clipboard. The clipboard feature is very risky though as it would require you to have yet another package installed in addition to PIL... so I have to think more on this. I don't want "feature creep" coming in... this release is one big creep already! I didn't plan on the scrollbars consuming quite to much, but they look really impressive to me. I think they're going to really kick things up a notch!
The next Catalog steps are to test the capture that's there now on Linux, Mac, the Pi, etc, and make sure it works well, and then Tanay is going to work his web-magic that he's done for us so many times before. I'm meeting with him on Sunday. This will definitely be getting us forcued on pushing it all forward!
Excited as Ever
I honestly can't wait to work on this project every day. I'm just aa excited as I was 3 years ago, and the reason for that is all of you... the many things you're building...the inspiring words... You make it easy to be dedicated.
PySimpleGUI 2022-04-16T21:48:55Z
Scrollbars Round 2
Made great progress today on the system settings. Quite a lot is running. I want to offer quite a lot of flexibility, but keep things simple and automatic.
Not done yet
This will perhaps be the most informative part.
-
TTK Scrollbars are the only option currently. The "Use TTK Scrollbars" stays checked. Need to work back into the code support for tk scrollbars
-
Columns and the Output elements not yet done
-
Retrieving the list of TTK themes available - this has always been a hardcoded list
- Testing - No testing on Linux and Mac yet. Have been focused on "make it run" (with a bit of "make it right-ish" too)
Default TTK Theme
This is a new entry added to the TTK Scrollbar Tab. The Tab may get renamed to just TTK Settings since it's edging over the line a little in terms of scope.
You can now set the Default TTK Theme from the Global Settings. This has quite a large impact on the look and feel of some of the elements (the TTK ones at least), and certainly the new scrollbars.
The TTK Scrollbar Definition Settings
This is where most of the time was spent today in development.
This page allows you to customize scrollbars. You can change:
-
Colors
-
Width - the overall frame width and the arrow width are separate, but it'll basically be the width of the larger of the 2
-
Relief
Colors
As with some elements, the pieces of the scrollbar are colored using the colors from the theme. The drop-down entries for each portion of the scrollbar represent a color from the theme..
For example, this line says that the color of the buttons with the arrows will be the same as the color for button text for the PySimpleGUI theme.
If we look at the scrollbar and a button next to each other, you can clearly see they're the same.
These are the choices from the theme colors to choose from:
In addition to these choices, you can type into the ComboBox colors names. They can be a text name that tkinter recognizes, like 'red'
If this was entered
Then when the system settings window is closed and you check out a window with scrollbars, you'll see they look like this now"
The way the PySimpleGUI scrollbar code is written, the mouse-over colors are the swap of the arrow and the arrow's background color... so instead of "red on blue" it becomes "blue on red".
For this iteration of this feature, it's how it's gonna be. I have to draw line somewhere on how configurable this is from the menus. Of course you can still do it in your code! You are not going to be completely walled in. This is a really typical mouseover behavior for scrollbars.
Like other ways y9ou can specify colors in PySimpleGUI, you can use the hex string. If we use #00FF00
then the arrow will turn green.
Checking a scrollbar we can see that the arrow has changed to green.
Reset Scrollbar Settings
(the I messed up button)
If you get into a situation where you want to get back to the original defaults, then click the Reset Scrollbar Settings
button an you'll get the original values.
Width
I've set the width to be 12 pixels. There are 2 widths, the frame and the arrow. Experiment if you wish.
The old gray scrollbars are about 17 pixels when I measured them. Over the past week they've been a quite skinny 10 pixels.
The TTK Theme has an impact on the overall width too. Some like WINNATIVE are full-width scrollbars of the old-gray type. The "Clam" ttk theme looks skinnier than the others.
A FEW Examples of TTK Themes, Relief
Here's a screenshot of all of the 7 TTK Themes that were available on my Windows 10 machine. I also included a few showing other widths for the scrollbar and other reliefs.
The Default
These TTK scrollbars are going to be the new default going forward. Hopefully there are some of you out there that agree that these are a step in a positive direction. The reason I'm adding all these options in the system settings window / in the PySimpleGUI config file is so that you'll be able to dial in the look and feel that you like the most.
Remember that you also have programmatic control at the individual element level. So if you have differing needs depending upon the application, user, customer, platform, you'll be able to be in a much better position of control than previously.
Give it a go!
If you're brave and willing to click the red button, then you too can be scrolling in style this weekend.
PySimpleGUI 2022-04-19T10:36:43Z
TTK Scrollbar - Previewing In System Settings
I'm sorry that yesterday I was again not feeling so well so I didn't get posted this info from the weekend.
Because you can tweak these TTK scrollbars to your own liking, I thought that being able to preview them as you're making the changes would be helpful.
Here is a session I recorded where I changed around the scrollbar colors. The change was to "invert" the bar color and the button colors. It's using the same color choices, based on the theme, but arranged differently.
Oh, the theme is a new one called "Python Plus"... There are a couple of "Python themes" now. This one has the color saturation punched up to be more vibrant and contrasty.
Anyway, on with the GIF demo...
PLEASE Test TTK Scrollbars
If you've got a moment to try the version of PySimpleGUI on GitHub, it would be great to get some feedback. "The candidate DEFAULTS have been chosen" is perhaps the message I'm trying to send. What's in the code now is what everyone is going to get... colors.... sizes...
I'll open an issue for some commenting from those that want to give some feedback.
There's a little ways to go yet, but not TOO far!!!
Left to Go - Output and Column Elemens
Columns are still the bigger one.
And I'm likely going to replace the Output element in this release with one that's basically a subclass of the Multline. I would like to remove it entirely, but I know I cannot do this for backward compatibility so the next best thing is to replace the underlying code.
"The PySimpleGUI Gallery"
Thinking that maybe "Gallery" is better than "Catalog". Names are important and it takes me a while to settle on one. Gallery fits in so many ways.
Tanay and I met Sunday and went through the latest design and data flow. I'm liking where were headed. We simplified a number of things. I think you'll like the process too.
This is going to be great not just for existing users, but new users as well. The existing users have an opportunity to help introduce PySimpleGUI and what it can do to everyone. Issue 10 does this now, but it hides 99% of what's been posted
This is more about you and the amazing things you've done than it is about PySimpleGUI.
I hope I've not taken on way too much trying this, but with 1,000s of applications being written and released, consolidating the screenshots into 1 place makes so much sense.
Lateral Weeks
The past few weeks have been somewhat lateral feeling with me being out so much, but I write down the things I accomplish every evening, and I see the list every day is not empty, so I know there's forward motion. I think perhaps it's because I'm building out some features at the moment that are not directly user enhancement requests. I'm trying to sneak those in too, but the majority of the time is spent right now trying to finish up a couple of mike-features.
OK.... off to keep the ball rolling!
PySimpleGUI 2022-04-19T21:12:18Z
Debug Window Enhancements DONE!
Finally marking stuff off the list!
The Debug Window has gotten 2 improvements in this release.
-
Ability to Pause/Resume
-
Can "block" or "wait for user"
Pause/Resume
The pause/resume is easy enough to understand. If your application is outputting a lot of stuff and you want to basically pause your application, you can now do that with the "pause" button on the debug window.
Too early to tell, but this feature may be of great help in debugging in general as you'll be able to "pause" your GUI without adding anything extra to your window.
blocking
or wait
parm
Two new parms were added to the Print
call. They do the same thing (they are aliases). Some people may not understand blocking. "Wait" is maybe a bit more intuitive. It's PySimpleGUI, so let's do both.
Here's some sample code that goes with the GIF that follows. As you see the video, recall that the debug window can be closed at any time, but it will re-open as soon as your program calls Print
again. This is why you see me testing by closing the window with the "X" or with the "Quit" button.
Specifying wait=True
will cause the button that's normally labeled "Quit" to be replaced by one that reads "Click to continue...".
import PySimpleGUI as sg
sg.Print('Here comes the data...', wait=True)
for i in range(300):
sg.Print(i)
sg.Print('end of the data set 1....', wait=True)
for i in range(300):
sg.Print(i)
sg.Print('Done printing all data.... click to exit', blocking=True)
PySimpleGUI 2022-04-20T18:14:19Z
Big Strides in Scrolling.....
Some nice things were accomplished today in getting these new features done and ready for general release!
They include:
-
Output element - upgraded to being a subclass of Multiline and thus scrollbars work correctly now. I still suggest using the Multiline instead of Output element. At least now the code is identical!
-
Fixed problem if the system had no scrollbar settings previously. It showed only gray bars for older systems (why didn't anyone tell me that none of you were seeing colored bars! LOL)
-
The system default, gray lovers, were taken care of today. The "Gray Gray Gray" theme works correctly as do other themes that use only what the system defaults provide
Here's today's thrilling video showing what's working...
No more tk scrollbars
I've been wrestling with the decision about backward compatibility of these ttk scrollbars and if there should be an option to use the old tk scrollbars.
After seeing how the ttk grayscale scrollbars look, I'm leaning on there only being ttk scrollbars. You can set the width of the ttk scrollbars to be similar to the older scrollbars if you want.
Adding support for the tk scrollbars just doesn't seem like a good use of resources and will add more complexity to the code that has to be maintained.
If the backlash from the community is huge for some reason, I'll certainly reconsider. Open an issue if this release impacts your project in some major way. I'm always open to listening.
Work still to do....
Since the Output Element got completed today that leaves the Column element. I believe that's the last set of changes needed for this feature!
Testing is another big piece that needs to happen prior to general release. I started some Linux testing today and it went well. With a dash of luck, we'll be running smoothly across the board. I sure hope this works out on all operating systems and all ports of tkinter! As you've seen in earlier screenshots, there are many many combinations at play here.
It was worth it
I hope the PySimpleGUI users end up agreeing that this change is a positive one. To me, the windows look considerably more "modern" a complaint I've heard about tkinter / PySimpleGUI for years. Since it impacts so many elements, maybe, just maybe, it'll make your whole application look and feel better. I guess only time will tell.
Thank you as always
Really loving this experience and the people it brings me into contact with. It's rewarding in a way that nothing else has before and I'm really thankful for you all giving me that. I've got the PySimpleGUI team to thank and the users too. It's really remarkable how enjoyable and rewarding it's been. Having the time of my life watching so many people build incredibly creative programs.
PySimpleGUI 2022-04-25T13:28:03Z
TTK Scrollbars DONE (sorta)
The Column Element was the last of the changes needed to the ttk scrollbar work.
I checked in changes that switched scrollable Columns over to ttk scrollbars. I'm not "proud" of the hacks, but they work, which was the goal. "Make it run, make it right, make it fast". These changes tried to use as much of the new ttk code I added earlier as possible while also minimizing the overall logic changes for scrollable Columns.
Anyway... the point is that it works and it would be great for some users to give their stuff a try to see if there are problems.
There is still a problem with Columns that an issue is opened on that I've not looked at.... again, wanted to get what was there working before doing anything else. I'll be cleaning up this hacked up stuff and also looking at the issue as the next step.
Thanks to everyone for their patience while this feature was being added. It and the other non-planned features (e.g. Debug Print pausing and blocking options, and the built-in screenshot capability) took longer than expected.
4.59.0.28 is the version just checked in.... that's a good number of changes to the code and I'm anxious to get this released to PyPI and see how the world likes these colored bars.
A Bit More...
There are more things still needed though like pulling the list of ttk themes from tkinter instead of hard coding them like they've always been. This would, maybe, allow custom themes to be used that are not normally part of the standard tkinter. We're testing this theory out currently.
The Column element and the Output element have not yet been changed to add the EIGHT new parameters that define the colors and size of a ttk scrollbar. I decided when designing this feature that every element that has scrollbars will have these parameters. They've been added to all but the Column & Output (i.e. Multline, Table, Tree, Listbox)
And as already mentioned, there is an issue outstanding on the Column element that I want to address.
The Gallery is Next
The screenshot code was added earlier in this release and still has a bit to go. I'm likely going to release 4.60.0 to PyPI prior to fully completing the integration with the Gallery feature. I do want to at least add the auto-numbering capability so that you can take as many shots as you want and it won't overwrite the previous one.
New psgdemos
Soon
There have been a LOT of changes to the Demo Programs that have not yet been posted to the psgdemos
PyPI project. They're in the PySimpleGUI repo already, but not in the Demos that are pip installable.
I need to make sure nothing requires the latest PySimpleGUI that's on GitHub. I don't yet have a Demo that shows using the many parameters that are available for the ttk scrollbars.
For my main development machine, I launch the Demo Browser from a local copy.... but on my Linux machines, I use the pip installed version as it's a lot quicker and easier to grab them using pip.
I'm working on a new YouTube video that's specifically on the Demo Browser, the Demo Programs concept, and how it all fits together into the ecosystem.
Thank you!
Having a blast watching what you are building!
It's fun to take a moment every now and then to look at some of the repos being posted. Beginners are always the priority... you just never know what they're going to do! To me, they're the next potential innovators.... so keep trying beginners... don't give up!
PySimpleGUI 2022-04-27T21:25:27Z
TTK Scrollbars Actually Done.....
Just finished today the last of the functionality for TTK scrollbars!
Version 4.59.0.32 has all of the ttk scrollbar code that I'm describing below...
Hierarchy of Settings
The last big piece added was the overall hierarchy of where an element's scrollbar settings comes from. There are FOUR places you can set the scrollbar settings. This is where you can set them and the order that will be used to get the value used for an element:
-
The Element's parms in the layout
-
Window
parms -
set_options
parms -
The Global Settings
The elements, Window
, and set_options
all use the same parameter names for the scrollbar settings.
This is the docstring you'll find in all of the above places.
:param sbar_trough_color: Scrollbar color of the trough
:type sbar_trough_color: (str)
:param sbar_background_color: Scrollbar color of the background of the arrow buttons at the ends AND the color of the "thumb" (the thing you grab and slide). Switches to arrow color when mouse is over
:type sbar_background_color: (str)
:param sbar_arrow_color: Scrollbar color of the arrow at the ends of the scrollbar (it looks like a button). Switches to background color when mouse is over
:type sbar_arrow_color: (str)
:param sbar_width: Scrollbar width in pixels
:type sbar_width: (int)
:param sbar_arrow_width: Scrollbar width of the arrow on the scrollbar. It will potentially impact the overall width of the scrollbar
:type sbar_arrow_width: (int)
:param sbar_frame_color: Scrollbar Color of frame around scrollbar (available only on some ttk themes)
:type sbar_frame_color: (str)
:param sbar_relief: Scrollbar relief that will be used for the "thumb" of the scrollbar (the thing you grab that slides). Should be a constant that is defined at starting with "RELIEF_" - RELIEF_RAISED, RELIEF_SUNKEN, RELIEF_FLAT, RELIEF_RIDGE, RELIEF_GROOVE, RELIEF_SOLID
:type sbar_relief: (str)
Global Settings for TTK
This is the final window for the global settings that involve TTK
Notice that you can now set the TTK theme in your global settings and this theme will be used across ALL of your PySimpleGUI programs. The PySimpleGUI theme already worked like this. With TTK you needed to set it at the top of all of your PySimpleGUI programs or in each Window
that you created.
Custom Themes
While we are testing the custom themes right now, only the standard themes that are distributed with tkinter are officially supported at this time. The other add-ons should work according to the early testing, but because they are 3rd party add-ons, it makes "supporting" them (i.e. answering your Issues here on GitHub) really difficult.
In theory, they should work as well as the built-in themes.... but, as we all know in software, there are theories and then there's reality. Unfortunately, we all have to live and work in reality-land. Let's see how it goes and hope for the best!
Serious Documenting Ahead
In order to do a PyPI release, I need to drop in a good-sized-chunk of documentation that explains how they work. The docstrings are great, but I do need to explain some of the specifics under the hood.
TTK has some limitations about what you can and can't set and I had some limitations in how far I was able to support the various combinations. The PySimpleGUI APIs need to be simple after all and that often means simplifying some of the options available.
One way to look at it is that you're getting a HUGE number of options compared to the zero prior to what will be 4.60.0. We've never had the ability to modify these in the past, at least not through the official APIs and I don't recall anyone opening an issue in the past that dealt with modifying the look of the scrollbars.
I think it'll all make sense when documented and the docstrings already do a good job of telling you what the parms do.
Thank You @norambna
The PySimpleGUI "Awesome User of the Month Award" goes to @norambna for doing a bunch of testing of the scrollbars and posting the results. It was more testing and information than I expected!
If you want to give it a try and report your findings, you'll find the issue that was opened here:
https://github.com/PySimpleGUI/PySimpleGUI/issues/5396
Thank you * 1_000_000
As always, an overall thank you to everyone.... you're such a great bunch of users... thank you for being kind, supportive, and gracious in the GitHub issues. I 💗 seeing all the thank you messages to Jason.
Thank you SPONSORS! OMG that's been so awesome and helpful!
And I love seeing what you're making, so be sure and drop a screenshot into your readme. Instructions are in the Cookbook if you need some help.
PySimpleGUI 2022-04-28T16:50:26Z
Demo Program For Scrollbars
Just added Demo_TTK_Scrollbars.py
to the Demo Programs so that you can see the MANY different options available.
There are SO MANY combinations of things here that I'm a little concerned.... but... the idea was to give you fine folks more control so.... wow was that idea implemented.
Column Element - New Size Subsample Parms
I've added 2 new parameters to the Column
element. I'm concerned that maybe I've made things a little bit too complex in the process, but, again, I want to give you a little more control. In this case it's control over how much of a scrollable column is initially visible.
In the past.....a scrollable column was set to a size specified by the user, or, if none was specified then the width was the full width needed and the height was set to 1/2 the size needed.
The defaults will continue to give you these same results.
I wanted to get away from a completely hard-coded setting which is how things have worked in the past. Now it's up to you!
The way the subsample works is much like the Image subsample. You take 1/subsample and that's the amount multiplied by the size. The defaults are size_subsample_width=1 and size_subsample_height=2. That is the full width is used and 1/2 of the height of the contents is used to set the height.
Maybe your window has a LOT of items in your Column and you would prefer 1/4th the size to be the initial size. To get this effect, set size_subsample_height=4. Or, if you expect to grow your Columns contents over time and want to make it twice the size initially needed, then you can use a float value of 0.5 for the size_subsample_height and this will make it twice as high as needed.
If you want your scrollable Column to exactly match the contents then set the two subsample parms to 1.
These are particularly useful for windows that have resizble=True.
PySimpleGUI has come a VERY long way since the initial days of windows that were completely static! Just hoping that all these changes going into 4.60.0 are not taking away the "simple". I don't think so. PySimpleGUI has always had a LOT of parms for elements, objects, functions. Because the defaults are likely to be what everyone uses, I think (hope) the net will be simply longer docstrings / documentation and giving more flexibility to those that want it.
PySimpleGUI 2022-04-29T12:33:39Z
Contributing.md
This post, like all of them, is entirely optional reading.
Recently I updated the contributing.md file to try to make sure no one's time is wasted and perhaps explain why things are different with the project in regards to contributions/pull requests.
"It's complicated" is maybe the best overall summary.
Subjective
Programming, how to live life, ....
It's all subjective/opinions. What I'm writing here is nothing more than my opinion. This is what's right for me... what's right for you may be vastly different or the reverse.
I've enjoyed sharing the knowledge that's been given to me by others here and what I've distilled through reading.
Philosophy
Over the history of this project, I've studied philosophy a bit. I needed a "guidebook" for life and I turned to philosophers of the past (never a living person) for guidance. I settled on a couple of major ones
-
Marcus Aurelius
-
Friedrich Nietzsche
The people I'm turning towards to help me with today's modern problems wrote their books in approx 180 AD and 1880.
I was surprised to learn recently that some of what I've done, the personal changes and choices I've made, matched something that Nietzsche wrote about.
I am not a "reader". I don't read a ton of books (yet another disclaimer).
"Not Reading" - the Surprise Recommendation
Nietzsche warned of being overly scholarly, as did a contemporary of his, Schopenhauer. While they both were mega-genius, well-read people, and read more books in a year than I have in a lifetime, they make a point that I think transcends time.
They warn again reading too much. That you'll simply spend your time learning what's already known. The suggestion is to make sure you give yourself room to think for yourself... to take long walks in nature to "digest" what you read. Nietzsche described the end-product of someone overly scholarly as the person becoming a "critic" rather than an inventor.
This is maybe a little of why I don't think I'll ever be a Python expert. I'm not interested in being one, and the time it takes (see below) may not be justified.
PySimpleGUI & Lack of Knowledge
I've written here a number of times that the reason PySimpleGUI came to be was because of my lack of knowledge. I had read about Python, but not very much (3 months). I was not educated anywhere near an expert level on how GUI's work I was very much a newbie to both Python and GUIs.
I've always been a "startup guy'". It's where my career has been, how I was taught, the life I've lived. The startups I was in were all about innovation, doing things differently.... that's sort of the name of the game with startups. They are rarely about evolution, but instead revolution. There is also a great deal of luck involved.
I want to be clear that luck has played a big role in PySimpleGUI. While decades of training helped formulate the architecture, there have been plenty of lucky breaks along the way.
Not a Solo-effort
I also want to be clear that while the first release of PySimpleGUI was an original creation, there have been many influencers.... users have a suggested a lot of features and ideas in the way of enhancements. A lot of these have helped PySimpleGUI become what it is. Some I had thought of previously, some not. I got help from all over the net early on.
There are also people that have been working on this project for years. Without @jason990420 's help in support, bug fixes, ideas, encouragement, customer care, and a million other wonderful things he's done, there is no way, it would be possible, for PySimpleGUI to be where it is right now.
I have help from @Chr0nicT as a full-time member of this project. OMG the help he's provided has been massive. There are others that have come and gone that impacted this project that I've been vocal about.
Simplify
It's not just what I did with PySimpleGUI, but I made changes to my life and programming too.
The PySimpleGUI Social Media and forum accounts are "closed" (or decommissioned). I turned off all "Programming Newsletter" emails. I discovered, that for me, the messages I got from them were "you're failing... you're falling behind... you're not doing things the right way".
These emails were personally impacting me as were the discussion groups, social media, etc. I needed the space in my head for my own thoughts.
The newsletters teaching me the new features, the right way to do things, the "5 packages you're not using but should be" were having a negative impact, not a positive one. The messages were not good for me mentally and it's the time impact that's the real killer.
There are only so many hours in a day, and I saw so much time being spent on social media, reading articles, getting sucked into discussions that were toxic were hurting the project, so I left those places and got my time back.
Trying to attract and maintain "followers" takes a lot of time. My interest is not in fame, followers, and some of the other things that actively trying to use the net to reach people bring. I want to reach people by building something they come and find because it's good. I want to spend my time building that thing, not building a list of people. Again, this is what's right for me... for others, this activity is what interests them and what they find joy in. There's nothing wrong with that! Do what you find joy in, as long as it harms no one.
Underlying Technology of PySimpleGUI
You may have noticed that PySimpleGUI ran on Python 2.7 and continues to run on 3.4. Python 3.4 was released on March 16, 2014. I'm using 8+ year old language features and nothing more. The point is that it's not about the language features and how well I know all the tricks, the newest bells and whistles, and "the best way" to write a portion of code. It's about... things working, being high quality, easy to use, maintainable (by me for now).
"Enjoy the Ride"
My mentor uses this phrase a lot and it's one that I write in my lab book every morning. It's written on post-its, on chalk boards in my home. I try to keep this phrase and some others in front of me nearly all the time.
There's a reason, an important one, that "Having Fun" is the number one goal for the PySimpleGUI project. It's a very serious goal and I truly believe it's the highest priority. If we're not ultimately enjoying life, making the most of it, then perhaps a great thing is being lost. Again, these are my personal opinions.
Gratitude
I'm so grateful for the help, the encouragement, the kindness, the support, the experience, ... that comes with this project. I'm sure you see the message here often. Sorry if it's maybe over the top, but that's how I'm experiencing life. Thank you all so very very much for making this a ride of a lifetime.
PySimpleGUI 2022-04-30T13:14:09Z
New psgtray
Demo Program
There was a good question posted over in the PySimpleGUI System Tray repo asking how to run with no window.
I created a new demo program that's posted in this repo as well as the system tray repo.
The basic answer to this is that you make the window invisible (set alpha to 0) and "hide" it (call the hide method). At that point as long as you don't do anything to make the window visible again, you'll have an system-tray only application.
The reason for the need for a Window is due to how this particular System Tray was implemented. I hooked into the existing Window event loop by running the tray as a thread. It greatly simplified creating this feature and thus actually delivering it for use.
psgdemos
Lots of Changes Stacking Up
I've continued to amass changes in the PyPI project psgdemos. The reason for holding them back is the new ttk scrollbar stuff and the other changes that are going into 4.60.0. When 4.60.0 posts to PyPI, I'll also post the 1.10 version of psgdemos.
Sorry for the delay. What I want to avoid is having demos that are pip installed and then crash because they require a version of PySimpleGUI that is currently only available on GitHub. This warning is already on the Demo Programs here in this repo, but because there is no repo to match the PyPI psgdemos
, there's no place to warn. I want those demos to be as stable as possible, so, they get a little bit of a delay.
The Column Expansion & Documenation & Mac Fix
There are the only outstanding items left for the 4.60.0 release (at least the only ones that come to mind right at this moment... I'll check my lab notebook and the issues to be sure). There are a few marked urgent so those will likely go in too. The Mac bug/mistake/missing feature is also likely to go in.
Weekend Release?
Hoping to get 4.60.0 posted THIS WEEKEND!
I'm anxious to get these new scrollbars and the TTK option in the system settings rolled out to the field. It's a significant step up in the overall look.
This side-by-side view of the Demo Browser is an obvious upgrade in the look.
And there are lots of other changes too. 4.59.0.34 means 34 check-ins since the last release and that sized number always makes me squirm.
Despite not being asked for, the Debug Print changes are also something I really think will be of value. I continue my assault on the command line / dos window and the Debug Window is an important part of this strategy. The command line may disappear, but we all 💗 our print
statements so it's important that exact same mechanism exists.... especially in environments that don't HAVE a shell/dos window/command line (a new port of PySimpleGUI hint)
Thank You!
As always, big thanks to the PySimpleGUI team and the many users the jump in to help.... @resnbl (THE Mac-man!), @edmundo has been doing a ton of testing and debugging of the Linux Jumping Window problem..... there are lots of you out there pitching in and it's appreciated.
PySimpleGUI 2022-05-02T13:50:46Z
"Hey... Watch this"
There is nothing more predictable than the results that follow when I've uttered the words "Watch this" just prior to demonstrating something. It's one of "Rules of Demos". Those 2 words seem to jynx demos for me.
Sorry if I sound like an old man that repeats old stories that everyone's already heard a million times, or I repeat myself.
I've got this same jinxed feeling this morning.
Posting that 4.60.0 might be posted to PyPI this weekend is something I really wanted to happen.... really did...
And then I fell ill on Saturday and have been in the bed for a couple of days.
I've not been able to check email, issues, or do much of anything. If I'm not replied to nor read your issue/message/email, this is why. It's got nothing to do with you nor how I value your problem or your assistance.
This post is the first thing I've typed on my computer. I'm hoping to rest enough and find some spots during the day to at LEAST look at issues, read email, and try to make some/any forward progress.
I'm disappointed, to say the least, and I'm sorry for this delay. I didn't do anything to cause the illness so I'm at least not beating myself up over it. I'm plenty frustrated though.
Thank you for your patience and I'm working hard to do the right things to recover and also help our users as I find the strength to do so. Back as soon as I possibly can....
PySimpleGUI 2022-05-05T16:35:57Z
THANK YOU SPONSORS!
I want to take a moment to specifically thank those that are sponsoring the PySimpleGUI projects through GitHub Sponsorship. Some have marked to remain anonymous. One I would like to thank that sponsored at a high amount, but I have no way of reaching the person, so this is one way.
M""""""""M dP dP
Mmmm mmmM 88 88
MMMM MMMM 88d888b. .d8888b. 88d888b. 88 .dP
MMMM MMMM 88' `88 88' `88 88' `88 88888"
MMMM MMMM 88 88 88. .88 88 88 88 `8b.
MMMM MMMM dP dP `88888P8 dP dP dP `YP
MMMMMMMMMM
M""MMMM""M
M. `MM' .M
MM. .MM .d8888b. dP dP
MMMb dMMM 88' `88 88 88
MMMM MMMM 88. .88 88. .88
MMMM MMMM `88888P' `88888P'
MMMMMMMMMM
MP""""""`MM dP dP
M mmmmm..M 88 88
M. `YM 88d888b. .d8888b. 88d888b. .d8888b. .d8888b. 88d888b. .d8888b. 88 88
MMMMMMM. M 88' `88 88' `88 88' `88 Y8ooooo. 88' `88 88' `88 Y8ooooo. dP dP
M. .MMM' M 88. .88 88. .88 88 88 88 88. .88 88 88
Mb. .dM 88Y888P' `88888P' dP dP `88888P' `88888P' dP `88888P' oo oo
MMMMMMMMMMM 88
dP
It's uncomfortable bringing up money. I've talked about the difficulty with funding a number of times, it's in the readme, etc. So I don't want to keep bringing it up here in the Announcements Issue.
BUT, I do want to continue to thank everyone that's helping to make this project possible. Without your help, it wouldn't be possible to do this.
While I've thought about and investigated Patreon and other mechanisms out there, they have a big drawback. They require my time to do special things for Patrons. That time is taken away from working for everyone that uses PySimpleGUI. I don't think it fits with my personal philosophy to take away time making the product better for everyone and instead make special things for a select group of wealthier individuals. Not judging others that do that! Everyone has a right to run their project how they see fit. I'm saying it doesn't fit my personal feelings.
If you can't afford to help financially, that's OK too. Your kindness and gratitude have been helping fuel this project too!
Sponsoring Back
I'm sponsoring a number of projects too. Your sponsorship goes to help other projects that PySimpleGUI either uses directly or I feel deserve recognition and sponsorship.
One of the most touching, warm events that happened was when I sponsored the @hoffstadt the developer of the DearPyGUI project. There is room in the GUI world for many many many solutions. There is no "best" and I wanted to show my support for that project. Within milliseconds of sponsoring it, I got a message from GitHub that @hoffstadt is sponsoring PySimpleGUI! Now that's solidarity right there.... working together towards a common greater good...
Drop me an email if I've overlooked sponsoring a project, a project added sponsorship and I didn't see it, etc. The Open Source world is a brutal place to attempt to make a living / put food on a table. I've no doubt that every project you sponsor is just as thankful as I am.
PySimpleGUI 2022-05-08T13:33:36Z
Side By Side 59 and 60.....
You've heard mike drone on and on about wanting to get 4.60.0 out the door for a while now. This side by side view of the Demo Browser does a great job of showing you visually why. The visual upgrades / polish that was done in (what will be) 4.60.0 is significant. It started with the scrollbars.... and then @jason990420 provided a really nice boost in the look and feel of the input and multiline as well as the combo boxes.
https://user-images.githubusercontent.com/46163555/167298331-59dc9b9a-c543-4b71-bcef-c2134724e5ef.mp4
The Listbox colors match in the 2 windows. The highlighting is done "correctly". It's the other elements that you see that didn't match before, but do now... and this I find exciting!
Yesterday's Documentation...
Yesterday I dropped in the documentation for the new TTK, Scrollbar, and global settings changes.
Scrollable Column Change
The one item that's been looming for a few days is the scrollable column changes. I made those this morning and it's working adequately in my opinion. I'm hoping that @jason990420 agrees.
The Final-Straight to the Finish Line
Hopefully, the release notes and all the procedures for releasing to PyPI are all that's left. I'm working on these now.
Thank you for your patience this week. It's been a challenging one.
PySimpleGUI 2022-05-08T16:53:48Z
4.60.0 PySimpleGUI 8-May-2022
TTK Scrollbars... the carpet now matches the drapes
Debug Window improvements
Built-in Screen-capture Initial Release
Test Harness and Settings Windows fit on small screens better
-
Debug Window
-
Added the
wait
andblocking
parameters (they are identical)-
Setting to
True
will make thePrint
call wait for a user to press aClick To Continue...
button -
Example use - if you want to print right before exiting your program
-
-
Added
Pause
button-
If clicked, the
Print
will not return until user pressesResume
-
Good for programs that are outputting information quickly and you want to pause execution so you can read the output
-
-
-
TTK
-
TTK Theme added to the PySimpleGUI Global Settings Window
-
Theme list is retrieved from tkinter now rather than hard coded
-
TTK Scrollbars
-
All Scrollbars have been replaced with TTK Scrollbars
-
Scrollbars now match the PySimpleGUI theme colors
-
Can indicate default settings in the PySimpleGUI Global Settings Window
-
Can preview the settings in the Global Settings Window
-
Scrollbars settings are defined in this priority order:
-
The Element's creation in your layout
-
The Window's creation
-
Calling
set_options
-
The defaults in the PySimpleGUI Global Settings
-
-
The TTK Theme can change the appearance of scrollbars as well
-
Impacted Elements:
-
Multiline
-
Listbox
-
Table
-
Tree
-
Output
-
-
-
-
Tree Element gets horizontal scrollbar setting
-
sg.main()
Test Harness-
Restructured the
main()
Test Harness to be more compact. Now fits Pi screens better. -
Made not modal so can interact with the Debug Window
-
Turned off Grab Anywhere (note you can always use Control+Drag to move any PySimpleGUI window)
-
Freed up graph lines as they scroll off the screen for better memory management
-
Made the upgrade from GitHub status window smaller to fit small screens better
-
-
Global Settings
-
Restructured the Global Settings window to be tabbed
-
Added ability to control Custom Titlebar. Set here and all of your applications will use this setting for the Titlebar and Menubar
-
TTK Theme can be specified in the global settings (already mentioned above)
-
New section for the Screenshot feature
-
-
Exception handling added to
bind
methods -
Screenshots
-
First / early release of a built-in screenshot feature
-
Requires that PIL be installed on your system
-
New
Window
methodsave_window_screenshot_to_disk
-
Global Settings allows definition of a hotkey that triggers a save
-
Popup is shown when hotkeys are used
-
To be clear - PIL does not need to be installed in order to use PySimpleGUI. ONLY when a capture is attempted does PySimpleGUI try to import PIL
-
It's the first step of building the larger "Gallery" feature
-
The alignment is not perfect and the whole thing needs more work
-
The auto-numbering freature is not yet implemented. Only 1 file is used and is overwritten if exists
-
-
user_settings_delete_filename
got a new parmreport_error
(off by default). TheUserSettings
object also got this parm to help control error reporting -
Themes (PySimpleGUI Themes)
-
theme_global
- added error checking and reporting should non-strandard theme names be attempted with this call -
New theme
Dark Grey 15
. Give it a try! -
New theme
Python Plus
- a more saturated blue and yellow colors. Give it a try! -
New function -
theme_button_color_background
- read-only call that returns the button background color. Previously only available as a tuple usingtheme_button_color
. -
New function -
theme_button_color_text
- read-only call that returns the button text color. Previously only available as a tuple usingtheme_button_color
. -
New function -
theme_use_custom_titlebar
returnsTrue
if Global Settings indicate custom titlebars should will be used
-
-
Output
Element - implementation changed to use the Multiline Element. No one should be impacted unless you were using some internal object details that was not published. I still suggest using theMultiline
element instead so that you can access much more functionality. -
Tab errors now use the popup errors with traceback
-
Column
Element-
Fixed scrollwheel not working correctly when expand paramters used. Scrolls the canvas now not the frame.
-
New
size_subsample_width
&size_subsample_height
parameteres-
Gives much more control over the sizing of SCROLLABLE columns. Previously the size was set to 1/2 the required height and the full required width.
-
The defaults are backward compatible (size_subsample_width=1, size_subsample_height=2)
-
Setting both to 1 will make the Column fit the contents exactly. One use is when you expect your Column to grow or shrink over time. Or maybe you didn't like the 1/2 size that PySimpleGUI has always used before.
-
-
-
Made Select Colors match the theme colors
Input
,Multiline
,Combo
elements now use matching colors for selections of characters (big-time thanks to Jason who also provided the magic code to make the combo drop-down match the theme)
-
popup_get_file
- Removed the file_types parameter use if on a Mac-
Missed catching this problem when added the no_window option
-
Need to revisit this file types on the Mac topic in next release.
-
Particularly bad problem because cannot catch the exception. Your code simply crashes. And the behavior isn't the same across all Macs.
-
I'm really sorry Mac users that we keep running into these kinds of issues!
-
-
Auto-correct file_types problems for Browse buttons. Automatically change the formatting from (str, str) to ((str, str),) and warns the user
-
Docstring typo fixes for file_types parm
PySimpleGUI 2022-05-08T17:04:49Z
psgdemos
1.10.0 8-May-2022
A new version of the psgdemos
package was also released today. This release was held back until 4.60.0 was posted since it has some demo programs that use the new ttk scrollbar feature.
pip install psgdemos
will get you a good time for free.
PySimpleGUI 2022-05-12T18:42:08Z
4.60.0 Did Not Implode!
The great news is that 4.60.0 was posted over the weekend, generating large numbers of installs, and there have been no issues reported that are 4.60.0 specific.
(knocking on wood emoji-style)
A Glance Ahead
A few things are on the stove already for the next release and a little further out too.
Mac Filetypes
This feature has been disabled for quite a while. Working on re-enabling it by adding a setting in the PySimpleGUI Mac Control Panel. We may be able to find a fix for old versions of Mac so this setting isn't required, but if one isn't found, then this is a good fallback as it'll enable Mac users that are able to make the calls using the filetypes parm to do so.
Linux GNOME Jumping Window
This Issue:
https://github.com/PySimpleGUI/PySimpleGUI/issues/5309
is a particularly ugly one because of the problem being caused by one specific Linux desktop, while the fix may have to be applied not only to all other desktops but also Raspberry Pi systems, Android applications, and in-browser solutions like Trinket. Getting some much needed help from @Chr0nicT on this one.... our Mac/Linux expert (thus also helping with the filetypes problem)
Gallery
The baby step of grabbing a rough screenshot was added in 4.60.0. The plan is to keep building this out until the feature is complete. Don't have an estimate, but progress will keep going in each release.
Documenation Rework
A much-needed reworking of the documentation is planned to start in July. It's something I've wanted to do for quite some time but haven't had the right timing, funding, etc. I'm sure a number of users will like the changes. It's been a long time coming and I appreciate the patience everyone has had. I'm ready to move from the "good enough" to the "looking good" phase.
Thank you!
Thank you for the support of the project, in the many forms that it takes!
Sponsors just reached a new level, a much needed help on funding. Udemy has been a real blessing and saved the project from complete collapse.
Lots of kind remarks and encouragement in the Issues... love seeing people say "thank you" to Jason. I dunno exactly why that makes me feel warm inside, but it does.
PySimpleGUI 2022-05-14T19:39:15Z
4.60.0 Coming to Trinket in Next 24 Hours
I've been working with the fine folks at Trinket to roll out 4.60.0 onto the Trinket platform. They provide amazing support and are incredibly responsive. They're a service I would happily pay more for if they raised their ridiculously low price of $6 per month.
They've upgraded their servers so by tomorrow all of the code in the eCookbook and the interactive Udemy course exercises will be running on 4.60.0. You'll have access to the latest and greatest features... and hopefully, there aren't any latest and greatest bugs hiding in there that I've not discovered while testing on Trinket.
Lots of eCookbook Traffic
Trinket was one of the first places where I noticed round-the-clock use. Anytime I check what was last being used, I see that someone has just been there in the past few minutes.
For those of you already experienced with web traffic and millions of users accessing your stuff 24/7, this will be quite ho-hum, but for me, it's been thrilling to see my stuff getting used and knowing that someone's learning to build something they've dreamed of building. I've not found any other feeling like it and appreciate seeing the awesome stuff being made... so thank you very much for sharing here on the GitHub in Issue 10 and for posting screenshots in your readme. FUN! LOADS OF FUN!
PySimpleGUI 2022-05-16T15:50:05Z
The Feature & Fix Algorithm
Features, fixes, changes, all go through an algorithm in my head that ultimately determines what goes in and what doesn't. One of the bigger determining factors is whether or not an operation is possible while using the current version of PySimpleGUI. Can you accomplish the operation without a change to the PySimpleGUI code? This is one of the basic tests and it's one of the more important ones to me.
If it's possible to complete an operation with the existing code, including using the "Extending PySimpleGUI" technique of accessing the Widget
member variable, now also known as widget
property, or tkinter can be called directly in some cases, then that bumps the priority down a little.
location=None
Feature
Over the weekend, on GitHub, I added a new feature that some of you might be interested in. It will go into 4.61.0.
Setting the parameter location
in the Window
object creation or in the popup
calls to None
will cause PySimpleGUI to not set any location for the window. The underlying windowing system / Operating System will determine the location to place your window.
This is a good example of one of the higher priority items. When designing the PySimpleGUI API, it's a scenario that I hadn't built in / considered. We've gone 3 years 10 months and 5 days without this one.... better late than never.
This is a very low-risk addition to the code. The impact on the install-base should be zero users impacted as it's a setting that's currently not allowed.
Risk/Reward
Another test that I apply is a Risk/Reward test. I consider PySimpleGUI to be a product, not a project. I have thought in this way since its inception. It's why the description in the readme has the phrase:
While PySimpleGUI is currently licensed under an open-source license, the project itself is structured like a proprietary product.
Because my view and the processes I use are geared towards product development and being cautious with the existing users, the decision-making and the pace may appear to be conservative to some. It may be even frustrating, as mentioned in the contributing.md file.
It's my job to minimize the risk to our existing users while also adding features and changes for current/new/future users.
As the install base continues to grow and the number of active users continues to grow it slows down the pace a little. It's just part of supporting a product that's "in the field". Weekend before last release 4.60.0 was posted to PyPI. That's 60 major releases since June 2019, ... 34 months ago. PySimpleGUI is not standing still. Development has not slowed to a crawl, though it may feel that way sometimes.
"Works for me" is not the standard
Acting with purpose is how I personally live my life and how I work on this product. I don't act randomly. My approach is to take specific actions that are done with specific intent and purpose.
Backward compatibility is a critical feature of PySimpleGUI. It runs on 3.4 to 3.11 systems. Code written 3 years ago should continue to run on the latest release.
Many users don't upgrade their environments. Some cannot because of the amount cost of testing that goes into their product. But they may upgrade some of the packages they use. It's for this reason that a great deal of caution is used in what gets released to PyPI. I'll take some risks on GitHub, but releasing to the world is to be done with purpose, caution, and with care.
Linux is Particularly Tricky
Linux isn't just on the desktop. It's also on the Rasberry Pi and custom hardware.
It's not even just on hardware. It's in your browser. It's running on Trinket and on REPLIT.
Changes that are along the critical path in the code, that are fundamental to every window created are not something that can be done in a haphazard way. It's been done numerous times, but there's always testing involved and again, great care.
Thank You Debugging Users
I really appreciate the help from our users to find difficult problems. Debugging, finding problems in tkinter or deeper into the layer-cake is not trivial and takes a special breed of developer. I really appreciate the help that's provided by these special developers. I understand the time you're putting in. It's how PySimpleGUI was created in the first place, with a lot of experimenting, trial & error, it's how fixes have been added over the past several years, and still done every day.
Everyone's Doing Their Best
Users, the PySimpleGUI team, and hopefully me as well, are doing our best. I can't imagine asking for more than that.
PySimpleGUI 2022-05-16T16:44:25Z
Tip of the Day.... Quick Window Cleanup
This is something I need to get into the Cookbooks.
I've seen a good number of newcomers making simple data entry windows.
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Text('Name'), sg.Input(key='-NAME-')],
[sg.Text('Address'), sg.Input(key='-ADDR-')],
[sg.Text('City and State'), sg.Input(key='-CITY-')],
[sg.Button('OK'), sg.Button('Exit')] ]
window = sg.Window('My Data Input Window', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
Try Adding Push
If your Input
Elements are the same size, then try adding a Push
element to the start of each row.
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Push(), sg.Text('Name'), sg.Input(key='-NAME-')],
[sg.Push(), sg.Text('Address'), sg.Input(key='-ADDR-')],
[sg.Push(), sg.Text('City and State'), sg.Input(key='-CITY-')],
[sg.Button('OK'), sg.Button('Exit')] ]
window = sg.Window('My Data Input Window', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
Each of the rows will have the entire contents of the row pushed to the right. The result is a nicely formatted window with little effort.
PySimpleGUI 2022-05-17T06:52:21Z
Tip of the Day - Quick Window Cleanup Part 2
There's more than 1 way to skin a window.
Another way to get a similar result....
import PySimpleGUI as sg
layout = [ [sg.Text('My Window', expand_x=True)],
[sg.Text('Name'), sg.Input(key='-NAME-')],
[sg.Text('Address'), sg.Input(key='-ADDR-')],
[sg.Text('City and State'), sg.Input(key='-CITY-')],
[sg.Button('OK'), sg.Button('Exit')] ]
window = sg.Window('My Data Input Window', layout, element_justification='r')
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
This one is a little trickier, particularly to get the first row, the window heading, to be left justified. I don't expect a complete beginner to come up with this pattern. It's relying on a rather unusual artifact of the expand_x
added to row 1. I honestly didn't expect that behavior, but, well, trial and error are a bit of the programming experience, right?
"Experiment".... it's one of the things I write in my lab notebook every morning as part of my instructions to myself. Yea, I admit to being weird. Try it (being your own version of weird)... it can be freeing and helpful.
Anyway, back to the example.
The key to his pattern is the Window creation and that element_justification='r'
parameter. It's going to push everything to the right. This is the same thing that the Push
elements on the rows in the previous post did.
I recall Jason once posting an example with the buttons right-justified and I liked it! It's a nice touch / change of pace.
As you can see, spending a few minutes once you've got things running, to work on polishing your window can have some really nice benefits. By adding a few elements, or a couple of parameters, we went from the initial running window:
To 2 different polished-up variants.
Beginner Magic
These are a couple of examples that I sometimes pick up from looking at projects made by beginners. It doesn't take an expert at PySimpleGUI to experiment with formatting, and it's sometimes the beginners that come up with stuff like this.
seeing what you beginners are making, so post those screenshots even if you think you've not done anything special.... they're ALL special!
PySimpleGUI 2022-05-20T13:03:14Z
Dot Release This Weekend... 4.60.1
There's a bug that needs to be fixed ASAP in the PyPI release of PySimpleGUI.
This one:
https://github.com/PySimpleGUI/PySimpleGUI/issues/5475
It's particularly bad because the code will crash if a program uses a Listbox with a horizontal scrollbar.
Sorry that this one got past me.
There's also a problem with the TKOut
member variable disappearing from the Output
element. Need to think through how to best deal with this.
These are good examples of what I meant about having an install base in the field in a post a few days ago and the great care that's involved in ensuring no harm is done.
PySimpleGUI 2022-05-21T11:09:47Z
Cookbook Addition - Window Cleanup Recipes
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-clean-simple-inputs
I mentioned a few days ago the trick of using Push
to clean up your simple windows. I also mentioned they should be in the Cookbook, so in they went.
I've added some recipes in the Cookbook to show a couple of ways to make this happen.
Briefly, here are the screenshots of "before" and 2 "after" windows....
PySimpleGUI 2022-05-22T20:00:55Z
4.60.1 PySimpleGUI 22-May-2022
- A patch-release that fixes crash if horizontal_scrollbar=True when making a Listbox element
Posted to PyPI. Fixes the crash that was created in 4.60.0 with the addition of ttk scrollbars
PySimpleGUI 2022-05-22T20:25:22Z
PySimpleGUI Tip of the Day.... Getting a Grip on Your Windows
Is your window resizable and you're struggling to grab the corner to resize it?
If so, then give the SizeGrip
element a shot!
Many of the PySimpleGUI Demo Programs or the psg utility
programs that are resizable use a SizeGrip
.
The Demo Browser is a good example
You'll find that your mouse cursor will change to the resizer cursor over a much larger area than would normally occur on a plain window.
Size by Side Compare
The window on the left has a SizeGrip... the window on the right is plain.
Notice how it's easier to get the cursor to change to a resizer cursor and it stays in the resizable state longer:
Adding a SizeGrip
To add a SizeGrip, add a SizeGrip
element to the last row of your layout.
Set resizble=True
& Make Something Have Expansion
Two final important bits of info.
-
You will need to indicate the Window is resizable when creating your Window.
-
Make something use the
expand_x
and/orexpand_y
elements, or add aVPush
element
In this example, I've added a VPush
element so that the rows below that row will be "pushed' vertically downward, resulting in the buttons sticking to the bottom edge of the window when the window is resized. Typically you'll have a Listbox
or a Multiline
element that expands (like in the Demo Browser example above)
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.VPush()],
[sg.Button('Go'), sg.Button('Exit'), sg.Sizegrip()]]
window = sg.Window('Window Title', layout, resizable=True)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
PySimpleGUI 2022-05-23T12:44:15Z
PySimpleGUI Tip of the Day - Get a Grip Part 2 - Minimum Size
If you make your window resizable, you most likely want to add the line of code in this example.
This example sets the minimum size for the window. If there is no minimum set, then the window can be resized down to a very very tiny window that's not useful. By setting the minimum size to be the same as the starting size, then you will make it easy for your user to shrink their window back to the starting size quickly and easily.
You need to finalize your window so that you can get the size, otherwise, the size will not yet be defined. Then make this call:
PySimpleGUI 2022-05-23T14:20:49Z
psgtest
Version 1.10
Both the GitHub repo and the PyPI release of psgtest has been upgraded to 1.10.0
A new "Regression Test" feature was added. You'll find the controls for it in the bottom left corner of the window.
With this feature, you can run 100s of programs that will be automatically terminated after some amount of time that you specify. You can specify the number of tests that can be run in parallel.
For example, maybe you've got 343 tests, like I do with the PySimpleGUI Demo Programs. You can't just start all 343 programs. You will quickly run out of memory. Instead psgtest will run blocks of tests. The default is 5 at a time.
If the output from your program includes the text Traceback
, then psgtest assumes your program has crashed and you'll be informed with a non-blocking error popup. Additionally, the tab with the error information remains open.
If you program doesn't crash, then psgtest will kill it after some period of time (default is 15 seconds), and the tab will be closed for that program.
If all goes will, you'll have no tabs and no error popups at the end of the tests.
psgtest uses the PySimpleGUI Exec APIs to launch subprocesses and uses threading and psutil to make the program highly responsive.
This Regression Test is a basic test that your window was created correctly. It does not try to interact with it. It's a basic first line of defense.
PySimpleGUI 2022-05-26T21:13:17Z
PySimpleGUI Tip of the Day - popup
Location
You're all quite familiar with the default location for a PySimpleGUI Window being the center of the screen. This is quite convenient for getting the attention of your user, initially.
popup
windows also default to the center of the screen. If your user has moved the main window and you show a popup, you may want that popup to be where the user's window is located rather than the center of the screen. A simple way to correct this is by using the location
parameter.
Instead of using the default center of the screen, how about using the location of the main window? You can do this by adding this parameter to your popup
call:
Your popup call will thus be:
It's that simple!
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Button('popup'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'popup':
sg.popup('This is my popup', location=window.current_location())
window.close()
PySimpleGUI 2022-05-30T08:58:49Z
New Demo Program - "Recording Frame"
I've been writing a script for a new YouTube video about the "PySimpleGUI Ecosystem".
One of the problems I faced while making the Udemy course was knowing exactly where the "recording area" was on my monitor. My primary monitor has a size of 3840 x 2160, so recording a 1920 x 1080 video takes up only a portion of the screen. The software I use doesn't show me the exact area that's being captured. By the way, these UHD TVs that I use that provide a huge number of pixels are cheap and available from Walmart (under $300).
About 1/2 way through the Udemy course I realized that I could make a simple, essentially 7 statement, PySimpleGUI program that will show me at all times where this area is. The program draws a line just outside of the recording area.
Beause the window is "transparent", it needs to run on Windows because only on Windows does tkinter support transparent windows.
I realized yesterday that perhaps others making videos could benefit from this simple program, so another Demo Program was created.
One trick I use in many of these windows that lack a titlebar is a small area I can grab to move the window. In this demo, this element serves that purpose:
and is the small white bar you see at the top of the square next to the "Exit" button.
https://user-images.githubusercontent.com/46163555/170956403-7370ad3d-0278-4274-8f9f-a923f76a101d.mp4
For those in the USA - hope you are enjoying the holiday today. For the rest of the world... I hope you're enjoying the day just as much!
PySimpleGUI 2022-05-30T19:55:49Z
New Video - The PySimpleGUI Ecosystem
https://youtu.be/9bfJ0Wy8YIU
I just finished recording and uploading a new video about the PySimpleGUI Ecosystem. Hopefully this will help users learn about part of PySimpl eGUIthey were not previously aware of.
The Presentation is a PySimpleGUI Program
Rather than use Powerpoint or other tool, I used PySimpleGUI to create the video. It has live links that open the browser for example. It was much quicker for me to write the code than to use an editor. It's less than 100 lines of code so it was no big deal to knock it out.
Enjoy! I hope you learn something new that's useful.
PySimpleGUI 2022-06-01T11:00:40Z
PySimpleGUI as "Powerpoint"
A quick revisit of the video I posted a couple of days back about the PySimpleGUI Ecosystem and how I used PySimpleGUI to create the "presentation". I've used Powerpoint for a long time, but it was actually faster and easier for me to do it this way this time around. Maybe it's because PySimpleGUI is what I do all the time.
There are 3 techniques / design patterns I used that you may find helpful in some of your programs.
-
Centering in the window
-
Navigation between "slides"
-
Images / single-file solution
Centering in the window
I wanted the contents of each slide to be centered vertically in the window. By far the easiest way to do this is to place a VPush
element on the first and last row of the layout.
Each "Slide" was a Column element. For example, the first one, the image that is shown in the previous posts, was made using this layout:
page1 = [[sg.Image(psg_logo)],
[sg.T('The PySimpleGUI Ecosystem', font='_ 40')],
[sg.T()],
[sg.Text('PySimpleGUI Goals', font='_ 30')],
[sg.T('1. Have Fun')],
[sg.T('2. Your Success')]]
The overall layout for the program was a bunch of Column
elements where only 1 at a time is visible.
page_columns = [sg.Col(page1, k='-P1-'),
sg.Col(page2, k='-P2-', visible=False),
sg.Col(page3, k='-P3-', visible=False),
sg.Col(page4, k='-P4-', visible=False),
sg.Col(page5, k='-P5-', visible=False),
sg.Col(page6, k='-P6-', visible=False), ]
layout = [[sg.VP()], page_columns, [sg.VP()]]
The last line with the VP()
elements does this vertical alignment. VP
is just an alias for VPush
Navigation
I used the arrow keys while giving the presentation. Right moves forward, left backward, and down exits the program. I used the bind
method of Window
to do this
Moving the "next" page meant making the current page invisible and making the next one in the list visible.
elif event == '-NEXT-':
key = pages[page]
window[key].update(visible=False)
page = (page + 1) % len(pages) # Increment to MAX then roll over to 0
key = pages[page]
window[key].update(visible=True)
Images and a Single-file Solution
I like to put my images into my .py files. This makes for a single .py file and nothing more in order to run the code. No pesky .png or other files.
To do this required converting the PNG files to Base64 strings. I used the psgresizer
utility to accomplish this. For each image I added to the program, I typed psgresizer
from the command line and pasted the path to the file I wanted to add to my code. The checkboxes are already set up to do the operation I'm after which was to convert to Base64 and leave it on the clipboard.
After clicking resize
, I went to my program and at the bottom typed a variable name = such as:
And then Control V to paste the string.
By putting these large bytestrings at the end of the code, I don't encounter them while working on the code. They are the last thing in the file. The very last line of the file calls my main
function so that they are all defined basically as global variables that can be accessed by anything above.
That's it...
It was that simple. Next time you need to knock out a presentation and you don't have powerpoint available, nor an internet connection, maybe think about dashing out a PySimpleGUI program and using that.
It worked out well in this instance. Your mileage may vary. it's not something PySimpleGUI was built to do, but all you guys and gals out there are building so many diverse applications that I'm inspired to try new things.... some of them actually work out!
PySimpleGUI 2022-06-01T19:51:00Z
BIG DISCOUNT Udemy Sale Starts Tomorrow.....
The current coupon expires tomorrow.
I'm starting a new BIG SALE tomorrow.... I'll make another announcement once I get the pricing changes made so watch this space! (and the readme & documentation)
PySimpleGUI 2022-06-02T10:04:44Z
Udemy Course Now $19.99!
I realize that because the majority of the PySimpleGUI users are not in the United States, not everyone can afford the discounted price of $99 that the Udemy course normally sells for.
As a result, I've dropped the price to the lowest level Udemy offers for a few weeks.... $19.99
The link is the same as usual, but you'll find the price has changed with no need for a coupon to get the $19.99 price.
https://www.udemy.com/course/pysimplegui
On average, you'lre paying $1.73 per hour of instruction. That seems really reasonable to me especially since you're also getting interactive exercises with this course. I dont' know of any other GUI course on Udemy that has online exercises that accompany the course.
Like PySimpleGUI itself, I wanted the course to be the best experience possible. FUN... it's the # 1 goal for everything I work on in case you've not seen the pattern. Same thing with # 2 - your success. There's little more enjoyable than seeing people being creative, building things they dream up, being successful, and having fun in the process.
PySimpleGUI 2022-06-02T10:47:32Z
The "Anniversary Sale".... Use The Coupon...
Since there has always been a coupon at the top of the readme, and of the documentation, I wanted to leave that tradition.....
So, now those coupons discount the $19.99 sale down to an even lower $13.99
July marks the 4-year anniversary of the first public release of PySimpleGUI. This seems like a great way to celebrate the past 4 years.
PySimpleGUI 2022-06-04T12:51:39Z
PySimpleGUI Tip of the Day - UserSettings
API as a Mini-Database
If you've got an application that needs data stored across multiple runs then the "User Settings APIs" may fit your needs. They're based on JSON or Config.INI files. For "small-ish" amounts of data, they can work as a nice little database. You can easily have 1,000s of records and not suffer any performance problems.
Here's a short example of using this API as a database. The program has a user ID and some information that's associated with it. You can enter new data, or look up existing data. It's not shown, but you can update existing data just was easily.
import PySimpleGUI as sg
def main():
user_data = sg.UserSettings('my_user_data.json')
layout = [ [sg.Text('My Banking Application')],
[sg.Push(), sg.Text('User ID:'), sg.Input(key='-ID-')],
[sg.Push(), sg.Text('Information:'), sg.Input(key='-INFORMATION-')],
[sg.Button('Add'), sg.Button('Display'), 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 == 'Add':
user_data[values['-ID-']] = values['-INFORMATION-']
sg.popup(f'Added user: {values["-ID-"]}')
if event == 'Display':
user = values['-ID-']
data = user_data[user]
sg.popup(f'User: {user}', f'Has data: {data}')
window.close()
if __name__ == '__main__':
main()
Retrieving in Realtime
Changing a few lines of code in the example is all that's required to change the application so that user information is automatically looked up and filled in when there's a match:
import PySimpleGUI as sg
def main():
user_data = sg.UserSettings('my_user_data.json')
layout = [ [sg.Text('My Banking Application')],
[sg.Push(), sg.Text('User ID:'), sg.Input(key='-ID-', enable_events=True)],
[sg.Push(), sg.Text('Information:'), sg.Input(key='-INFORMATION-')],
[sg.Button('Add'), sg.Button('Display'), 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
elif event == '-ID-':
user = values['-ID-']
if user_data[user] is not None:
data = user_data[user]
window['-INFORMATION-'].update(data)
else:
window['-INFORMATION-'].update('')
elif event == 'Add':
user_data[values['-ID-']] = values['-INFORMATION-']
sg.popup(f'Added user: {values["-ID-"]}')
elif event == 'Display':
user = values['-ID-']
data = user_data[user]
sg.popup(f'User: {user}', f'Has data: {data}')
window.close()
if __name__ == '__main__':
main()
This code has simply enable events for the User ID input so that as characters are typed, a lookup is performed to see if that ID is in the database. If it is, then the information about that ID is filled into the "Information" input so that it's displayed and can be changed.
PySimpleGUI 2022-06-04T16:07:28Z
UserSettings
as Simple Database - New Demo Program
Continuing briefly from the previous post.... I've created a new Demo Program that demonstrates this concept that you'll find here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_User_Settings_As_Simple_Database.py
Each User ID simply has a dictionary that is associated with it. The dictionary is created from the values in the window. It's a simple mapping exercise from the values
dictionary that's returned from window.read()
to the dictionary that is stored in the User Settings file.
There is also a matching page in the eCookbook over on Trinket that you'll find here:
https://pysimplegui.trinket.io/demo-programs#/user-settings/usersettings-as-a-simple-database
The advantage of the eCookbook is that you don't need to install anything. Just go there and begin working with the code straight away.
This Demo Program will be in the next release of psgdemos
to PyPI.
PySimpleGUI 2022-06-04T19:42:17Z
New Cookbook Recipe - Exception Handling
A new Recipe was added today to the Cookbook that shows a couple of ways of handling exceptions in your PySimpleGUI program. This is especially important for programs like those that run in the system tray or are "Desktop Widgets" that run without any console and run for weeks at a time.
Two techniques shown include using the Debug Print window and a popup call that enables you to integrate with your editor so you can be taken straight to the error in your source code.
https://pysimplegui.readthedocs.io/en/latest/cookbook/#recipe-exception-handling-of-a-console-less-application
PySimpleGUI 2022-06-06T16:38:39Z
New Constant TKINTER_CURSORS
, New Demo Program, .... GUMBY!
I've added a constant that is a list of the cursors available on all Operating Systems when using tkinter. There are some special ones for each OS, but I'm keeping it simple and going with the 88 common ones.
A new Demo Program was also added that will make it much easier for you to see what these cursors look like.
https://user-images.githubusercontent.com/46163555/172204966-d1f9357d-3ce0-4bb8-a754-89bc4e77aa20.mp4
Several Demo Programs already use the cursor features of PySimpleGUI.
Showing my age here, but I didn't know there was a Gumby cursor!! That's made for an exciting morning indeed! Gumby... built in...
Life is good!
PySimpleGUI 2022-06-07T08:47:18Z
REPLIT Update
I've got an update for everyone on the Replit problems. There has been a bug that's lingered for long enough that I canceled my membership and was in the process of deleting my projects when I was contacted by their support team.
An engineer named Toby was assigned to the problem and he wasted no time getting busy busy!
The problem is a fundamental one.... it's not possible to create a window anywhere except (0,0). Armed with information that this feature worked great for the first couple of years that I used REPLIT, he found the problem! One of the most enjoyable things for me to seeing a young engineer be tenacious with a problem and stidk with it until they find a solution.
He's working on how to go about fixing this.
Tenacious Young Engineer Award....
Speaking of tenacious engineers, I want to point out what a huge contribution that @Chr0nicT recently made to the PySimpleGUI project for Mac users. Through many late nights of testing, trying, trial and error, refusing to give up, he managed to find a solution to a problem that's been in the Mac code for the tkinter port. It's the infamous file_types
problem.
He found a solution that works on old and new systems and as a result I was able to remove a setting from the Mac system settings.
Big-time thank you owed to Tanay for this one!
I've no doubt that he's going to make a mark on computing history.It's fun to get to watch and be a part of him becoming a seasoned software engineer.
PySimpleGUI 2022-06-07T10:04:04Z
Custom Checkbox Demo Program Added
I thought there was already one of these as a Demo Progam, but I didn't see one so I've added it and I added an eCookbook entry as well:
https://pysimplegui.trinket.io/demo-programs#/custom-elements-buttons-radio-buttons-etc/custom-checkboxes
psgresizer
Makes it Simple & Easy
Anytime I have Bas64 images in a PySimpleGUI program, I use the psgresizer
tool that you can pip install and is found in the PySimpleGUI repos. It will take any image, convert it to PNG, encode it as a Base64 bytestring and place the result on the clipboard. At that point, all you have to do is paste the image into your code. It's as close to trivial as I can think t make it.
Make that Modern GUI!
A number of people want different controls that look more modern. This is one very easy way to get them. The Image element and the Graph element are ways for you to re-skin PySimpleGUI in numerous ways. Would be great to see some user GUIs that look completely unlike the native GUI widgets.
Enjoy!
PySimpleGUI 2022-06-09T11:26:27Z
Screenshots
I've said it numerous times, but I don't think it can be overstated.... seeing what is being made using PySimpleGUI is an important part of my overall experience with this project... and I'm quite sure it also has an impact on the person that has written the code and other people that see what's been created.
There's a sense of pride in showing what you've made. It's also a bit terrifying!
You're putting yourself out there. Showing the world your creation. Perhaps opening yourself up to criticism. But, my experience is that you're opening yourself up to praise too and that what I've witnessed has been praise and encouragement.
The Gallery
It's been a slow-moving project, the addition of a PySimpleGUI Gallery feature that's more official than Issue 10. I would like to to go quicker, but there are only so many hour and only so much I can afford to throw at the feature.
There is also a priority issue.
Continuing on... THE priority...
One reason why the pace is slower than desired is I'm fighting a fight to keep PySimpleGUI alive. That's where a lot of my time and energy is going at the moment. PySimpleGUI is again, or perhaps I should say still, on the brink of collapse as the unsustainable situation has not improved to where the project is able to fund itself. I'm determined, as you all know, to keep it going and so that's where I'm putting a good chunk of my time and resources.
Please keep posting in Issue 10 and keep adding images to your readme!
This is perhaps the biggest non-financial impact you can have on the project at the moment. It has a tremendous impact on many people as described above. So, I urge you to keep showing the world what you're doing!
I have called it a "guilty pleasure" to browse the images I find. I get the pleasure of sharing with you in your accomplishments. As I said in explaining goal number two of the project - "Your Success", it's not just you that benefit from this happening.
Thank you so very much for making this experience a truly wonderful one.
PySimpleGUI 2022-06-09T21:11:07Z
psgtest
Version 1.11 Released
A new version of the psgtest
utility was released to PyPI and GitHub today.
It includes a new "run a single file" feature that enables you to manually specify a file to run. This allow you to quickly and easily test a program against many versions of Python without having to manually invoke Python from the command line each time.
The version number of psgtest
is also shown on the main window now at the bottom along with the many other version numbers shown there.
PySimpleGUI 2022-06-13T21:33:06Z
PySimpleGUI Tip of the Day - non_blocking=True
Popups
Sometimes it's handy to show some information, like maybe a log or some bit of information like version numbers, that stays open while your user continues to use your primary window. The non_blocking
option on popup
windows is for this purpose.
Many of the Demo Programs have a right-click menu that shows versions of various components of PySimpleGUI. These are usually shown in a non-blocking popup so that the main program immediately continues to work regardless of the status of the popup window. In the case of these version popups, it's not important if or when the user closes that popup window. It's more convenient to allow them to continue running with the window still open, so that non_blocking
option is set.
Your own non-blocking popup
If you want to make your own window that operates like this, that stays visible after being displayed and then can be closed later, you can do this by using a DummyButton
and calling your read call with this statement:
This will cause the read
to immediately return so that your program can continue running. You will not use an event loop with this read. It's a 1-time read.
NOTE however that you won't be able to do anything intelligent with that window. You can't take any actions based on the button clicked because you won't be informed about the click.
This is not the same as running a true multi-window application. You're still only running one main window. The window with the DummyButton
is going to close when the button is clicked or the "X" is pressed.
PySimpleGUI 2022-06-17T11:43:35Z
Weekend Heads-up
I'm going to be a little slower to respond to issues this weekend. There are several specs that I need to get into heads-down mode on for some upcoming work. I've also got a couple of meetings, one of them is with @Chr0nicT where we'll go through some of the Mac M1 problems. It's likely that I'll continue to be pulled away with PySimpleGUI tasks not related to the issues being logged just as I've been this week and will be this weekend.
Thank you for your patience. I'm trying to get as many hours as possible directly addressing user questions and enhancements. I've managed to get 43 releases posted to GitHub and a number of new Demos and Demo changes since the May 4.60.0 release so things aren't standing still.
PySimpleGUI 2022-06-18T10:03:10Z
REPL.IT - Credit where credit's due
I've made a couple of announcements over the past months about closing the PySimpleGUI REPL.IT account after struggling with getting support on a critical problem.
As I was going through the final stages of closing things up, I asked for a hand in deleting the account's contents. The support team reached out with a "give us another chance" message. I'm willing to give people/companies another shot that sends a message that was like theirs where they admitted the problem could have been handled better and that they wanted to try again. I make a lot of mistakes and I assume others do too. I think it sends a powerful message when they send a message like the one they sent.
The REPL.IT Engineer
Toby, an engineer that was a somewhat recent hire, contacted me and he kept me up to date on the progress. I was really impressed. Not only did he really and truly dig in on this problem, but once he found a root cause, rather than jumping right in and making a quick fix, he paused.
The Reflection Step
He's taking his time in understanding the impact not just now, but down the road, of the various options he has. I really respect an engineer that's willing to do that. Not all engineers make time to take this reflective step and he gets bonus points even if the result isn't a fix. It doesn't diminish what I've seen so far.
We're not to a fix yet, but from what I've seen over the past weeks, I believe he's going to come through. If so, I'll happily sign back up as a paying member of their service.
Hopeful
I'm hopeful... that feeling about something in this project, by itself, however fleeting, has great value to me.
PySimpleGUI 2022-06-22T12:55:24Z
New Udemy Coupon Issue Opened
Acting on a good suggestion I received. Rather than the coupon codes being buried in these announcements, or only at the tops of the readme and documentation, having an Issue dedicated to the coupons may be easier for users to locate. It sounded like a reasonable suggestion worthy of experimenting with.
The Issue is this one: https://github.com/PySimpleGUI/PySimpleGUI/issues/5629
And is pinned at the top of the issues. Unfortunately, there can only be 3 pinned issues... and I unpinned the warning about not filling in the form.... (Sorry @jason990420 I hope this doesn't cause a flood of issues without forms... if so, that warngin will certainly be re-pinned!)
A few days away from issues
Like over the weekend, I need some time to work on some specifications, development, and meetings on some important PySimpleGUI work. It's difficult to remain focused on this work while also working the new and open issues.
I don't want anyone to feel abandoned, thus the announcement and I believe there is coverage on critical issues like the Mac Issues since @Chr0nicT is all over those.
Back shortly, of course. My apologies if your project is being delayed due to my absence.
PySimpleGUI 2022-06-24T13:05:14Z
New Window Movement Hotkeys
The Existing Control+Left Mouse Drag
You may not be aware of this capability, but you can move any PySimpleGUI window by holding the control key while clicking the left mouse button. This will cause the window to behave as if you have the "Grab Anywhere" feature enabled. It's very handy if your window's titlebar is somehow offscreen and you can't grab it to move the window.
The New Control + Arrow Keys
Like the Control + Mouse drag, you can move any PySimpleGUI window that's in focus 1 pixel at a time by holding the control key and then using the arrow keys on your keyboard.
This is particularly handy for arranging any "Desktop Widgets" running all the time and you want to precisely move them. Here's an example of how they can be quite handy.
I dunno, maybe I'm a little too OCD with my windows
Just like the control drag, you can turn this feature off when you create your window by setting grab_anywhere_using_control=False
when you create your window.
Another Weekend of Slower-To-Respond-To-Issues
Like last weekend, I'm going to be a bit slower to get to the issues. I'm around, working hard on PySimpleGUI, but less on the issues than normal. Really appreciate your patience. We're still working on the open issues for the Mac every day, so that area isn't going to be impacted. There's a significant documentation rework underway and a number of other areas that require my attention. @jason990420 usually beats me to responding to most issues, but I don't want to assume there's coverage by him on a weekend.
Thank you for all the kind messages that I see coming from lots of directions. It's difficult to communicate how impactful they are.
PySimpleGUI 2022-07-03T20:23:51Z
For Fun 1-liner Demo Program - Download & Display an Image
import requests
import PySimpleGUI as sg
"""
Demo Program - Download and display an image
Read an image from the Web and display it in a line of PySimpleGUI code
Copyright 2022 PySimpleGUI
"""
sg.Window('Read and Display Image From Web', [[sg.Image(requests.get("https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png", stream=True).raw.read(), key='-IM-')]]).read(close=True)
New Udemy Coupon
The coupon expired this past weekend. A new coupon is now available. I've decided to keep the price of the course low rather than keep it at $99. While it was the poorest performing month since the launch of the Udemy course in terms of income, I want to try keeping it significantly lower so I'm trying $19.99 this month.
The new coupon sets the price at $19.99. The code = D11B305A347585E7A915
This link will take you straight to Udemy and apply the coupon:
https://www.udemy.com/course/pysimplegui/?couponCode=D11B305A347585E7A915
The readme here on GitHub (www.PySimpleGUI.com) and the www.PySimpleGUI.org documentation always have the latest coupons and links so please check them out prior to going to Udemy. You'll get the best deal possible this way.
Thank you!
As always, I'm so grateful for the users of PySimpleGUI, for the help of the amazing @jason990420, and the whole PySimpleGUI team. I truly mean it when I say -- "It's the dream come true that I didn't know I had"
PySimpleGUI 2022-07-05T13:53:22Z
Project Spotlight... mizosoft - ImageRestorationAndEnhancement
https://github.com/mizosoft/ImageRestorationAndEnhancement
One of the things that I really enjoy is seeing the many different applications being built with PySimpleGUI. GitHub reports over 5,200 public projects using PySimpleGUI. There are considerably more I believe since many don't use requirements.txt and I believe this is how GitHub is finding them.
I can't keep up with the rate new ones are being added, but as a "guilty pleasure", for my own enjoyment more than anything else, I browse a few every couple of weeks. I've mentioned this before and that beginner projects are of particular interest as that's often where innovation happens.
There is a "Colorizer" project under the PySimpleGUI account that's been fun to play with. This ImageRestorationAndEnhancement repo is in a whole other league. The results are, well, stunning.
You'll find these images in the project's readme.
These Mark Twain images were shocking to see. I've never seen results that had such an emotional impact before. A whole new level of "reality" was added. It brought a familiar photo to life.
I've seen this black and white photo many times. The restored color version is way beyond anything I've experienced in these colorization/restoration algorithms. I'm no expert in the field and haven't seen a huge number of examples, but of the ones I've seen, none had the kind of impact this one had.
The written word breaks down for me when I try to describe emotions so my apology for rambling and trying.
Anyway, here's Mark Twain presented in a way unlike anything I've seen....
PySimpleGUI 2022-07-08T14:54:04Z
4.60.1.56 - Latest GitHub Release
I've changed the number of current GitHub cycle to be 4.60.1.X
The 4.60.1 "dot release" was unusual and done external to the 4.60.0.X work that was happening on GitHub. Keeping the GitHub version frozen at 4.60.0.X has been confusing users, so the releases went from 4.60.0.55 to 4.60.1.55, 4.60.1.56, ...
It's more obvious now that the PyPI version is "older" than the code on GitHub. I'm sorry about the numbering confusion
It should be more obvious now that the GitHub version is the latest and greatest code.
PySimpleGUI 2022-07-10T06:20:29Z
Happy PySimpleGUI Day!
From here:
To here:
In under 4 years... with much more to come....
Thank you everyone for making these years so enjoyable.
PySimpleGUI 2022-07-17T19:55:35Z
Image Restoration Project from Mizosoft
A couple weeks ago I posted a "Spotlight" of an Image Restoration project that's by far the most impressive of these I've ever seen. The GitHub Repo for the project is:
https://github.com/mizosoft/ImageRestorationAndEnhancement
It's an "area of interest" for me. You'll find a repo under the PySimpleGUI account that does image colorization that I created back in In December of 2019:
https://github.com/PySimpleGUI/PySimpleGUI-Photo-Colorizer
The difference in what these projects produce is vastly different. My 2019 project has been fun, produced some nice results, and fulfilled the original intent of demonstrating that a front-end GUI brings very powerful capabilities to a larger audience. It's one thing to add color to an Ansel Adam's photo.
It's an entirely different thing to restore a family photo
Bridging the GUI Gap
PySimpleGUI bridges the GUI-gap between the "world" and powerful new technologies. Programmers have no problem opening a command prompt and typing in 100's of characters and deciphering which command line options to use... but your aunt Martha isn't so great at this.
A Complete Solution of the Mizosoft Image Restoration Project
Even with code posted and instructions, it can still be a real challenge to get AI programs fully operational. Trained models need to be downloaded and placed in appropriate folders. It took me quite a while to get a fully working program. Thankfully I had a LOT of support directly from the author who was very patient and incredibly responsive.
I managed to get all the trained data downloaded and was able to run the restoration program on a number of family photos. One of the photos has been, well, life-changing to see. I'm not exaggerating. It's difficult to put into words emotions (you've seen years of me struggling to do this right here in the announcements). It was impactful enough that I wanted to enable others to experience this too.
An Expanded GUI
I made some changes to the original code:
-
It runs the lengthy operation as a thread so that the GUI remains alive and doesn't appear to be locked up
-
An output folder can be specified to copy the resulting images to (you'll also find them in a subfolder of the "output" folder)
-
The stdout and stderr information is sent to a multiline element so that you can see the progress in your window
Where To Download
The full project can be downloaded as a ZIP file from this address:
http://mizosoft.imagerestoration.pysimplegui.org
The ZIP file is large with a total of about 4.5 Gigabytes.
You may have to copy and paste the link into your browser as GitHub doesn't seem to correctly redirect it. The link points to DropBox where I've hosted the files after obtaining permission from the Mizosoft project owner.
The Power of an Individual Thank You
I had the pleasure of sending an email to Moataz, the software's author, that is similar to some of the emails I receive from PySimpleGUI users. His work had a personally life altering impact on me. I know what it's like to receive one of these emails and found it very satisfying to have the opportunity to send one.
The reply I received was astonishing. It reinforces the "It's circular" theory I have of inspiration, motivation, and gratitude. He inspired me, resulting in a message, that then inspired him.... around and around go these very powerful positive messages.
Thank you everyone that takes a moment to say "thanks". It means a lot.
PySimpleGUI 2022-07-21T18:18:16Z
Version 1.11 of Demo Browser Released
There is a new version of the Demo Browser here on GitHub, and I've also made a release of psgdemos
that includes this version 1.11 as well as updates to Demo Programs.
Version 1.11 added a "Show ALL file types" option.
I use this tool all day, every day. It's my basic way of searching, editing, and launching Python programs.
I'm making updates to the docs and that means sometimes needing to search markdown files. I like this tool better than PyCharm or other tools.
@Chr0nicT did a nice job with the search algorithm in the Demo Browser. So, I added the search all files option so I can search markdowns and any other files that are in the tree specified.
Enjoy!
PySimpleGUI 2022-07-22T13:40:30Z
PySimpleGUI.org - The official home of PySimpleGUI Docs
From the project's launch, I've used the address PySimpleGUI.org when pointing folks to the docs. They are hosted on ReadTheDocs. Most people that write tutorials or paste a link have in the past ended up getting a link that had "readthedocs.io" or something like it.
As part of the documentation rework that's underway, we've integrated the PySimpleGUI.org address so that the docs show this address when you're navigating the documentation as well.
This is a more complete address to use..
https://www.PySimpleGUI.org
The previous forwarding I had in place used http rather than https as it was a primitive forward. Should be much easier to remember and work with now.
Subdomains
There are numerous subdomains for PySimpleGUI.org. A couple of examples are:
https://Cookbook.PySimpleGUI.org
https://SDK.PySimpleGUI.org
PySimpleGUI.com
PySimpleGUI.com continues to forward to this GitHub, but not quite in an integrated fashion. It too now uses https instead of http.
https://www.PySimpleGUI.com
PySimpleGUI 2022-07-22T20:57:27Z
More PySimpleGUI.org Subdomains
While updating the links in the SDK Help Window, I added a few of the subdomains to the comments at the top of the PySimpleGUI.py file. These are also in the new documentation update that's being worked on now. A number of these you could maybe guess would get you to the information you're after.
https://SDK.PySimpleGUI.org - The SDK Reference tab
https://Calls.PySimpleGUI.org - The SDK Reference tab
https://Cookbook.PySimpleGUI.org - The Cookbook tab
https://eCookbook.PySimpleGUI.org - The eCookbook located on Trinket
https://Anncouncements.PySimpleGUI.org - The Announcements Issue on GitHub
https://Install.PySimpleGUI.org - The "How to install" section of the docs
https://Upgrading.PySimpleGUI.org - The "How to upgrade" section of the docs
https://Udemy.PySimpleGUI.org - The Udemy course
https://GitHub.PySimpleGUI.org - The PySimpleGUI GitHub (also the located at PySimpleGUI.com)
https://Issues.PySimpleGUI.org - Open a new issue on GitHub
https://Bugs.PySimpleGUI.org - Open a new issue on GitHub
Udemy Price Reduced
I've dropped the Udemy price down to the lowest Price Tier that Udemy offers, $19.99, and have also created a new coupon that further reduces the price to $13.99.
While the original price of $99 did bring in more income per month, the number of students was, of course, significantly lower. The difference in the total per month wasn't a huge difference. I would much rather make the course affordable to everyone that wants to take it than make a little bit more per month.
The Mac Debugging Continues
@Chr0nicT and I have been working on the Mac "invisible window" problem every day for a while now and making progress daily too. While it was limited to M1's previously, because 12.3 is being rolled out onto non-M1 systems, the problem is spreading to other hardware. So, it's clear this is a high-priority item and thus getting lots of attention. You can expect more updates this weekend to GitHub with more approaches to workarounds / fixes.
PySimpleGUI 2022-07-26T14:36:26Z
EMERGENCY Release 4.60.2 Being Prepared for Mac OS 12.3+
The invisible Window problem is growing to the point that I really can't wait any longer to get something posted to PyPI.
The approach I've decided on is another "Patch" that's Mac specific. Until a "fix" is found on Apple's side and put in or we find a better workaround, the best approach so far is to set the Alpha Channel to 0.99.
Much more detail can be found in this issue that has 91 comments and growing.....
https://github.com/PySimpleGUI/PySimpleGUI/issues/5471
The patch has been checked into GitHub. I need help from as many Mac users as possible with this patch to verify we've got a viable fix that's going to PyPI.
I was really hoping for a better workaround, but this one seems to do really well visually and does fix the problem 100% of the time... so my hopes really aren't relevant in the big picture. The important thing is to release it to PyPI today.
PySimpleGUI 2022-07-26T19:30:27Z
4.60.2 PySimpleGUI 26-Jul-2022
-
Emergency Patch Release for Mac OS 12.3 and greater
-
Adds a PySimpleGUI Mac Control Panel Controlled patch that sets the Alpha channel to 0.99 by default for these users
-
Is a workaround for a bug that was introduced into Mac OS 12.3
-
An emergency patch release was posted to PyPI this afternoon. It adds the Alpha Channel of 0.99 workaround for Mac OS 12.3 and greater.
It's unclear if the version of Python from Python.org has this problem or not. We're still working on this really terrible problem that Apple was so kind to give to us.
I'm glad we were able to post a fix that visually looks acceptable. This has been a "not fun" issue. Having it be intermittent made the problem even more difficult.
We're "not dead yet" (Monte Python)
PySimpleGUI 2022-07-27T06:50:04Z
Another Mac PyPI release today
My love/hate... ok hate... relationship with the Mac continues. The code released yesterday has a problem. It'll be fixed and released today.
Time with Issues - Need to pull back some....
I continue to be in a mode where my time here is limited. I'm debating on whether I should be simply absent rather than supplying poor support or in some cases, being sloppy.
PySimpleGUI is a huge project... the meme-ish "iceberg" visual comes to mind.
I can't believe I'm invoking a meme visual...
In short, I'm personally stretched too thin and this is having a negative impact on the project. Please understand that I am actively searching for solutions, which only compounds the problem.
There are some key issues that I'll be able to concentrate on. The others are simply going to have to wait.
Thank you SO much
To be clear... the PySimpleGUI users have been coming through again and again when posting issues, sending support, writing personal emails,.... I see no ugly messages... no unkind words. You're a wonderful user base. These are my issues that I'm grappling with, and I apologize they're spilling over into supporting you.
PySimpleGUI 2022-07-27T22:18:48Z
4.60.3 PySimpleGUI 27-Jul-2022
-
Emergency Patch Release for Mac OS 12.3 and greater
- Fixed bug in Mac OS version check in yesterday's 4.60.2 release
4.60.3 posted to PyPI. The same changes were rolled into 4.60.3.68 which is currently on GitHub
PySimpleGUI 2022-07-29T13:04:39Z
PySimpleGUI Tip of the Day - upgrading to GitHub version....
Want to run the latest version of PySimpleGUI from GitHub? If you previously pip installed PySimpleGUI, then it's easy-ish.
There are several ways to go about this. The main docs discuss the ways here:
https://www.pysimplegui.org/en/latest/#upgrading-from-github-using-pysimplegui
This subdomain also gets you there:
https://upgrading.pysimplegui.org/
Personally, I like using psgupgrade
from the command line.
There are issues sometimes. If a failure, you might want to pip uninstall PySimpleGUI, then pip install the lastest from PyPI, then try to upgrade from GitHub.
An Example 4.60.3 to latest on GitHub
psgmain
shows me what I'm currently running:
Typing psgupgrade
from the command line shows me this initial window:
Here is the remainder of my session as a GIF so you know what to expect:
PySimpleGUI 2022-08-01T20:11:45Z
REPL.IT - Working again...
For quite a while there was a problem using REPL.IT. Windows could not be opened at any specific location. They were always made at 0,0. Thanks to an awesome engineer there named Toby, the problem has been fixed. If you use a tkinter template, then his fix is included. Here's an example from Demo Programs project that I created earlier today that you'll find here: https://replit.com/@PySimpleGUI/DemoPrograms
In this screencapture, you can see windows are created both in the center of the screen and for programs that remember their last location, they are correctly created in the location they were last closed.
A HUGE THANK YOU TO TOBY AT REPL.IT!!!
Thanks for the awesome support!
PySimpleGUI 2022-08-06T16:34:20Z
Eating Your Own Dog Food
Eating your own dog food is a lesson I learned way back in the early days of my career. The more runtime you as a developer, team, or company can get on your own products the better.
I've got 30 PySimpleGUI programs running in the background on my computer at all times. These never close. I launch and use countless more during the day. There are 2 running in the system tray. One does hotkeys, the other a discord tool. As stated numerous times, I launch and use the Demo Browser dozens of times a day.
Running programs for days or weeks builds confidence in the stability of a release or product. PySimpleGUI most likely doesn't have a serious memory leak or one of these 30 programs that run 24/7 would most likely encounter a problem. This clock, for example, calls window.read
once a second. Over the course of many days that's a lot of window.read()
calls using a timeout.
I'm able to keep a close eye on what's happening to my processor cores using this PySimpleGUI desktop widget, not only giving me vital debug data continuously but exercising PySimpleGUI continuously too.
There's a "Launcher Bar" Demo Program that minimizes down to a single icon on my desktop. It's weird, but I like it as it's quicker to use than the start menu and I've already got 20 or more icons pinned to my taskbar. I noticed that it's started to act very strangely when I "minimize" it.
Here's how it normally minimizes (note the use of the "Gumby Cursor"😀 I get the benefit of testing the cursor feature and I get to smile at seeing Gumby several times a day:
I don't minimize it often so I only recently noticed this problem:
It didn't take much debugging to determine that the hiding of the Column elements was taking a very long time. In release 4.60.3.71 I added checks to the update methods for elements to determine if a window is closed. This check, evidently, takes a very long time due to the complexity of this window. I haven't noticed a problem is any of the other programs, but it certainly is noticeable in this one.
I checked in a change this morning 4.60.3.76 that fixes this by adding a "quick check" option to the function that determines if a window has been closed.
PySimpleGUI 2022-08-07T11:07:11Z
Still Committed....
If you've been following this project, using PySimpleGUI since 2018, then you've likely noticed a "slow-down" in activities that are visible here on GitHub. I've mentioned a few times over the past weeks that this was and is happening.
As always, I work every day on this project and am as dedicated as last year, the year before, going back to the launch in 2018. I appreciate the patience and the help users have been showing and providing.
I debate daily if no participation at all in the Issues is better than making brief appearances or fixes/additions that are not huge in the number of changes required. Personally, I need to maintain the connection I get here on GitHub. It's from you all that I draw a significant amount of motivation. Seeing what you're creating has a powerful impact.
It's one of the reasons I browse projects using PySimpleGUI every week or two, sometimes catching some of you off guard. One user recently commented they didn't expect anyone to view their repo so quickly. That may be a message we all can benefit from. Just because you don't hear from visitors doesn't mean people aren't appreciating your creation and learning from you.
Again, a message of gratitude
Thank you so much for making this experience a unique, unexpected, and special one. PySimpleGUI wasn't a planned event in my life. It was a tool for me and only me.... until it wasn't... and that's when this fun ride started.
PySimpleGUI 2022-08-14T15:06:05Z
Evaluating Python Packages
PySimpleGUI is not the best Python GUI package. 🙄 I must have said this 1,000 times in the YouTube videos, documentation, Udemy course, etc. Blanket statements in programming with no requirements, no context, or none of the subtle hints at a project's parameters are not only worthless, but they will almost certainly put you at a disadvantage before you've even begun.
Look at the PyPI information
With security being heightened and open source is in when I would call an unpredictable state, understanding the code you're going to be living with is really important to you and to the company you're working for. By "unpredictable state", I'm talking about the sustainability problem that open source has at its core and that it's not been solved.
Maybe you are a student and what you're building doesn't matter. Whether or not the project will be around next week/month/year doesn't matter to you if you're never going to run your code after you've turned in your assignment, or you've learned a new feature of Python.
But, for some of you, particularly if this is your profession and you're writing code for your employer, then knowing what you're getting yourself, your company, and the person taking over your job in the future is important.
Act Purposefully
Act with purpose, not just in programming, but in life in general.
Think about what you're doing. Take a moment and investigate. If you're shopping for cereal and grab a box that looks like it has a flavor you would like, then you can safely be cavalier and toss it into your grocery basket. Being spontaneous can be fun! Go for it on occasion, but be purposeful too. Make sure it's an appropriate time to be spontaneous. Buying cereal, go nuts and be as spontaneous as your digestive system allows.
Choose Python packages by investigating them. Go to the PyPI site and read the release history. See where the project repo is located. Kick the tires. Maybe think of it like buying a car. You're going to be stuck with it for a while. When was the last time the oil was changed?
The last release was in 2018? hmmm.... That calls for a little more digging perhaps. Maybe the package no longer needs any work... it's 100% done, with no bugs, and nothing new to add. Or maybe the person that wrote it has lost all interest and doesn't check the GitHub issues that may be piling up. Go look and see.
Beware Lists of Packages
The best 5 packages for doing X. "The top" anything. They're fine for getting one set of packages to investigate. They're a starting point. They're often an opinion. And I've noticed they're often copied from person to person to person, perhaps blindly, and I'll be bold and say sometimes no value is added. Some have an agenda as well, a hidden purpose.
Errors Caught Early Are Less Expensive
This is a corerstone to software development. Catch a problem while designing a system and you've save a lot of time, money, gray hairs than if you figured out you've got a problem when the first customer reports it.
I was taught that it was the Japanese automative manufacturers that helped shape softwareand product development. Continuous process improvment, constistent quality control, etc, were co-opted by software development from other industries and systems. How much of that's true, I'm not sure. I heard about these lessons/stories in the 1980s, pre-Internet, so it wasn't quite as easy to fact-check on the spot. 😉
The point here is that discovering you're unable to get a critical bug fixed because the project is no longer maintained is going to cost you and your company considerably more, maybe, had you factored this into your choice of tools.
I've Screwed Up Plenty
Some of these lessons I've learned directly.
There is no claim here, at all, that I've got all the answers, that I never make mistakes, or don't do enough research.
Goal # 1 - Enjoying the Process (Having Fun)
A wise person told me once to focus on the journey, not the destination.
When I have a little spare time, it's not only enjoyable to see what's being made, but I learn from the beginners, the students that are using PySimpleGUI. They also tend to be enthusiastic about programming. Seeing someone that's excited about using PySimpleGUI makes me excited to work on it. It's contagious.
Thank you for the inspiration!
PySimpleGUI 2022-08-14T22:44:59Z
New Demo Program - Simulated Buttons with Mouseover Highlighting
I was inspired by a user XxPregoxX today who is creating a custom titlebar using images.
I wrote a short, 31-line Demo Program, that simulates a Button
using a Text
element. Simulating a Button using a Text element is not a new concept. What is new in this Demo Program and associated Trinket is the highlighting on mouseover. tkinter is inconsistent across operating systems with Button highlighting. The Demo Program enables you to have "buttons" that highlight consistently across operating systems.
The code works with any theme. He is the default PySimpleGUI theme and the dark red themes.
https://user-images.githubusercontent.com/46163555/184555901-56b9ff3c-6425-47e9-a722-e19895da3f02.mp4
https://user-images.githubusercontent.com/46163555/184555900-d70865aa-1884-480b-bb5b-b8d68860dfe2.mp4
Give it a go on Trinket
To see it operating right away, head to this new eCookbook Recipe.
Tuples as Keys... in this Demo
While the functionality is interesting, and demonstates using the bind
method for elements, it's the use of tuples as the key that's the reason I wrote and released this demo.
Tuples make event processing simpler. Instead of parsing a string to get "key modifiers", you can access an item in your tuple. For keys that are strings, key modifiers are concatenated to the key. If your key is a tuple, then to modify the key, PySimpleGUI creates a new tuple that contains your key and the modifier.
In this program, the keys for the simulated buttons have the format:
The first "Button" has the key:
We're binding the tkinter event '<Enter>'
which will modify the key with the text 'ENTER'
. When this event is returned from the window.read()
call, it will have the format:
This enabled me to use the if statement:
to determine if the tkinter <Enter>
event is the event returned from the window.read()
call.
Tuples in Your Future
One last tip.... my fault-tolerant reminder program that's just below my taskbar.
PySimpleGUI 2022-08-17T15:25:49Z
Rediscovered pypy Project
While rewriting the documentation, I saw the pypy port of Python listed as one of the environments that PySimpleGUI runs under. I had completely forgotten about the pypy project.
So, I gave it a try again for the first time since 2018 and WOW am I glad I did.
From the pypy webpage:
On average, PyPy is 4.5 times faster than CPython
It certainly feels 4.5 times faster to me.
Normally, having the 30 or more PySimpleGUI "background programs" I have running at all times means one of my processor's cores is maxed out.
You can see the difference easily using a snapshot just taken of my CPU usage:
And the one found in the PySimpleGUI readme, that was typical of my CPU load:
Not All Packages Easily Installed
You can "pip" install packages with pypy just like normal Python, but I ran into trouble with Pillow and OpenCV. psutil was a nice surprise.
Dilemna
This situation leaves me in a professional versus personal dilemma. A week and a half ago I wrote a post entitled "Eating Your Own Dogfood". This new re-discovery is a good reminder that while I personally am benefitting and having a lot of fun with this new environment, it is not the environment that my users are running. Running pypu on my system 24/7 instead of CPython defeats the purpose of these around-the-clock tests.
Going With A "Balanced Approach"
I'll continue to run my background / regression tests as I normally did. For some of the utilities I've written to aid in development where a boost in speed will be felt the most, I'll selectively apply using pypy
"Experiment"
I have a morning "ritual" of sorts that includes writing numerous lists in my lab notebook. I'm working on a YouTube video about using paper and pencil/pen in software development that may explain a bit of this.
I write a list of "things I'm thankful for" (gratitude is a "brain thing" that a positive impact). Another is a list of 8 reminders of "How I Want to Live"
based on the work of a philosopher that I've enjoyed studying. That list includes "Think Differently"
and "Experiment"
.
Maybe it's silly to write the same lists every morning. It works for me personally as a reminder. "Be Joyful"
is also on that list and I try to live a joyful life and spread joy here as much as possible. "FUN", it's the # 1 goal! These lists are simply a way to remind me that these are my goals.
Anyway... the point is to experiment a little. Poke around at doing things a little differently and see what happens.
My friends hear me say this disclaimer frequently, probably because of the desire I have to experiment:
"I have lots of ideas, most of them are bad"
Go forth and fail! You'll find success sprinkled in between.
PySimpleGUI 2022-08-18T17:32:14Z
My pypy Experiment....
OK, well, it's a good thing I mentioned "Balanced Approach", to "Experiment".
Since I sorta made a recommendation, I've got a sorta obligation to give a heads-up should I see a problem.
Heads up!
I'm seeing a memory leak issue where garbage collect is not running, or it's not running often enough to stop a crash due to being out of memory.
The same code... the same application, the same PySimpleGUI, run on CPython 3.6 & 3.8 is rock solid. But on pypy, it crashes. I was able to run overnight if I manually call gc.collect()
which is how to trigger a garbage collect. While this "fixes" the problem, I should never have to call this as a developer.
Experiment... and perform measurements when you do
The lesson, maybe, if there is one... Go ahead and experiment, but collect data when you do. I'm glad to have rediscovered this project. There are times when it'll be very useful. It's another tool for your batman/batgirl toolbelt... the trick is knowing when to use it.
PySimpleGUI 2022-08-21T17:02:13Z
psgtest Version 1.12 (1.12.1 on PyPI) Released
A quick change tosday to psgtest to make working with versions of Python such as the pypy release, easier to integrate.
It is possible with prior releases of psgtest to simply use one of the slots labeled with a specific Python version to hold a custom version of Python. When authored, these releases were meant to hold the main CPython releases.
This morning was an addition of a "Custom Interpreter" as shown in this settings window:
It makes working with something like pypy easier. The same test program can be used on the variable releases of Python by choosing one from the drop-down list in the main interface
Running the main test harness is accomplished by running the Demo Program: Demo_Main_Control_Test_Panel.py.
Choose 3.11 and click Run, then choose pypy and click Run. It makes testing across releases of Python/tktiner much more efficient and less error-prone.
PySimpleGUI 2022-08-21T23:29:19Z
Stdout Stderr Rerouting fixed....
The bug I was out to squish get this weekend... the one that was causing trouble with stdout/stderr not being correctly restored...
has been fixed.
Here's a little test harness that will reroute stdout via either a Multline
or an Output
element.
import PySimpleGUI as sg
counter = 0
def other_window():
global counter
counter += 1
layout = [[sg.Text('My Window')],
# [sg.Output(s=(60, 10), key='-O-')],
[sg.Multiline(s=(60, 10), write_only=True, reroute_stdout=True, key='-MLINE-')],
[sg.Button('Go'), sg.B('Go again...'), sg.Button('Exit')]]
window = sg.Window(f'Window Title {counter}', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Go again...':
other_window()
window.close()
del window
def main():
layout = [ [sg.Text('My Window')],
# [sg.Output(s=(60,10))],
[sg.Multiline(s=(60,10), write_only=True, reroute_stdout=True, key='-MLINE-')],
[sg.Button('Go'), sg.B('Go more'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Go':
other_window()
window.close()
print('Back to the original stdout')
if __name__ == '__main__':
main()
It looks like this one is fixed, better than before.
Back to more writing this week
After a weekend break to do this fix and answer a few issues, it's back to the documentation for me this week
Mac bug news
The tkinter team replied back that they believe the newest 3.10.6 has a fix. I met with @Chr0nicT this morning and he's queued up to get back on the Mac this week to test out their findings.
User Screenshots - Some good stuff coming!
Issue 10 has had the "collapsed GitHub issue" for years.... posts are hidden by GitHub. We're working on a solution that integrates the posts in Issue 10 with the primary documentation. So, please keep showing us all what you're making by posting some screenshots there!
HERE: #10
Beginners.... "non-programmers" (if you write PySimpleGUI code, you're a programmer)... please post screenshots in your repo and here
Nothing is too small to share. I learn something new from public PySimpleGUI projects every week!
I truly love what you're making and I am inspired by your work.
I am sure that others are inspired by your work too. If you're feeling like you're too new to programming to share... you're not.... it's the beginners that I learn the most from. This is SO true.
I actively seek out beginner projects to learn from them. The beginners don't know the "rules" yet. They don't know what's impossible. They simply want to make something and give it a try. So, don't be shy.... show your work off. There's nothing to be shy about. You made something. That alone is "enough."
PySimpleGUI 2022-08-22T23:01:38Z
User Project Spotlight - morse-analyzer
https://github.com/spaceymonk/morse-analyzer
Yesterday I posted an announcement requesting screenshots and suggested that beginners, in particular, are of interest. I didn't know at that time that I was about to be blown away by what onePySimpleGUI beginner did.
I dn['t know how much GUI experience @spaceymonk has, but I can tell you from the conversation we've had in the past 23 hours, that this was his first Ptyohn GUI project. His words do a better job of communicating this craziness than any explnation I could write:
This is my first GUI application on Python and I did not want it to become a complex project
Now take a look at the screenshot of his first GUI application on Python, intentionally chosen so as to not be complex.
THIS is why I look around GitHub at what you're all building. The inspiration from seeing this kind of work is incredible.
"Seek out Awe-Inspiring Experiences"
I was reading in a book called "Chatter", that one of the ways to manage stress or difficult feelings is to seek out "Awe-Inspiring Experiences". For me, these incredibly creative programs you're making are certainly awe-inspiring.
Love seeing these images! I'm certain, very certain, other people love seeing them too, so share your work. You never know who you may inspire someday, any day, maybe every day.... so take a chance by showing everyone what you've made.
PySimpleGUI 2022-08-23T12:48:21Z
Button "Shortcuts" added...
Over the weekend, to give me a break from the other tasks on my palate, I dropped in a new feature. I've found I need a couple of tasks, a primary task and a secondary one that is not as important and allow my unconscious brain time to work on the first.
This code, added in 4.60.3.80, is only available on GitHub so I'm not yet releasing a Demo Program to accompany it. Instead, I'll post a short one here.
import PySimpleGUI as sg
"""
Demo - Hotkey/Shortcuts for Buttons
How to get Underscores into your Buttons
Buttons now (as of 4.60.3.80) can way contain the "Shortcut indicator character" like Menus
It's very basic and the feature needs to be enabled for backward compatibility reasons
The brief instructions:
* Enable the feature - for now, it's manual - sg.set_options(use_button_shortcuts=True)
* Use & before a character and it'll be shown with an underscore
* Use \& if you want to display a "&" in the string rather
* Use window.bind to complete the operation
The chars will be removed when making the key.
sg.Button('&Go') will give you the event "Go" when the button is clicked
Copyright 2022 PySimpleGUI
"""
sg.set_options(use_button_shortcuts=True)
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Output(s=(40,6))],
[sg.Button('&Go'), sg.Button('Config \& Stuff', key='-CONFIG-'), sg.Button('E&xit')] ]
window = sg.Window('Window Title', layout, finalize=True)
window.bind("<Alt_L><g>", 'Go')
window.bind("<Alt_L><x>", 'Exit')
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
print(event)
if event == '-CONFIG-':
print('Got a config event')
window[event].update('&New')
window.bind("<Alt_L><n>", '-NEW-')
elif event == '-NEW-':
print('New binding was found')
window.close()
The Shortcut character "&" in the PySimpleGUI Menu definition has been a fun capability. I've extended it to Buttons.
There are a few things that are important
-
You need to explicitly turn on this feature. If turned on by default, a lot of existing application would break that are in the field
-
You need to add a
bind
call so that the Alt-Char combination will be bound to your button -
There are notes in the comment of the example like those above
It's far from perfect, but it's a good little feature to start with. It's in the "Good Enough" category for me. Better than nothing, didn't take a ton of time to do. Completely optional if you don't like it.
Here's an example session of the above program
PySimpleGUI 2022-08-26T05:23:59Z
What I Find on GitHub
I've written here numerous times how much fun I have in seeing what you guys and gals are creating. I can't keep up with the pace that projects are being created and posted.
Every week or two I rummage around a little on GitHub and see what I can see. I never know what I'm going to find.
I've been doing these informal surveys for a few years, and the most surprising discovery was....
JOY
I find some of my joy is present in these users' repos. And I think it's clear that some users are expressing their own joy.
A developer talking about "joy" in a GitHub Issue sounds kinda crazy or silly, but when the project has "Having Fun" as the first goal it doesn't sound as silly. Having fun and experiencing joy are just as important (more important?) as which version of Python to run and using a dictionary versus a list to solve a problem.
Two Colorful Projects!
Both of these projects make use of color in specific ways.
User Project Spotlight - Wordle
https://github.com/dennisbyington/wordle_gui
The first of these, the Wordle demo is gorgeous. It's also the first time the author has made a GUI in python. The screenshot is from a Mac. I ran it on my Windows machine and it looked great on it as well. There is a lot of polish for a first-time-GUI.
I know I've said that I learn from beginners in these announcements. I'm willing to show my ignorance of tuples so you too can learn something from Dennis. I thought that parentheses are required when tuples are used as a key to get a dictionary's item.
User Project Spotlight - Chat Rooms
https://github.com/vasja34/Chat-Rooms-Project
This chat-room project is also quite colorful.... and it uses a somewhat rarely used PySimpleGUI feature - cprint
(the color print). It has almost all of the same paramters as the Python print
statement. The file/stream is the parameter that PySimpleGUI doe not implement.
I particularly liked seeing demonstrated how to get many colors printed on a single line. The trick to achieving this is to set the parameter end=''
Output
Element - Welcomed back....
For a while, the Output
element was not recommended and was suggested that users switch to using the Multiline instead. In release 4.60.0 the implementation of the Output Element changed. It is now a subclass of the Multiline element which resulted in it being added back onto the "A-List" of elements. Today I also added code that automatically reroutes cprint
to be auto-rerouted to the Output element if one is present. You can reroute cpsrint manually as well if you dont' get the chnges from yestefay.
Here is an example of how cprint
can be used to quickly add a colorful way of debugging a program that's in development
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(k='-IN-', enable_events=True)],
[sg.CBox('Checkbox 1', k='-CB1-', enable_events=True), sg.CB('Checkbox 2', k='-CB2-', enable_events=True)],
[sg.Button('Go'), sg.Button('Exit')] ]
layout_output = [[sg.Output(size=(60,20), font='Courier 12')]]
final_layout = layout + layout_output
# if you want to "hide" your Output Element in a tab then uncomment
# final_layout = [[sg.TabGroup([[sg.Tab('My GUI', layout, k='-TAB1-'), sg.Tab('Print Output', layout_output, k='-TAB2-')]], k='-TGROUP-')]]
window = sg.Window('The fun of cprint-ing', final_layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
# Display the event and the values dictionary in beautiful technicolor
sg.cprint('EVENT: ', end='', erase_all=True)
sg.cprint(event, colors='white on green')
sg.cprint(f'KEY VALUE', c='white on purple')
for k, v in values.items():
sg.cprint(f'{k:15}{v}')
window.close()
PySimpleGUI 2022-08-26T17:11:42Z
Your Work - Finally Fully Visible!
The "problem" with GitHub Issue 10, the user screenshots is that GitHub "Hides" 243 of them currently. In the middle of the issue you'll find:
I'm thrilled to say that ALL of your screenshots and posts are now visible as part of the documentation, in the User Screenshots tab:
https://www.pysimplegui.org/en/latest/user_screenshots/
We've been working on solutions to this for a while and finally have one that's going to work well.
PLEASE continue to post in Issue 10. Our GitHub Issue bot will automatically take your new posts and upload them to ReadTheDocs (we're working on that part now)
I've got some formatting work to do and fix up the Table of contents (it has each individual date at the moment) and the header's a little funky... but, it's in a "Good enough" state to let it go and be available for everyone to see.
Thanks for your hard work and sharing your creations. It's very motivating for me, and I'm certain it is for others as well.
Thank you to everyone that's taken the time to upload one.
PySimpleGUI 2022-08-27T20:21:06Z
Two User Screenshot Tabs
At the moment, I've made 2 tabs that have the user screenshots from Issue 10.
https://www.pysimplegui.org/en/latest/user_screenshots/
One has the full information:
-
User ID and link to their GitHub account
-
Date of the posting
-
Full text of the comment
-
Screenshots
https://www.pysimplegui.org/en/latest/user_screenshots_plain/
The other has no text so that it's all pictures and the user that posted them:
-
User ID and link to their GitHub account
-
Date of the posting
-
Screenshots
I really like the plain screenshots... it's one long Wwwwwoooooowwwwwwww... look at all the stuff you can do!
Those shots started with the first, and quite limited releases of PySimpleGUI and have grown along with the new capabilities. Something is constantly being added to or improved. Tons more planned. There's no shortage of things to do.
Working on the Auto-update
The first phase is done which was to get what we've got up there.
Now we're working on getting incremental updates added so that when you make a change, it's relfected automatically on PySimpleGUI.org
Also Add to the New Docs
A similar was added to the new documentation that I'm working on now.
Mac Update
We tried the suggestions made by the Tkinter team and saw no improvement to the Mac window problem. So we're back to where we started. Will keep you updated as the situation unfolds.
Thanks for the thanks and encouragement
Really appreciate the messages of encouragement and gratitude,. They really helped during some difficult periods.
PySimpleGUI 2022-08-29T00:18:45Z
New Udemy Coupon Posted
I'm really sorry that the Udemy coupon code expired about a week ago. I normally have an entry in my calendar to remind me to create a new one, but I missed adding it to my calendar when I made the coupon back in July.
I created a new coupon this evening and have added it to the readme, the main documentation, the Cookbook, and the code AND, this time, I've added an appointment in my calendar so I won't miss the next one.
Thank you to everyone that's taken the course and said nice things to me afterward.
You're Making Impressive Windows!
My ego would love to have something to point to that I've done recently that had a big impact on the visual quality of windows, The TTK scrollbars did have a nice effect, but I'm talking about something bigger than that.
Overall, it seems like users are spending a little more time on their projects. You're polishing your widows. You're choosing colors in a purposeful way. You're adding custom graphics. The result has been some of the best-looking windows I've seen in the past 4 years.
I applaud your effort and success in making more attractive windows! It's inspiring.
PySimpleGUI 2022-09-05T20:16:55Z
More Emojis
A lot of emojis are being drawn by the artist that makes our emojis. The 10 of the new ones arrived and I've integrated them into the PySimpleGUI code and into the Emoji Toolbar Demo Program. It's how I'm able to easily paste emoji's here into the issues.
You can expect I'll be using a lot of this one given how much magic our wizard Jason does for us:
Mac Users - Help Needed
I've left a comment in the issue that is impacting all Macs that have upgraded to 12.3 and greater:
https://github.com/PySimpleGUI/PySimpleGUI/issues/5471
Your help is needed to verify that the tkinter code I put in the comment fails on your system. Until an engineer working in the tkinter code on the Python project is able to reproduce this issue, it won't be fixed. They've been unable to reproduce the issue given the code provided. It would be helpful to know if other Mac users are also not able to reproduce this issue.
This is a critical bug to get fixed because:
-
It's an intermittent bug in tkinter or TCL and won't simply go away on its own
-
ALL Mac windows have an Alpha of 0.99 set now, which ever so slightly degrades the quality
-
It's unclear if this bug will impact Windows or Linux too. It showed up on the Mac, but until it's found, nothing's for sure
## PySimpleGUIQt Mac Users
Could also use your help. An issue was opened by a user that had PySimpleGUIQt stop working after upgrading to MacOS 12.5. @Chr0nicT is still working on duplicating the problem. I'm also pulling the detailed PyPI install stats to see what versions of MacOS PySimpleGUIQt users are running.
https://github.com/PySimpleGUI/PySimpleGUI/issues/5803
Thank You NS-Systems for Sponsoring PySimpleGUI
I received a nice message from a Udemy course that's for Japanese users. They're also sponsoring the PySimpleGUI project.
You'll find their course on Udemy here:
https://www.udemy.com/course/python-gui-app/
Thank You to All Sponsors
While I'm thanking sponsors, I appreciate everyone that's sponsoring the project. The Udemy course is providing the most help. There's still a significant shortfall in the funding needed to cover the costs and I'm working hard to do everything I can to keep the project operational. Really appreciate everyone that's pitching in!
PySimpleGUI 2022-09-09T14:47:10Z
New Demo - Demo_Table_CSV_Display.pyw
Displays a table found in a CSV file. Make sure row 1 had header labels.
Features include:
-
Sorting by any column
-
Sorting ascending or descending
-
"Filtering" on any column
A quick message about a new demo program. It's another one of those that I wrote for my own use and then realized others could likely benefit.
It's under 100 lines of code. What can it do that Excel can't? It can display 2,000,000 rows of data and be responsive in scrolling through it. It takes a while to build the table for display when it's that large, but once it's on the screen, you can easily scroll through it. My version of Excel won't load more than 1,000,000 rows.
Some of the stats I've been pulling lately are huge numbers of rows. The PyPI installs for example are millions of rows.
The Simple Demo Program
I found myself copying this core bit of code into a number of small utilities, so I pulled it apart and into a tiny demo program.
It starts with a popop_get_file
that uses the history feature, something not in many if any demo programs. If your program prompts for a file and you're using the same file over and over, turn on the history so you don't have to choose it by pasting or opening the dialog.
Sorting and Filtering
I find myself using the filtering and sorting options in Excel the most. Filtering is where you reduce the data being shown by only including items matching a search of a column. Sorting is done by sorting on a specific column. This little demo provides both of those features.
As you'll see in this video, to filter, type in your search string and click the header. To sort, click on a header with the filter input empty. If you want to reset the data displayed to be the original data, click the "Reset Table" button.
https://user-images.githubusercontent.com/46163555/189375760-034bc77e-2e50-4795-bacd-581b65f3048b.mp4
Surprised By Size and Speed Capabilities
I had no idea that PySimpleGUI would be capable of displaying 2 million rows, easily. "Experiment".... this is one of the best ways to find out questions like these... just try it, so see how it goes.
Sometimes... it doesn't go so great...
Other times... it works out...
It's quick to mock up tests like these before integrating a feature into your application and is likely worth a quick test.
PySimpleGUI 2022-09-13T22:22:41Z
PySimpleGUI Tip of the Day (I know they're not posted daily, but they feel like they fall into a "tip of the day" category)
Continuing from the previous announcement about tables...(hmm... I'll also update the demo program).
Tables automatically have a page-up and page-down keyboard binding built into them by tkinter. They don't have a "Control-Home" nor "Control-End" key binding to go to the top and to the bottom of the table. Thankfully, it's trivial to add this capability to your code!
Binding Control-Home & Control-End
I chose to bind this keystroke at the Window
level. I could also instead bound to the Table
element, but that would require the Table
to have focus. Since there's only 1 element in the window this keystoke makes sense to use with, and because I'm lazy, I went with Window
.
Always make sure you finalize your window prior to calling bind
. If you don't, you'll learn to pretty quickly.
Check for the event and scroll to the top or bottom
Assuming your Table
element has a key of '-TABLE-'
, add these lines to your event loop:
if event == '-CONTROL END-':
window['-TABLE-'].set_vscroll_position(100)
elif event == '-CONTROL HOME-':
window['-TABLE-'].set_vscroll_position(0)
It's obvious how this works. When you get the event indicating that Control-Home is pressed, then call set_vscroll_position
, passing in 0 to represent 0% of the way into the table.
#superlazy
As I'm typing this in, I realized that I can be super-lazy! Why press the control key at all??
window.bind("<Control_L><End>", '-CONTROL END-')
window.bind("<End>", '-CONTROL END-')
window.bind("<Control_L><Home>", '-CONTROL HOME-')
window.bind("<Home>", '-CONTROL HOME-')
A warning is in order here that because I'm binding at the window level, pressing the home key while typing in the Input
element will cause your table position to change.
PySimpleGUI 2022-09-13T23:10:40Z
Demo Programs - Screenshots updated in the documentation
https://www.pysimplegui.org/en/latest/screenshots_demos/
The tab in the documentation that has the screenshots for the Demo Programs has been updated. They look fantastic!
It's been a long time since the Demo Programs screenshots were updated. I hired a contractor to do the work and he did an incredible job. Over half of them, 192 to be exact, are videos.
Thrilled with the results is an understatement.
I would like to promote him as an excellent contractor, but, well, to be honest, I don't want the competition for his time. I've got more work for him and I don't need the PySimpleGUI users taking his time when I need his help. Yea, it's selfish, but I'm honest about it. Does that balance things out with Karma?
I will definitely be providing information about contacting him in the future if it's appropriate to do so.
Enjoy! I've certainly enjoyed this project and the many amazing people I've met through it.
PySimpleGUI 2022-09-14T12:51:16Z
Simple "Can Button" Demo Program Added
Hadn't heard the term Can Button, or maybe it's Button Can.... They look really interesting and since they're trivial to incorporate into a PySimpleGUI program, I made a Demo Program from them
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Button_Can_Button_Images.py
and added an eCookbook entry for it.
https://pysimplegui.trinket.io/demo-programs#/custom-elements-buttons-radio-buttons-etc/custom-can-buttons
I would like to hire a graphic designer a little further down the road so that a large selection of images like these are available to PySimpleGUI users. In the meantime, we'll live with a few demo programs like this one and the toggle button.
Recipe Coming on Making Your Own...
It's not difficult for you to make your own using the psgresizer
utility. It will encode any image into a PNG encoded in Base64, and places the results on your clipboard so that you can then paste the result into your code. I've added to the list of new Recipes to add, instructions on how to add custom buttons using this utility and this kind of technique.
The whole process for me this morning was under 10 minutes from seeing the buttons to getting a couple turned into a Demo Program.
PySimpleGUI 2022-09-14T17:54:06Z
Documentation Problem Fixed!
There have been 2 problems with the docs recently. One has the header was cutting off the top of the pages. The other was that the table of contents stopped scrolling.
Both of those have now been fixed!
There are also 3 tabs that are screenshots. One of the screenshots tabs of the Demo Programs. Two others are user screenshots.
If you have problems still, particularly on Chrome, please try clearing your browser's cache.
Here's the view of one of the user screenshots tab
PySimpleGUI 2022-09-16T14:31:34Z
"CAN" Buttons....
One thing I've become really good at the past few years is saying, "Wow, I was wrong about that!". It's particularly helpful when I'm simply uneducated, or made a mistake, .... actually, I guess it doesn't matter why. The more important thing for me is to correct the information. I don't want to provide bad information to someone so that they TOO look , uhm, not bright...
I wasn't paying attention to the source of these buttons. They were physical buttons that I used in the example. They are called "CAN" Buttons because they work on a CAN Bus!
I'm not sure what the "Web" or what the Graph Designers call multi-state buttons with a glowing ring indicator. Whatever they call them, that's what these are.
Graphic Design Assets Coming in the Future
A little down the road, I'm going to contract out some custom buttons for users to use royalty-free. Same with meters, gauges, and some other custom controls that I've been thinking about.
The past few weeks I've been using these meters to show my CPU and Memory Usage:
They're a fun departure from my normal desktop-widget that show CPU/RAM Usage
Trivial to Integrate
The best thing about these types of graphic elements is that they're trivial to add to PySimpleGUI code and thus to a user's application. It takes 0 additional lines of code to use a beautifully drawn fancy button image instead of a default tkinter button. This is one of the fundamental benefits of PySimpleGUI, trivially customizing.
Hopefully, you learned 2 new things today.... 1. these are not "CAN Buttons" and 2. What a CAN bus is
PySimpleGUI 2022-09-20T22:03:29Z
psgdemos
1.12.1 Released
Over the weekend a new version of psgdemos
was released to PyPI. It fixed a bug that was happening if the editor specified in the Demo Browser had a space in the name. Setting the editor in the PySimpleGUI Global Settings doesn't have the error.
sg.main
Test Harness - Python Executable Added
A new line was added to the data at the top of the window. It shows the location of the Python interpreter that's running.
One of the reasons behind this need has been my use of pypy
lately. Getting the Python version is no longer enough to know the full extent of the environment... hmm... that reminds me that it should be added to the get_versions
data that's returned.
Knowing that Python 3.8 is running is no longer enough. Now we'll be able to tell if it's a python.org 3.8 or a pypy 3.8 or maybe your own 3.8.
psgpsg
Package Added To PyPI
A simple new PyPI release was posted. Most of you won't be interested but some may. I run both pip installed and local versions of PySimpleGUI. I have a PySimpleGUI.py file on my PYTHON_PATH for example.
Normally, you can run psgmain
to get the sg.main
test harness to run, but if you have a PySimpleGUI.py file that doesn't match with psgmain, then nothing will happen. You won't get a window. The solution was to release a super-simple utility psgpsg
to PyPI and instead of running psgmain
, run psgpsg
. This utility is capable of running using a local copy of PySimpleGUI.py or a pip installed one.
I'm maybe the only person that runs a PySimpleGUI environment like this, so it may not apply to anyone else.
Documentation Mode
I'm still working on the docs as my primary task, but trying to stop into the GitHub issues to work on problems. Incredibly thankful that our wizard...
Jason, is here providing the best support I've ever seen on a project. It's awesome to see PySimpleGUI users also saying what a great job he's done.
PySimpleGUI 2022-09-20T22:32:51Z
TeachMePython.com Launched!
A long-time friend of the project, Mike Driscoll, has launched a new Python instructional website, TeachMePython.com. I think there is only 1 of Mike's Python books that I don't own and I like 100% of the ones that I do. Mike's been incredibly supportive over the years and has been personally there for me anytime I've asked for help.
I have no hesitation at all in recommending his site because I know that he's going to do the best he can and has oodles of integrity. I signed up right away. Really hope PySimpleGUI users will go take a look and see if there's a fit. He's been a vocal supporter of PySimpleGUI and posted numerous tutorials over the years and featured PySimpleGUI in the Pillow book he wrote (an excellent book!! It's featured in the Pillow lesson in the PySimpleGUI Udemy course).
Anyway, go check out TeachMePython.com!
PySimpleGUI 2022-09-27T15:43:54Z
Menu
, ButtonMenu
and MenubarCustom
- "active" highlighting completed
These elements did not quite have the theme applied fully. The version checked into GitHub 4.60.3.100 adds the highlighting color to these 3 elements.
The "active" item is the one under the mouse. Here is a GIF that shows the difference for the MenubarCustom
element. The Menu element's changes were limited to the menu items being highlighted as the OS does not support changing the colors of the menubar itself for the OS-provided one. On the left is the one prior to the change.
PySimpleGUI 2022-10-04T22:14:57Z
Down For Several Days....
Hello everyone... I hope everyone is safe following the storm. I was without power for 48 hours over the weekend. I was fortunate to not have suffered serious property damage, only minor problems and a 48 hour power outage that has caused a rolling set of problems. I'm really sorry for not being present and responsive. Was excited to see some screenshots for example, but hasn't commented. The Udemy coupon also expired which is a priority to get updated ASAP.
Thank you to everyone for being so patient and of course.... of course... a massive thank you is owed to our PySimpleGUI Wizard, Jason.
Thank you for the kind words
While my social media accounts are generally no longer active, I do a search now and again to see how things are going with users. The comments said about the PySimpleGUI project have been really kind and supportive. It's really touching to read that we're viewed as being responsive and are working hard for our users. The PySimpleGUI users have been unbelievable in how positive, grateful, thankful, and encouraging they are.
I've worked with and managed a lot of teams throughout my career. The PySimpleGUI team has been the most positive group of people I've ever worked with. It's not that I worked with negative people in the past, but rather every individual on this team has said so many positive things and acted in positive ways. Every week it's been like this. Maybe this is normal now, but I don't think so. I've been so fortunate to have crossed paths with truly remarkable individuals in this project. Many of them are very young and while I too started coding at a very early age, I lacked the kind of maturity and wisdom these kids demonstrate. It's very inspiring.... very inspiring.
PySimpleGUI 2022-10-10T17:55:09Z
Why Your Help is Needed With Other Projects
I think that I've perhaps not done a good job of explaining why your help is needed when bugs are filed with other projects.
The Announcements Issue over the past months has numerous posts about a specific Mac problem or maybe you've been following the Mac problem specifically that showed up with the 12.3 MacOS release.
It's not just your problem & the challenges are numerous
The first thing to understand with any issue filed is that you are likely not the only person impacted by the problem and will be impacted by the solution. This is true for all things PySimpleGUI regardless of where the root cause of a problem may lie.
Challenge 1 - Get users running ASAP
The challenge is to satisfy users immediately impacted as well as those that may be impacted in the future. It's a challenge that can be frustrating for a number of reasons. While individuals have their interests in mind and are eager to get their problems solved, the PySimpleGUI project has this much bigger picture that is always present. It's enjoyable working on complex problems so I don't mind, clearly, or I wouldn't be running this project.
Challenge 2 - Find the Root Cause
Oh what fun this one is
and oh how frustrating.
This is a very important step, particularly if you plan on working on your project long term. If you don't care about tomorrow, and your code runs, this step may be of zero interest to you. Because the first decade of my career was in fault-tolerant, "five nines" systems that had to stay up, it was drilled into me at a very early age to spend the time and significant energy to get to a root cause. I took it seriously and still do. It bugs me to have a bug that I don't know why it's happening.
Challenge 3 - Get a long-term fix in place
Regardless of finding a root cause, a long-term fix needs to get deployed. This is crammed full of variables that need to be accounted for... the install base, numerous operating systems, Python versions spanning 3.4 through 3.11, tkinter or other GUI framework versions past/present/future, etc.
Challenge 4 - Getting help from users that are "operational"
Some people want a fix to their problem and then go on working/living their life.... perhaps we all do. Maybe think of software development in terms of teams. Team Linux, Team Mac, Team Windows. "There's no I in team", as they say, to which I would add... "but there is in Linux!" Sorry... bad humor I'm good at.
I've got some basic rules that are always present in my mind....
-
Impact the install base as little as possible
-
Be backward compatible
-
Work deliberately, not randomly
An Architecture Diagram For Reference
This diagrams shouldn't be too difficult to understand. Your app runs on top of Python with PySimpleGUI being between you and tkinter (although you can go around/through PySimpleGUI to get right at tkinter too... and PySimpleGUI supplies some APIs to OS calls)
Finally Getting to the Point....
With all that background information fresh, I would like to present a specific scenario, one that in fact mirrors the Mac problem that's been challenging.
Your application, running on PySimpleGUI version 4.30.0 (released in Oct 2020) has been running great. You upgraded your Mac and now it doesn't work correctly.
Tkinter + OS Problem
The problem is traced down to the tkinter/Mac level and found to be a legit problem that happens without PySimpleGUI being used.
There are 3 pieces of software your app depends on:
-
PySimpleGUI
-
Python/Tkinter
-
Operating system
In the world of software development, you don't want to change/upgrade unless necessary. It's costly, increases the likelihood of problems, etc. For some companies, it means their QA Department needs to "recertify" a release/component, a potentially very costly process.
Why PySimpleGUI Changes Are NOT The Answer To Other Components' Bugs
If PySimpleGUI "fixes" this problem by working around the lower level issue, that has 2 bad side effects:
-
The actual bug/problem is not fixed
-
ALL users that upgrade to that OS/tkinter version must also upgrade to a new PySimpleGUI
These 2 reasons are why help has been requested by the PySimpleGUI Mac users. Help is needed to get the actual problems fixed so that other users, your fellow OS Teammates, aren't impacted.
This has been the danger in delivering workarounds to users. It gets users up and running quicker, but at a potentially large cost, one that requires all other users to upgrade their copy of PySimpleGUI, and the actual bug continues to go unaddressed.
An extreme action would be to not provide any workaround and send users to the project with the bug. I can't imagine doing that, but it's one path that could be taken.
How You Can Help - Speak Up
The help that's needed is for users to tell the group that has the bug in their code that you are impacted. All users of that OS are impacted. I, as a single individual, have ONE voice. It's easy to ignore 1 person saying there's a problem. It's a lot more difficult if there are 10, 20, 50.
I'm not sure of any way of communicating the severity of a problem, that many people are impacted, than by having those individuals chime in, say something, lend their voice.
Where are we?
The current status of this problem is that movement has stopped. Any Mac user that upgrades to 12.3 or later will see windows intermittently.... unless they upgrade to the emergency release of PySimpleGUI that was posted to PyPI with a workaround. It's a very unsatisfying resolution, but it's where we are.
I'm backing off spending so much time and resources on this issue. The workaround isn't ideal, but it seems to make Mac users happy enough so I'm going to consider it done from a PySimpleGUI standpoint.
Ideally, enough pressure would be put on the tkinter team by our Mac users to get some movement on getting a fix, but that's out of my control. I'm not going to remove the workaround to force users to go get help from that team.
Hopefully, this is a general enough description that you'll get an understanding that there are subtleties and complexities to these systems that you may not have considered but now understand better.
PySimpleGUI 2022-10-22T19:50:23Z
Your User Screenshots..... Now on https://www.PySimpleGUI.org
When you post a screenshot in Issue #10 it will automatically be added to the PySimpleGUI documentation under 2 different tabs. One tab has the full text of the posts. The other tab has only the images.
This has been a feature that @Chr0nicT has been diligently working on for a long time, while working on a lot of other PySimpleGUI issues and upcoming features. Every week I'm impressed with the solutions the PySimpleGUI team is coming up with. Jason continues to be the world's best support engineer.... I've seen none better.... And @Chr0nicT has been our multi-tool/multi-language MacGyver.
It's the users of PySimpleGUI that are the super-star application builders and it's important that new users see the possibilities.
The Demo Programs and PySimpleGUI Utilities don't convey the wide range of applications and styles possible. Your application screenshots do communicate those possibilities so keep them coming! I'm impressed by every image I see. Nothing is too simple/easy/minor to share.
We're still working hard....
While fixes and enhancements are being added on GitHub, I know the pace of those is slower than in the past. While I took Friday off, I'm still working every day on this project. The new documentation is looking good and I'm sure everyone's going to like it. The eCookbook is part of the main documentation for example.
And as mentioned in the issue asking about a call reference for the Web port, all 4 ports of PySimpleGUI have an SDK reference in the new docs. This has required adding docstrings to all of the ports and is a time-consuming operation.
Thank You for the Thank You's!
Thank you for all the kind words and encouragement, publicly and privately! They are all seen and I pass them around as well. They have an impact greater than you know. They fuel the project. It's been a difficult year keeping the project alive and afloat. Having your support has meant so much.
All Python developers need your support, not just me, so show love to others too.
PySimpleGUI 2022-10-31T18:00:14Z
Exceptions Made Simple PySimpleGUI-Style
You may have already encountered the PySimpleGUI Error Popup. One of the most common errors is a bad key. Here's an example:
I use these error popups in my personal programs as I can immediately edit the file with the problem by clicking the Take me to error
button. You can use them too of course. The function to call is popup_error_with_traceback
.
The new version of PySimpleGUI on GitHub, version 4.60.4.110, has a new feature to help you with the details of your exception.
If you include the Exception information as one of the items to display, then the window will contain information about the exception that occurred.
Here's an example that has a test for an exception in the event loop:
import PySimpleGUI as sg
layout = [ [sg.Text('My Window', k='-TEXT-')],
[sg.Text('Input an int:'), sg.Input(key='-IN-')],
[sg.Text(size=(12,1), key='-OUT-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Go':
try:
i = int(values['-IN-'])
window['-OUT-'].update(i+1)
except Exception as e:
sg.popup_error_with_traceback('Error on int input', 'Something went wrong', e)
window.close()
The window is shown when there's an error in the conversion to int. The Take me to error
button, as you can see in the image, takes me to the line of code with the popup that reported the error. Because I passed in the variable e
, which contains the information about the exception, the window also displays the specifics of the error in the format of the filename, line number, and the message associated with the error.
In this example, the exception happened on line 17. The error message associated with that exception says invalid literal for int() with base 10: 'ABC'
Hopefully this will make finding errors in your program a bit easier, and a lot more pleasant when they do occur.
PySimpleGUI 2022-11-02T11:00:11Z
Reminder - User Screenshots Gallery Now Open....
A quick reminder/suggestion that you post a screenshot in Issue #10.
It's always been open and available for you to post a screenshot. Now they have much greater visibility because they are also being put into the main PySimpleGUI documentation, with full text and only the images! A LOT of people are looking at these screenshots. They are the best way of showing the world what's possible with PySimpleGUI.
Your creations, big and small, are unique, different than the stuff I make, diverse, and honestly coming from actual users (making them "authentic"), and.... you'll perhaps get a sense of pride in what you've accomplished by sharing them.
The Emergent Complexity Phenomena
In the new docs, I spent a bit of time discussing the impact of seeing your screenshots. From them, it's obvious that something beautiful happens when making the creation of GUIs open to everyone by providing simple-to-assemble windows. Complexity emerges. Knowing this happens and explaining this happens are not the same as showing this happens. '
Seeing is believing
The Demo Programs are, by design, plain, simple, short, and meant to instruct in using PySimpleGUI. As a result, they appear simple. The conclusion/opinion by some programmers that have not used PySimpleGUI is that "PySimpleGUI is only good for simple applications". Your screenshots dispel that myth, quickly and easily.
Thank You for the Motivation
These applications you're developing and sharing truly are motivating. They're inspirational. They're also educational as you do things I've never thought of doing. They're truly mindblowing to see.
PySimpleGUI 2022-11-10T10:58:16Z
Support
As mentioned in the current documentation, and the upcoming new docs.,. using StackOverflow and Google to seek information about PySimpleGUI is not suggested and has the likely hood of producing results that are lower in quantity, once correct but no longer, or are flat-out wrong.
Google and SO provide you with the most popular answer, not the most correct answer. There is no human being involved in helping you find the best answer.
Worst yet, because I don't have the bandwidth to support both locations, problems reported there never make it to the project. Enhancements the project could benefit from simply won't happen because I don't know they would be helpful.
SO Answers
PySimpleGUI evolves... the answers there do not. When possible, I edit the old answers I see of mine that are incorrect or done a better way now.
I was informed via email of one this week when a comment seemed to have a designed shaming or embarrassing outcome. I think that pretty much sent the message I needed to see... the reminder that I've no business providing support on SO. So, I'll stop, again.
The Issue Form...
My best is all I can do....And it's what I'll keep doing here. Please open an issue if you have a question or problem. We're here to help. There is a GUI form found by typing psgissue
from the command line. I've tried to balance getting the information required to perform support with the time required to gather that information.
There's a certain amount of required information. Negotiation back and forth to get that information was inefficient (what's your version? 4.60.4. And OS?) These used to be the conversations had before working on the problem could begin. Contrary to the voice that's perhaps in your head that the form is there to piss you off, it isn't. If you can't take a few moments to fill in the form, then it's assumed your desire for a solid answer is less than that investment.
We're Working Hard
The project may appear to some that it's not as active. It is quite active. I've got more people working with me now than ever before. It's simply not done so you're not seeing it. I'm still as dedicated as ever. As I've said a number of times in the recent posts, this year has been extremely challenging to keep the project afloat. The financial data is there for anyone caring to do the math.
Thank you for the "Thank yous"
When logging and issue, 99% of the user say "thank you" when it's resolved. That alone has an impact, one that's biggest than you likely know.
Please Post Screenshots
Please keep posting screenshots in Issue #10. They're VERY motivating, not to just me and the team, but to the other PySimpleGUI user. They are part of the documentation now and thus quite visible. They demonstrate the universe of possibilities. It's literally impossible for me to make enough examples to communicate how vast this universe is, but you have the ability to help show the many creative solutions you've built.
All you need to do is copy a screenshot and paste it into the issue. There is even a built-in way to do this. You can use the built-in "Window Snapshot" feature to take a screenshot and drag-and-drop it the file into the issue.
I truly love seeing what you're making!
PySimpleGUI 2022-11-14T12:13:20Z
Image Zoom Added to Image, Button, ButtonMenu and Tab elements
You can now scale upwards in addition to downwards when using elements that have images associated with them.
subsample
has been the only method of affecting change to an image's size to date. With the addition of zoom
or image_zoom
you can scale upward as well as combine the two to achieve fractional scaling.
A Test Harness
This code shows in the layout how zoom is specified as well as in element's that provide the capability in their update
method. I do realize this is an ugly way to communicate these changes so my apologies.
import PySimpleGUI as sg
right_click_menu = ['Unused', ['Right', '!&Click', '&Menu', 'E&xit', 'Properties']]
layout = [ [sg.Text('Zoom Parameter Tests')],
[sg.Image(sg.EMOJI_BASE64_HAPPY_THUMBS_UP, key='-I1-')],
[sg.Image(sg.EMOJI_BASE64_HAPPY_THUMBS_UP, subsample=2, key='-I2-')],
[sg.Image(r'C:\Python\PycharmProjects\PSG\Logos\Logo 372x37250x50.png', zoom=2)],
[sg.Image(key='-I3-')],
[sg.ButtonMenu('', right_click_menu, image_source=sg.EMOJI_BASE64_FINGERS_CROSSED, key='-BMENU1-', text_color='red', disabled_text_color='green')],
[sg.ButtonMenu('', right_click_menu, image_source=sg.EMOJI_BASE64_FINGERS_CROSSED, image_subsample=2, key='-BMENU2-', text_color='red', disabled_text_color='green')],
[sg.ButtonMenu('', right_click_menu, image_source=r'C:\Python\PycharmProjects\PSG\Logos\Logo 372x37250x50.png', image_subsample=2, key='-BMENU3-', text_color='red', disabled_text_color='green')],
[sg.TabGroup([[
sg.Tab('1/2 size', [[sg.T('1/2 size')]], image_source=sg.EMOJI_BASE64_HAPPY_JOY, image_subsample=2),
sg.Tab('2/3 size', [[sg.T('2/3 size')]], image_source=sg.EMOJI_BASE64_HAPPY_JOY, image_subsample=3, image_zoom=2),
sg.Tab('Normal size', [[sg.T('Normal size')]], image_source=sg.EMOJI_BASE64_HAPPY_JOY),
sg.Tab('2X size', [[sg.T('2x size')]], image_source=sg.EMOJI_BASE64_HAPPY_JOY, image_zoom=2),
]])],
[sg.Button('Go', image_source=sg.EMOJI_BASE64_HEAD_EXPLODE, image_subsample=3, image_zoom=2), sg.Button('Exit')]]
window = sg.Window('Image Zoom Tests', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Go':
window['-I3-'].update(sg.EMOJI_BASE64_HAPPY_THUMBS_UP, zoom=4,)
window['Go'].update('', image_source=sg.EMOJI_BASE64_HEAD_EXPLODE, image_zoom=2)
window['-BMENU2-'].update(image_source=sg.EMOJI_BASE64_HEAD_EXPLODE, image_zoom=2)
window['-BMENU1-'].update(image_source=r'C:\Python\PycharmProjects\PSG\Logos\Logo 372x37250x50.png', image_zoom=2)
window.close()
This is how the code looks when executed:
https://user-images.githubusercontent.com/46163555/201656501-bc0a37df-f5dd-457e-8e9e-4f8738589158.mp4
Enjoy!
Hopefully this will help a few of you with scaling without needing to pull in the Pillow package. While crude, there's at least the ability to go in an upward direction now.
Looking forward to seeing what you make!
Don't forget to share your creations in the screenshots Issues #10.
PySimpleGUI 2022-11-18T22:01:24Z
New Demo - Demo_Multithreaded_Delegate_Appear_To_Make_PSG_Calls_From_Thread.py
Decided to go with the "more explicit" description in the filename for this demo. Wanted to make sure lots of keywords got hit.
This Demo Program provides code that allows you to a multi-threaded PySimpleGUI program that looks and feels like your threads are calling PySimpleGUI directly.
It wasn't until a question was asked about how to show windows from a thread that I realized no demo program or Cookbook Recipe exists for doing this specific operation. All of the multi-threaded Demo Programs assume you have a window for your application, and that some action you take will then start a thread, etc.
No Window, No Taskbar... Initially....
When you run this design pattern, the result is that nothing is shown on the taskbar or on the screen until your thread indicates it wants to show something. This was the missing use case.
Implementation Syntax
The way this demo is designed to work is that your code, running as a thread, communicates with the main-thread (that is controlling the GUI). The information passed to the main-thread is a lambda function. This allows you to write code that resembles directly calling PySimpleGUI.
make_delegate_call
This is the function that's part of the demo that communicates with the main-thread. I used the term "Delegate" to indicate that the main-thread is making PySimpleGUI calls on behalf of the thread. The thread is "delegating" the action of making the PySimpleGUI call.
This function takes only 1 parameter, a lambda expression. In this example, a call to popup_scrolled
is being made. The call to make_delegate_call
returns immediately. The request is placed in a queue that is part of PySimpleGUI itself.
Blocking
You'll want to be cautious in how you make your calls. It's OK to make a blocking call to a function like popup
. Just understand that doing so will cause other requests you have to wait until the blocking call completes.
Entire Windows
You're not limited to making calls like popup
using this design. You can create entire windows complete with an event loop. I recommend creating a function that does it all... make the layout, the Window, run the event loop... and then use the make_delegate_call
to call that function.
Screenshots Please!
Please keep posting screenshots in Issue #10 . Your screenshots are a popular destination in the documentation.
I hope you all have a safe and enjoyable weekend!
PySimpleGUI 2022-11-19T14:43:32Z
The Documentation Search is FIXED!
Our talented documentation wizard, @Snaiel has fixed the problem we've been having with searching the documentation at PySimpleGUI.org.
He's been quietly working away at the new documentation, which I'm 100% confident will stun everyone. We're working hard to get it complete and rolled out. It's worth the wait... definitely worth it.
NOTE - on Chrome, you may need to reset your cache for the PySimpleGUI.org site
Sneak Peek
Here's a little peek at the new documentation and how it's been heavily paginated and uses collapsible table of contents entries. Gone is the monolithic main page... honest....
Here you can see that all 4 of the ports of PySimpleGUI are represented as a call reference. This screenshot is subject to change, so not promising anything will be exactly as shown, but do want to share how exciting and different it all is.
PySimpleGUI 2022-11-21T19:42:11Z
Udemy Sale!
I didn't know that the coupon code currently shown in the docs, readme, code, etc, has expired. Udemy doesn't inform me and somehow I missed seeing the entry on my calendar.
For the next 5 days, you can use this coupon to get the course for $9.99
https://www.udemy.com/course/pysimplegui/?couponCode=EAC88BA243480BDEB9FE
This coupon is good for $13.99 and lasts for the next 30 days.
https://www.udemy.com/course/pysimplegui/?couponCode=09B234B00A7E89CC8C1F
Udemy has some odd restrictions on how long a coupon can be used and what prices are available. I can't create, for example, a $9.99 coupon that lasts for 30 days. The lowest I can use for a 30 day coupon is $13.99 so that's what I've been using.
If you've been following this project for a while, you'll know that last Christmas, when the course was launched and for several months after, the cost of the course was $100.
The lowest price...
Most of the PySimpleGUI users are not in the USA and many are from areas of the world where income is such that a $100 course isn't affordable. So I decided to drop the price in May.
The number of enrollees hasn't risen to provide the same level of income as the $100 price was bringing in, but I decided to keep the lower price. While Udemy helps with income, it is far from enough to cover the basic costs of the project. It was a solid attempt to create a stable funding situation, but a failed one. $13 or $100... neither has a significant impact on the project.
Holidays are coming...
I hope everyone has a safe and joy-filled holiday season!
PySimpleGUI 2022-12-13T18:27:12Z
3 Million Installs....
We've hit a milestone of sorts with PySimpleGUI. Last week the total number of installs, as reported by PyPI, pass the 3 million mark for the tkinter port. This is one of the reports that I run on occasion:
https://pepy.tech/project/pysimplegui
I generally don't draw attention to analytics such as this. It feels like bragging to me, something that I don't feel comfortable doing. I've privately watched and used analytics to help me stay engaged and working hard on the project. It took over 4 years to get to 3 million. At the current rate of installs, another million will be added in under 6 months.
PySimpleGUI is What I Do
As mentioned in the readme, this project and these products, are what I've dedicated myself to doing. It's what I do every day of the week. I believe in PySimpleGUI and have been making the investment to keep building, maintaining, and improving it. Also in the readme is the discussion on funding. Like bragging about the number of installs, asking for financial help is not a particularly pleasant activity. I do it, but infrequently.
2021
2021 (and a chunk of 2020) was the "Year of Udemy". A lot of time and expense went into creating the 61-lesson "Best Seller" course on PySimpleGUI, complete with interactive exercises. I'm grateful to everyone that's taken the course. I'm grateful to everyone that's provided financial and simply kind words. I'm very fortunate to have that help. The impact it's had financially has been underwhelming. It will take some time for the course to pay for the cost of making it. Basic hint - it's under 4 digits per month of income.
2022
2022 has been a "Year of Getting Professional". While not yet released, the upcoming changes are focused on professionalizing PySimpleGUI. Reworking the documentation top to bottom, getting all of the ports to an acceptable level of built-in documentation (docstrings), and adding additional security to help users know when they're running an "official version" of PySimpleGUI code. There are more features that I'll make an announcement about when we're closer to releasing the code.
2023
2023 is going to be the "Make or Break" year. I ultimately need to determine if the project is going to continue. To date, it's nowhere near sustainable. The income doesn't cover the cost of the project, meaning that it's not only unable to allow me to pay for my cost of living, but I continue to rack up debt, borrowing money, to keep the project functional.
This isn't new information if you've followed the over 1,200 announcements I've made since Sept 2018. The data is available should you wish to look at the GitHub Sponsorships and do the simple math required to calculate income from Udemy. It would be great for the project to keep going. I'm hopeful, but more than hope's required to keep the project going.
I'm Sorry for the delays....
I know that the pace has slowed in terms of the features you see being released. I'm doing the best I can with what I've got. I try to be OK with that and hope that everyone else is as well.
Thank you to the PySimpleGUI team and supporters!
@jason990420 is here providing support and ideas for how to keep improving our code. His contributions have been truly unbelievable. We've got over 2,400 closed bugs thanks to Jason.
@Chr0nicT and @Snaiel are delightful to work with and have made enormous contributions to the project (many of them you've not yet seen.... so just wait... it gets even better!)
These aren't the only people helping make this project the success it's been. It's not a solo effort and never has been. I also rely heavily on my friends and they've not let me down when I've asked for help, or I've shown I need help. I took the "surround yourself with people smarter than yourself" advice literally and seriously.
Happy Holiday
It's that season and I hope that everyone has a safe and enjoyable holiday.
PySimpleGUI 2022-12-19T13:10:07Z
ChatGPT
The ChatGPT release has created a bit of a stir, particularly in generating code. It may be helpful to share this information to stop potential uses and abuses.
My Opinion
My usual disclaimer - computer science is filled with subjective answers.... opinions. I often state my opinion and try to make sure that it's understood when I'm doing this.
"Artificial Intelligence" is such a misleading term. It has the word "Intelligence" in it and as Roger Penrose has said (paraphrasing) "Intelligence cannot be computed". It does have the "Artificial" part right. What AI does is artificial. It's a clever fake and this is the beauty and the danger.
I'll be impressed with AI's programming capabilities when a program creates something like PySimpleGUI or it fixes bugs posted here, like the Apple invisible window problem. Until then, it's another tool, not a miracle.
Stack Overflow's Policy
Shortly after posts of "code generated by ChatGPT" started to be posted, one of the PySimpleGUI team members sent me the StackOverflow policy:
https://stackoverflow.com/help/gpt-policy
The last line of the policy sums up their overall feeling about someone posting GPT created code:
Moderators are empowered (at their discretion) to issue immediate suspensions of up to 30 days to users who are copying and pasting GPT content onto the site, with or without prior notice or warning.
My Tests
My summary/takeaway...
AI algorithms are skilled at fooling human beings.
One thing I noticed in the "code" it produced is that it used old calling conventions.
window = sg.Window('Reddit submissions').layout(layout)
# Infinite loop that checks for input events
while True:
# Read the input events
event, values = window.Read()
These are older constructs that you'll not see in the documentation and demo programs. So right away, you're being led astray and into legacy ways of coding that may not work any longer.
The other thing I noticed, and this I believe is the main argument that StackOverslow was making is that the code "looks legit". It looks like code that should run.... and... well, sometimes it got lucky and did. Other times, it didn't.
Just Say No
Simply put, GPT is not designed to write code and doesn't write code. It guesses at the task and sometimes, like people, it guesses right. The Chatbot itself will tell you that it can't write code if you ask in the right/wrong way.
AI Inside
OK, so I've said some not-so-flattering things about AI, but I do want to acknowledge that it IS a powerful technology. The PySimpleGUI Designer (called Sketch-It) has not yet been released and I hope to release it next year after all these current changes are released. It uses AI algorithms to generate code, but the part that does the code generation is not the part that uses AI algorithms. That part of the code was written by human beings. The design it uses may be possible without AI, but it would be much more difficult.
Like all technologies, anything can be made to sound bigger than it is. Edge cases can be found that make something look really amazing (just look at PySimpleGUI 1.0 if you want an example... it worked great for simple GUIs, but lacked the more complicated elements like Column so it's use was limited).
Stay in School... Be a Programmer
If you're learning to code, your future job is not at risk anytime soon due to AI. Just as millions of Uber Drivers have not been replaced by self-driving cars, as predicted years ago, programmers will not be replaced by AI code in the mid-term-future. I'm doubting it'll happen in my lifetime... but, I'm old, so factor that in. Until then, I'm going to keep having the time of my life writing code and leave the worrying to the youngsters.
Want to beat AI? Study and write code...
It'll keep you busy building things that help people and distracted from the machines taking over (the task of fooling people).
PySimpleGUI 2022-12-25T16:59:29Z
🎵 "Christmas Timer Is Here" 🎵
I hope everyone that celebrates Christmas has a very Merry Christmas today. Everyone else Happy [Holiday of your Choice]!
I was feeling nostalgic for Charlie Brown's Christmas and the beautifully written Vince Guaraldi song (that I used to know how to play on the piano but have forgotten) "Christmas Time is Here"
I recently released a Demo Program this past week that created and managed timers. I had some time on my hands the past few days as there was a storm and I lost power for a day. I had the bright idea of pulling this timer functionality into PySimpleGUI itself.
Timer Versus Timeout
Many programs use the timeout
parameter of the window.read
call to get a "heartbeat" type of design pattern. The way the timeouts on reads are designed, it's not a very reliable way to get a regularly spaced timer event. The reason for this is that window.read
will return as soon as it gets an event and it cancels the timeout when an event occurs. It was designed to always give you an event within a certain amount of time.
The new timer feature provides a regularly spaced timer event regardless of other events that happen. The Demo Program posted a couple of days ago provides a regular set of timer events, but it requires a fair amount of code, including the use of threads. You'll find the code to that demo here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Timer_Periodic.py
window.timer_start
and window.timer_stop
Use the new These are your new window.timer_start
methods to start a single timer or a periodic timer. The timer will return an event sg.EVENT_TIMER
. You can also specify your own key to use for the event. In the values dictionary (values[event]
), you'll find a timer_id that tells you which timer caused the event. This timer_id is returned from timer_start
.
If you want to stop a timer, call window.timer_stop
with the timer_id.
If you close a Window, then all timers for that Window will automatically be stopped.
Simple Format of Call
The simple format of the start timer call takes 1 parameter, the timer value in milliseconds. To get an event once a second call:
If you only want a single timer event, then you'll set the repeating
parameter to False
. This call generates a timer event after 10 seconds:
New Demo_Window_Timer
You'll find this code in the new demo program that was just posted along with the changes for this feature. It shows how to both start and stop timers.
import PySimpleGUI as sg
"""
Demo Program - Window Timers
Uses the PySimpleGUI Window Timers to generate single or periodic timer events.
Requires version 4.60.4.131 or greater of PySimpleGUI.
Copyright 2022 PySimpleGUI
"""
def main():
layout = [ [sg.Text('Demonatrataion of Window Timers', font='_ 15')],
[sg.T('Timer duration in ms:'), sg.Input(1000, key='-DURATION-', s=4), sg.Checkbox('Repeats', True, key='-REPEATS-'), sg.Button('Start')],
[sg.T('Timer ID to stop:'), sg.Input(key='-STOP-', s=4), sg.Button('Stop')],
[sg.Output(size=(90, 10))],
[sg.Button('Does nothing'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Start':
try:
duration = int(values['-DURATION-'])
except:
continue
window.timer_start(duration, repeating=values['-REPEATS-'])
if event == 'Stop':
try:
id = int(values['-STOP-'])
except:
continue
window.timer_stop(id)
window.close()
if __name__ == '__main__':
main()
Enjoy the Holiday!
If you're getting a break from work, enjoy the time away from the office! It's a season for rest and recovery (and fixing broken water pipes due to the cold weather in my case).
I hope everyone has a safe and happy holiday!
PySimpleGUI 2022-12-30T09:37:38Z
New Year, New PySimpleGUI Updates Coming...
There has been a tremendous amount of work going on that hasn't been released. I've been talking about the documentation update for many months. There's no doubt that everyone is going to love the new docs.
I thought sharing a screenshot of the new docs would maybe be helpful to show the extent of the rework and rewriting happening.
Not only has the main documentation been extensively reworked and reorganized, but it's highly interactive. The eCookbook is now part of the documentation itself, and as you can see in the sample screenshot, there are interactive Trinkets embedded within the documentation. They're not limited to the eCookbook.
The navigation bar on the left has gone through a complete transformation. Gone is the one long massive table of contents. Instead, there are collapsable sections. There are so many improvements that it would take me pages of describing them so I'll just show you this screenshot and let you see for yourself soon when all this is finally relesaed.
Thanks for the Patience
Thank you all for being incredibly patient while this work is happening. The bug fixes and enhancement implementations have slowed in their pace, but haven't stopped entirely. I try to keep a mix of activities.
It's a Teamwork Project
Jason has been such a huge piece of the overall PySimpleGUI experience. BTW, if you've not discovered the Easter Egg, then using your IDE's code completion while typing in an EMOJI name, you'll find he's represented in the code as the Wizard he is. He's been the support for PySimpleGUI for a long time and has made it possible for me to concentrate on leading the team and making these new changes that hopefully will propel PySimpleGUI into a whole new phase. I owe a huge HUGE thank you for his contributions and incredible endurance as he is here, helping everyone, every day.
Behind the scenes, another team member (also an easter egg), Tanay has been the project's Jedi, able to take on anything and everything I've thrown at him.
Thank You for the "Thank You's"
Maybe it's silly, but I really appreciate the kindness and gratitude I see so frequently here. Many of you thank Jason for his help. I get a warm fuzzy feeling reading those. The overall experience has truly been "the dream come true I didn't know I had" and it's because of the users of PySimpleGUI that this dream is happening. Thank you for making it a special experience.
I'm quite hopeful that 2023 will be the year PySimpleGUI will be successful in becoming a thriving project able to continue into the future. With your help, it will be. Thank you for the ride of a lifetime....
PySimpleGUI 2023-01-14T12:42:26Z
Why This Topic?
I don't want this place/space to be where I state a bunch of my personal opinions. That's not the point. This is all about PySimpleGUI.
I'm seeing PySimpleGUI used as an example of where it "works". But most importantly, it's the PySimpleGUI project's goals that have me concerned. Fun and user success are the goals. Having generated code leading users down a path that's incorrect may lead to frustration and failure. Both are not fun and not successful.
Chat Fails
Cherry-picking examples of Chat AI solutions for programs has been happening quite a lot I think. It's just as easy to cherry-pick failures. Even though there are warnings that are often shown that were written by the developers of GPT that it is not appropriate for generating code, lots of people are using it for this. That's fine... until it starts to be posted and others don't understand it's a terrible idea.
Here's a cherry-picked failure I got while generating text, something it is designed to do really well.
The Gartner Hype Cycle
I hadn't heard of this until recently. It's interesting for a variety of reasons. One is to explain those "this will change everything" events that don't change everything. The other is for entrepreneurs looking to get funding for a new idea in a "hot space". Hit pitching your idea at that first peak and you may get better funding.
There Are Vaid Uses
These things are tools and powerful ones. But like power tools, they need to be used with care and appropriately.
For PySimpleGUI programs, use the other AI, Actual Intelligence, to learn and produce code.
PySimpleGUI 2023-02-06T16:50:37Z
GitHub Version Number Changed To 4.61.0.xxx
I apologize for the confusing way I've been managing the PySimpleGUI version number for the version on GitHub. I should have bumped the version number higher or added yet another digit to the version that was released to PyPI.
PyPI has version 4.60.4 at the moment.
By changing the GitHub version to 4.61.0.xxx it's more clear that 4.60.4 does not contain the changes that are in the version that's posted to GitHub.
A large number of changes have been accumulating because they are part of a much larger release that's coming as part of the documentation rewrite. All of the PySimpleGUI ports are being upgraded. The other 3 ports have docstrings added, which not only provide documentation while writing code, they are also used to generate an SDK call reference for each port:
New Demo Program
Yesterday a new Demo Program was released that saves and loads Input elements automatically. It uses a dictionary to both set the key and the default value. It enables elements to be defined in a way that utilizes the settings file without cluttering up the layout.
The trick is to use a helper function make_key
to create both the key
parameter and the default_value
parameter
Because PySimpleGUI automatically creates the User Settings JSON file for you based on your file's name, you can directly use the User Settings calls without first explicitly "opening" a settings file.
def make_key(key):
"""
Returns a dictionary that is used to pass parameters to an Input element.
Another approach could be to return an Input element. The downside to that approach is
the lack of parameters and associated docstrings when creating the layout.
:param key:
:return: Dict
"""
return {'default_text':sg.user_settings_get_entry(key, ''), 'key':key}
def main():
layout = [ [sg.Text('Automatically Load and Save Of Inputs', font='_ 15')],
[sg.Text('Input 1'), sg.Input(**make_key('-IN1-'))],
[sg.Text('Input 2'), sg.Input(**make_key('-IN2-'), background_color='green')],
[sg.Text('Input 3'), sg.Input(**make_key('-IN3-'), text_color='blue')],
[sg.Text('Input 4'), sg.Input(**make_key('-IN4-'), size=5)],
[sg.Button('Exit (and save)', key='-EXIT SAVE-'), sg.Button('Exit without save')] ]
window = sg.Window('Save / Load Inputs Using User Settings API', layout)
PySimpleGUI 2023-02-07T16:47:35Z
New Custom Elements Dark Mode Demo Program
I saw a request from many years ago on another site asking about duplicating a GUI that was supplied. So I gave it a shot for part of it, just to see how much work it would be.
Using Paint.net to grab parts of the image of the sample window, I saved them to PNG files. I also grabbed the various colors and made a new theme.
Then I used the psgresizer utility to take each of those PNG files, turn them into BASE64 encoded strings which were then pasted into my source file. I didn't do a perfect job of making the assets pixel for pixel the correct size. It's a quick mockup.
It took me maybe 20 minutes to make the entire demo. It's far from perfect and you could say it's a little brute-forced since the event loop handles the logic for each custom element. But even all the logic for the custom elements is only 20 lines long. It's less than 100 lines of code, total, including all of the assets. Everything you see is in the file. With just a little bit of time and patience, a wide range of custom interfaces is possible.
PySimpleGUI 2023-02-16T13:57:18Z
New "Policy" added to the GitHub Issue instructions
My goal is not to "rain on anyone's parade"..
"Fun" and "your success" are important goals of the project. They are the goals of the project. The word "policy" doesn't sound like either of those, but in this case, it fits both of these goals.
Like StackOverflow, I've decided to make an explicit statement regarding ChatGPT-related Issue posts. In short, they're not allowed. The StackOverflow staff have done an excellent job of explaining why this is a good idea, at least for now.
https://meta.stackoverflow.com/questions/421831/temporary-policy-chatgpt-is-banned
I mean no disrespect nor am I trying to be mean or a jerk by making the statement - If you want someone else to write your code, hire a programmer.
Using a tool in an attempt to have code written for you is no different than hiring a programmer, a human being, for the same task. Either you're making an attempt to learn or you're "outsourcing it". At the moment the AI tools are nowhere near the quality level to produce useful code.
What I see happening or likely to happen:
-
Someone wants some code that does X
-
They type into a chatbot a question asking for code that does X
-
The chatbot provides code
-
The user runs it, sees it doesn't work, and then copies and pastes the output into an Issue and asks for help
This process takes less than 1 minute for a user and is very close to asking for free consulting. "Here's a piece of code that I don't understand, please make it run".
There is no shame in asking for help. That includes asking for a programmer to help write the initial program. It will likely work, AND the programmer can teach you how and why it works.
I've hired programmers from Fiverr. There are some good ones there and they're not expensive.
I'm as excited about this technology. I signed up for the Bing version and was approved for their GPTChat feature recently. My decisions on this have been based on my own personal experience using this technology. If I thought AI's were capable of being a positive addition to the programming process or the educational process, I would of course be very supportive. In my opinion, we're not there yet and all the hype around the chatbots is not helpful, especially for beginners.
So, for now, I've asked that no GPTChat code or generated information be posted. Is this a permanent restriction? I don't plan on it... as soon as the results are "good enough", I'll reassess.
PySimpleGUI 2023-02-20T11:27:46Z
ChatGTP Is Not "All Bad"
I would like to counter-balance the "policy" posted above and the warnings for a moment,. as this is clearly useful technology.
While the hype around AI is likely at a deafening roar level in the media (I dunno... not paying attention to the news), and I've made several announcements about not using it to generate code, there is value in using the tools and have a concrete example.
I signed up for Bing's version some time ago and was recently approved. It's a powerful tool and I'll take one of those, thank you! It's a great search engine, but I still urge caution. I'm betting you wouldn't want to only see the first Google search result. The same holds true with these chatbots. They're highly skilled at being wrong with great confidence. There's no magic here. The more you can be mindful that these tools are 100% mathematical probabilities and language patterns with zero "intelligence", the better results you'll achieve by augmenting the answers with additional searches and other tools.
When ChatBots Have Different Opinions...
Prior to Bing's version, I have been using a PySimpleGUI front-end to OpenAI's ChatGPT. I've been hacking/customizing one that you'll find in this awesome user's repo:
https://github.com/MaxSSD/OpenAI-GUI
I've not researched enough about the implementation to understand how easy or difficult it is to manipulate responses. From this test, I think it's clear that there's a fair amount of control the developers have.
When I asked the original ChatGPT about code-writing abilities:
Can ChatGPT be used to write software?
I receive the same warning I've been seeing from the start:
No, ChatGPT is not designed to write software. It is designed to generate natural language responses to user input.
This response led me to believe that the developers at OpenAI had specifically planted this information.
Bing's version of ChatGPT has a completely different answer:
ChatGPT is a large language model chatbot developed by OpenAI based on GPT-3.5. It can interact in conversational dialogue form and provide responses that can appear surprisingly human. It can also write essays, summarize documents and write software.
However, ChatGPT does not have the ability to search the internet for information and it may not know what’s true or accurate. d It also may not be able to write high-quality code that meets your specific needs or standards.
That answer is, uhm, different than the one I received yesterday, which did not have caution about the quality of the code.
I DO Use This Tool... For me... it's been a great starting point...
I've seen some people say that they find it useful for finding libraries. I've tested this use numerous times and it's worse than hit or miss. PySimpleGUI was missing from lists of Python libraries sometimes. Given the data on the Internet, the websites that list "the best libraries for XXX", this doesn't surprise me. There are decades of these articles out there. Maybe start there for libraries, but I wouldn't trust it too much for anything that you want to be "timely" or "up to date".
If you're working with a specific library, that is mature, then it's a great place to start.
PySimpleGUI is not what I call a "mature library". It's ever-evolving and the techniques programmers used and capabilities PySimpleGUI had in 2018 are very different from those today. tkinter's mature as is much of the Python standard library. Be an intelligent user of the tool.
An Example From Yesterday...
I was working on a problem with Tabs and I use one of the calls to get the "currently active tab". I normally would go to 4 or 5 different tkinter reference sites and look up the calls for the Notebook widget.
One thing I like about Bing is the references it provides so you understand where the data originated and can check the source website if needed or discount the information if it's an old post. In this case, I learned about the notebook.index
call. PySimpleGUI uses the notebook.select
call. It was the answer I needed and could go look up more info about the call.
"Give me a hint"
My overall approach to these tools is to not use them in an absolute manner. They don't have THE answer. They've got some answers.... or maybe they don't. The problem I see is that the replies, unlike if you asked a friend, are given with complete confidence. A friend would at least tell you, "I'm no expert, but I've used the library once... maybe look at ....". Or "I don't know". At least a friend doesn't fabricate names of libraries that don't exist, ChatGPT said I wrote several that don't exist... complete fabrications, but stated as fact.
Be careful out there!
And keep building! I'm loving seeing what people are creating.
There are some amazing applications being built! Thank you for sharing them.
PySimpleGUI 2023-03-10T12:10:29Z
Out until Sunday....
I have some personal matters to attend to. I'm taking a rare weekend, somewhat off. I'll be back on Sunday for a bit. The Udemy coupon is expiring so that will get fixed up then. I'll also be out a few days early next week.
New Demos, New Features
There have been new Demo Programs released since the last announcement and a number of new features added to the GitHub release as well. Take a look at the Demo Programs section if you want a sneak peek before I write anything else about them.
Upcoming Releases
The majority of my time is spent on upcoming releases and new documentation that I've been writing about for months. I apologize that it's taking so long and that my time is split between support here and the work you've not yet seen. It makes the project look a bit like it's languishing, but I assure you it is not.
GitHub Dumped PayPal
The Sponsorship situation is particularly bad for open source across the board on GitHub now that PayPal was dropped. This project's sustainability I'll write about in the future but thought it worth mentioning since all open-source projects are struggling financially.
Thank You For The Kind and Supportive Messages
I really appreciate the comments in the GitHub issues. It's been what keeps me working on this project every day. Your gratitude is the fuel for the project.
Back on Sunday....
PySimpleGUI 2023-03-13T10:04:08Z
Reminder - My attendance is spotty this week
As I mentioned in the comment above I will be unable to be fully present this week here with the project. Friday is the soonest I'll be back operating at 100%, or thereabouts.
Getting as much done this morning as I can before signing off. I'll try not to completely break things on the way out the door....
PySimpleGUI 2023-03-21T19:32:34Z
New Mike Driscoll Book - The Python Quiz Book!
I'm excited that I received the latest Mike Driscoll book in the mail today.
I like Mike's books on numerous levels. The style is right up my alley and stickers with his books, and now puzzles too?! FUN... and I like fun!
This one is really interesting and a little different than his others. I love it! It's clever. It can be a "I've got 3 minutes while waiting to pick up the kids so pull it out and give one of the quizzes a try" book.
The answers/hints to the quizzes include the location you will find the information in the Python documentation so you've got a place to go diving deeper if you want.
I start here with Mike's sites as he's got a lot going on now with his newer and growing TeachMePython.com site too:
https://www.blog.pythonlibrary.org/
Here's a page about the specific book:
https://www.blog.pythonlibrary.org/books/the-python-quiz-book/
Of anyone I've met in the Python community.... I've not met someone that's been in it for SOOO long, has written so much material and is also one of THE nicest persons I've encountered. His positive attitude permeates his books, his websites, and his Twitter account. So, for sure go check him out!
PySimpleGUI 2023-03-26T17:56:31Z
Slowed Pace.....
As I mentioned a couple of weeks ago, there have been several personal issues that are pulling me away from the project. It's frustrating, to say the least, as the year-long work on the upcoming release is nearing completion. Several medical complications have also significantly impacted my ability to work. I'm sorry for any impact that may have on your project and for the impact on the pace of PySimpleGUI overall. I'm doing all I can to recover and look forward to getting back to working hard as I can on the project.
PySimpleGUI 2023-04-01T10:53:47Z
Getting Back Up To Speed....
I'm feeling better and am able to work several hours a day again. @jason990420 has been a hero of this project, not just recently while I've been out, but for the past several years. He deserves a massive round of applause for his non-stop commitment to helping so many people here.
I'll be getting back into the issues this weekend. I'm still splitting time between the currently publicly released project and the much larger release on the way. We're getting closer by the day.
I again apologize for the absence. I love this project, the users, and have missed working on it.... so it's nice to finally be able to spend some focused time on it again! Hopefully will get to these new issues in the next 2 days.
Thank you everyone for the support. It means more than I can express in words.
PySimpleGUI 2023-04-02T16:31:04Z
Launcher Code For Chat....
I've written plenty on the AI Chat tools. Like everyone is learning, it's new territory to be explored. There are plenty of wonderful uses of this technology and I like Bing's implementation, particularly since I get the underlying "sources". While it can "generate code", I think the shorter snippet the better.
I like my own "Launchers" written in PySimpleGUI that I leave running. I've got 40 or so programs running at all times that monitor weather where my friends live, my CPU usage, 2 different launchers so I click 1 button and something kicks off like a "Build", etc.
I wanted a button that would open Edget to the BingChat so that I didn't have to open Edge, click a saved link, etc. This line of PySimpleGUI code is all that's needed to launch Edge to the Bing Chat page... at least on my system:
LED Weather Widget
One of the Demo Programs has stopped functioning... the long-term weather that's located here:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_LED_Clock_Weather.py
You'll find it at the bottom of this image:
I found that the reason that it is no longer working can be found here:
https://darksky.net/dev
which has the message at the top:
Will have to get this one converted at some point... but not super important at the moment... just an FYI...
PySimpleGUI 2023-04-21T13:07:17Z
New 3.0 Version of psgtest
Released to PyPI
A lot of testing is required for the new release that's coming soon. Testing and stability have been an important part of PySimpleGUI releases since the initial release in July 2018. This release needs to be thoroughly tested on all releases of Python, from 3.6 through 3.12.
To aid in the testing, the psgtest
utility was expanded to perform automated testing using multiple interpreters. The "Run Regression All Interpreters" button will test the selected programs on every interpreter you've configured in the settings.
A tip for using on your development machine
If you want to run stress tests while you continue to work on your computer then try making your test programs have no_titlebar=True
. I've found that this has much lower impact on Windows as an icon is not created on the taskbar for these windows. Explorer seems to be much happier and run much smoother without having to create and destroy icons on the taskbar.
https://user-images.githubusercontent.com/46163555/233640324-535d1787-23ad-4a8e-80a3-4a13c34eaa4c.mp4
PySimpleGUI 2023-05-01T13:33:16Z
PySimpleGUI 5.0 Almost Done
For the past year I've been talking about splitting my time between the current version of PySimpleGUI and a larger release of PySimpleGUI that includes a rewrite of the documentation. We're getting close to completing this release.
I would like to share a bit of what's coming in this release. More details are coming as the release nears completion.
I'm sure you can understand the amount of testing that's involved in a large release of PySimpleGUI. There are multiple OS's, versions of Python, versions of tkinter, support on devices like the Raspberry Pi and online environments like Trinket. The stability of PySimpleGUI has and remains an extremely important part of the PySimpleGUI user experience. I don't like crashes and I'm sure our users don't like them either.
Backward Compatible
Of course, 5.0 is backward compatible with previous releases of PySimpleGUI.
Documentation
The docs have all been rewritten. The interface is greatly improved with a much better and more manageable table of contents with sections that expand and collapse.
All 4 ports now have an SDK call reference, which also means all 4 ports have a full set of Docstrings so that your IDE understands the PySimpleGUI interfaces, providing you better code completion and error checking.
The eCookbook is now a part of the documentation (a new tab). Rather than visiting the Trinket site, you're able to run PySimpleGUI code directly from the PySimpleGUI documentation. Not only does the eCookbook take advantage of this new capability, so does the main documentation.
Enhanced Security
Several companies have voiced concern about security and being able to verify that PySimpleGUI code is "authentic".
There is a self-check in the code that authenticates the code is a valid "signed" release every time you import PySimpleGUI. There are web-based tools that enable you to be absolutely certain the code has not been tampered with since the self-check code, while made tamper-resistant, could in theory be modified.
Simplified Pip Installs and Upgrades
We're restructuring the GitHub repos for the PySimpleGUI project and have been using a new installation and upgrade architecture that has been working well during development. You'll be able to use the built-in "Upgrade From GitHub" feature as you do today, as well as using pip by itself in a more standard way.
There are also a number of utilities included in 5.0 that help with installing PySimpleGUI as well as other Python packages. A utility to help you with releasing your own code using this design will be released with 5.0.
Intelligent Upgrade Service
It's been a challenge to synchronize PySimpleGUI releases with OS and tkinter releases, particularly on the Mac. To improve stability and user experience, we've developed an Intelligent Upgrade Service to inform users when there are releases of PySimpleGUI that fix a problem that may be unique to their combination of components.
This is important when someone upgrades their OS which causes a problem with tkinter and PySimpleGUI. We'll be able to detect when they have a known bad configuration and provide instructions for which version of PySimpleGUI will work best given their new environment.
New Features
There are a number of new features are in 5.0 that are not in the GitHub port. The User Settings API has been expanded so that it's better integrated with your layout. It makes working data that persists between runs. For example, a parameter was added to the Window
object that will automatically save the last location you had your windows located and will open it to that location the next time you run the program.
Your Patience Has Been Fantastic
I really appreciate the patience everyone has shown while this development work has been happening. We've done our best to keep bug fixes and some enhancements being added while working on 5.0. It's been much easier with your help.
PySimpleGUI 2023-05-20T16:45:00Z
4.60.5 Posting to PyPI this weekend. 5.0 In June or PySimpleGUI 5 Year Anniversary at the Latest
We're posting a dot-release to PyPI this weekend that addresses 2 Mac issues. Those 2 issues are:
-
Input Element doesn't work for no-titlebar windows on MacOS 13.2.1
-
Narrowed the Alpha Channel 0.99 fix for disappearing window to be only on tkinter 8.6.12. This removes the need for anyone to uncheck the setting in the Mac Control Panel
Release notes will be posted once we're done testing and have uploaded to PyPI.
5.0 is looking good for June. The 5-year anniversary since the initial release of PySimpleGUI is July 7th (I think that's the right day). I would like to be done prior to that date. It's exciting to be getting close, but still a lot to do so I'm sorry if I'm distracted while we're trying to get it all wrapped up.
PySimpleGUI 2023-07-21T14:41:00Z
PySimpleGUI 5 is coming, soon, honest!
I apologize that the schedule for the PySimpleGUI 5 release keeps moving out. There are a lot of new, big additions to the project, such as a new website. That means more moving parts with a lot of new people that have come on board as a result. The added complexity of the release has meant more coordination and a longer release schedule.
We're getting quite close, but a bit further to go. I like products that are stable which means paying attention to the details and testing testing testing.
Thank you for being patient and supportive while we're working behind the scenes. I'm sure this large step forward will bring the quality of the PySimpleGUI experience up significantly as well as make the product more secure, something that's becoming a huge problem in all things software.
Thank you for being the best group of users I could have ever dreamed of serving.
PySimpleGUI 2023-10-02T21:28:14Z
Custom Titlebar Windows and Grab Anywhere Windows Move Smoother
I checked in a change today that make the custom titlebar, grab anywhere and control+Left Mouse move smoother. @jason990420 gave me a hand with it. I'm trying to devote as much time to PySimpleGUI 5 as possible so there aren't as many features going into PySimpleGUI 4. I wanted to get this change out to everyone now and not wait for PySimpleGUI 5.
PySimpleGUI 5 Update
We're still working 7 days a week on the sweeping PySimpleGUI 5 release. The scope of this release is massive with every port of PySimpleGUI changing and every application released to date also changing. Every file is changing in some way.
psggpt
One new application part of the PySimpleGUI 5 release is psggpt. It enables you to query ChatGPT. If you request a short piece of code, you can run it from within the program. ChatGPT has improved over time, and while I wouldn't suggest using it for a lengthy piece of code, it does a fine job when you need help on 5 or 10 lines of code.
Thank you for the Thank you's!
I appreciate the gratitude I see from our users. It's been truly remarkable to experience. I get all warm and fuzzy when someone thanks Jason for his help.
Thank you for your patience while we've been in heads-down mode, working on PySimpleGUI 5.
I owe the world's biggest thank you to Jason who is a miracle worker when it comes to providing support for PySimpleGUI... I'm in awe...and clearly, those getting help are in awe too.
PySimpleGUI 2023-11-02T11:16:05Z
PSG 5 Is Getting Very Close....
It's been such a long long stretch of working on this release. We're getting super close.
Distributing PySimpleGUI Applications
Another application was completed to help with Distribution of PySimpleGUI programs. It will create the setup.py and folder structure you need to distribute your application on PyPI. You'll entire your log and PW, saved locally on your machine, and then click upload.
After this simple upload is completed, you can tell your colleagues, friends, or the world, that they can install your program (e.g. my_application) by typing:
python -m pip install my_application
Thank you for the encouragement and understanding
I see comments in issues telling me that it's clear you're all understanding the slowed pace of me working on PySimpleGUI 4 and it's so helpful to have your support.
Getting PySimpleGUI Listed As A Classifier
Uploading PySimpleGUI applications for distribution via PyPI is something the PySimpleGUI project has done for a while now and the experience is really nice. It feels tightly integrated into Python.
We would like PySimpleGUI to be listed as a Framework in the classifiers on PyPI. If you want to add your support in getting this change added, add a thumbs up to the pull request that was submitted. You only need to click the thumb emoji that's already there:
https://github.com/pypa/trove-classifiers/pull/157
PySimpleGUI 2023-11-17T11:37:01Z
PySimpleGUI Framework Added to PyPI Classifiers
Thank you to everyone that gave a thumbs-up to adding PySimpleGUI to the PyPI classifiers! With PySimpleGUI 5 we're providing tools and instructions to make using PyPI for PySimpleGUI application distribution easier.
You will find PySimpleGUI listed on the left side of the PyPI search page. At the moment, only psgresizer
is marked using this classifier. For this search, I checked PySimpleGUI as a filter
https://pypi.org/search/?q=&o=&c=Framework+%3A%3A+PySimpleGUI
PyPI returned psgresizer as a match:
We're getting closer by the day to being done with PySimpleGUI 5 and releasing it.
PySimpleGUI 2023-12-12T10:09:41Z
Targeting Pre-Christmas PySimpleGUI 5 Release...
We've been targeting to get PySimpleGUI 5 released before Chriastmas
It's become a PySimpleGUI tradition of sorts to release big things at the holidays. But, I also don't like releases that are not rock solid. PySimpleGUI 5 has been running rock solid for months as I've been making changes, but there's been changes all along the way, so the final testing isn't really valid until the a code FREEZE happens with no more changes. I thought I was there a couple times over the past weeks, but still not quite done done done.
I'm "hopeful" for pre-Christmas release, but I'm also not going to cram something out the door just to meet that somewhat arbitrary deadline. It's not fair to you, and it's not fair to the PySimpleGUI team. This is too important of a release to be casual about the quality. Another couple of weeks is not going to have a negative impact compared to releasing a product with problems 2 weeks earlier.
Hoping we make it!
THANK YOU everyone for being SO incredibly supportive over the many many months it's taken. Despite trying, I can't thank @jason990420 enough for providing the world's best product support, but I'm going to keep trying!
PySimpleGUI 2023-12-30T10:07:18Z
Happy New Year's eve-eve
I hope everyone is having a great holiday season. PySimpleGUI 5 clearly didn't make it under the Christmas Tree this year. We are quite close and are feature & code complete. We didn't get through all of the testing and documentation updates in time to get the release out the door.
It's important we maintain the kind of quality our users are accustomed to, and rushing everything out the door without testing would not make for a great experience. We're not shooting for perfection by any means so there will be some rough spots. That's just how software development is.
Thank you so much for the patience during this really long development cycle.
-mike
PySimpleGUI 2024-01-28T18:41:03Z
One more week.....
We're in the final stretch! The target, and I think it's a good target, is PySimpleGUI 5 ships in a week.
The testing is going very well and the proof reading and editing is also underway. We're working hard to make the experience with this release as solid as everyone is used to experiencing with PySimpleGUI over the past 5 years, and I have no doubt that everyone will be blown away by the documentation.
I appreciate the patience and support from everyone! The personal experience I've had with this project has been unlike any project I've been a part of... going back to the 1970's when I fell in love with programming. Thank you for truly making it "the dream come true I didn't know I had".
PySimpleGUI 2024-02-16T11:03:49Z
PySimpleGUI 5 Launch Progress & PySimpleGUI 4 Availability
I really appreciate the patience and support as we continue to roll out PySimpleGUI 5 and the associated applications!
While the GitHub PySimpleGUI repo has been reconfigured and changed from an open-source LGPL license to our commercial license, nothing has changed on PyPI regarding release availability.
100% of the previous releases of PySimpleGUI 4 that were available continue to be hosted on PyPI and available for access. You can pip install PySimpleGUI 4 with no restrictions. Sunsetting the previous open-source releases, as mentioned in the documentation, isn't scheduled until Q2 2024.
PySimpleGUI 2024-02-19T12:57:11Z
PySimpleGUI 5 Debug Watermarking Feature
You may have noticed on some of the screenshots I have posted over the past few months that there is a watermark on many of them with version information and a security badge.
While testing PySimpleGUI 5 I needed to easily see what versions a test/program was running. PSG5 runs on Python 3.6 through 3.13, making testing a chore and debugging a challenge. Being able to glance at a window and see the versions and if the code is secure was very helpful. I thought it may be of help to others so I left the capability in the code and make it a feature.
Here's a simple popup window:
And the same code with the debug watermark enabled:
Across the bottom, you'll find:
-
PySimpleGUI Version number being run
-
tkinter version
-
Python version
-
Security badge - normally green, showing the code has not been tampered with
Enabling/Disabling
Global Settings Window
There are several ways to enable / disable the debug watermark. One is via the Global Settings window:
psgwatermarkoff
and psgwatermarkoff
Commands
You can also use the command line commands psgwatermarkon
and psgwatermarkoff
. Even using this technique, there are multiple ways of accomplishing it. One is to simply use the shell/command prompt
Windows Search Box
On windows, you can enter command line commands in the search-box on the taskbar. WindowsKey+S is a shortcut to get your cursor over there for typing
Shortcuts (for example pinned to the taskbar)
For PySimpleGUI programs or psg-commands that I use frequently, I pin them to my taskbar using the psgshortcut application. With this technique I created 2 shortcuts, each pointing to the corresponding EXE file for the command. Then I pinned each of these shortcuts to the taskbar.
Development Builds
The ability to easily get bug fixes and new features prior to them being officially released to PyPI has been a feature heavily used over the past 4 years. The same as before, a red button is what you're looking for in the psgmain
(Home) Window. psgupgrade
will also launch the same upgrade procedure.
The first step of getting the development build is this confirmation window that shows you the version you're running and the version you're about to install.
New in PSG5 is the ability to see the "release notes" (i.e. changelog) showing the changes that are in the build since the last release to PyPI. You'll find this same information in a file named development_build_changelog.txt contained in the PySimpleGUI GitHub Repo
PySimpleGUI 2024-02-19T15:54:49Z
The PySimpleGUI 5 Documentation
Be sure to check out the new documentation, located at https://Docs.PySimpleGUI.com !
We spent a lot of time completely reworking the documentation. Not only does it look, feel, and perform much better, but you can get everything in one place. The eCookbook was previously hosted on Trinket. Now it's integrated directly into the documentation.
https://docs.pysimplegui.com/en/latest/cookbook/ecookbook/
Trinket hasn't upgraded to PySimpleGUI 5 yet, but all of the eCookbook code runs just as it would using PSG5 so you should notice no difference.
The Call Reference was reworked considerably as well. Here's the page for the Button element in the tkinter port:
https://docs.pysimplegui.com/en/latest/call_reference/tkinter/classes/elements/button/
PySimpleGUI 2024-02-22T18:25:09Z
Thank you!
Really appreciate the:
-
Patience
-
Hobbyists Registrations
-
Commercial Registrations
-
Support & understanding
Thank you to the 1,000's of you that registered for a PySimpleGUI 5 keys! It's great to see people signing up and using the new version.
While there have been a few problems with key input, it's less than .1% which is really great.
We're doing our best to be open, communicative and prompt. Thank you for the kind emails showing support for what we're doing!
PySimpleGUI 2024-02-23T17:01:40Z
License Key Input
The documentation section that shows how to input your license key is located here:
https://docs.pysimplegui.com/en/latest/documentation/installing_licensing/license_keys/
When we run into issues where there's uncertainty, it's not clear, or more needs to be explained, we are adding to the FAQ and/or documentation so that we can point everyone that has an issue to the same place.
I'm also working on a new HOWTO section that shows videos of registering for a key and entering a key for example.
https://github.com/PySimpleGUI/PySimpleGUI/assets/46163555/dc6c5d2d-fc6c-4674-a344-8e6f9b53efdf
There are literally 1,000s of people successfully entering keys so in a broad sense, things are operational. BUT, this is software, and of course there may be bugs. Thank you again for your patience. We're working hard on it.
PySimpleGUI 2024-02-24T07:23:07Z
Addition of PASTE Button for Keys
Software development is an iterative process is something I've known maybe more in the back of my head than something consciously thought about. Having a library that spans 8 versions of Python, 3 major operating systems, many development environments has been quite a unique experience and one I know I'll have to continue to iterate on into the future.
A lesson learned this past week has been on entering Keys.
Yesterday I added a clear and paste buttons to the Home Window. I'll be doing the same to other dialog windows where keys are entered. Here's how the Home Window turned out:
A Paste button removes the need for knowing the shortcut key for pasting a string. A Clear button wasn't a bad addition either.
Once I get these additions done and tested, I'll get them onto PyPI and into the documentation.
Software Can be SO Frustrating
When others struggle to set up a Zoom call or meeting or get something to work and tell me how stupid they feel, I'm quick to point out to them that I struggle just as much, make just as many errors. "It's not YOU, honest!"
If you're frustrated at the problems you're having, I get it for sure! I'm seeing a lot of patience shown in the messages I've received and the issues that are posted. I've got no great piece of wisdom here.... just wanting to say thank you to everyone for being patient and kind. I really appreciate it! Thank you for the help.... your support is very much helping.
Roll Into the Docs What's Learned
It hadn't occurred to me that some of the activities post-launch would be to quickly make adjustments to the documentation so that one person's report of not understanding is not just a single issue to solve on GitHub, but rather a hole in our documentation that needs quickly fixing so that others don't also become confused.
PySimpleGUI 2024-02-27T13:49:16Z
PySimpleGUI 5 Applications Released
'########:::'######:::'######::::::'########:
##.... ##:'##... ##:'##... ##::::: ##.....::
##:::: ##: ##:::..:: ##:::..:::::: ##:::::::
########::. ######:: ##::'####:::: #######::
##.....::::..... ##: ##::: ##:::::...... ##:
##::::::::'##::: ##: ##::: ##:::::'##::: ##:
##::::::::. ######::. ######::::::. ######::
..::::::::::......::::......::::::::......:::
:::'###::::'########::'########:::'######::
::'## ##::: ##.... ##: ##.... ##:'##... ##:
:'##:. ##:: ##:::: ##: ##:::: ##: ##:::..::
'##:::. ##: ########:: ########::. ######::
#########: ##.....::: ##.....::::..... ##:
##.... ##: ##:::::::: ##::::::::'##::: ##:
##:::: ##: ##:::::::: ##::::::::. ######::
..:::::..::..:::::::::..::::::::::......:::
It's taken a little while to get all of the new "PSG Applications" posted to GitHub and PyPI. These are the applications:
-
psgdemos - the demo programs and demo browser
-
psgresizer - image converter, resizer, and most importantly a Base64 encoder
-
psgtray - system tray icon for PySimpleGUI
-
psgfiglet - create figlets...I use them heavily for commenting my code and as a banner like above
-
psggadgets - these are called "Desktop Widgets" in the demo programs. This is a new app
-
psgshortcut - create shortcuts for window easily. A must for pinning programs to taskbar, etc.
-
psgyolo - the YOLO AI application that's been a part of PySimpleGUI for a long time
-
psgtest - test tool for regression testing and testing across multiple versions of python
-
psgcompiler - front-end for PyInstaller. This is how I make EXE files
-
psghotkey - a hotkey manager that runs in the system tray
-
psgreddit - reddit searcher/reader that shows how to use the praw module
More applications are in development such as a PyPI application uploader. It's working (I used it to upload all of the above to release at the moment.
Pip Installing the Applications
I'm trying something new with the applications. PyPI is the official home and the easiest place to install them from as the command is, for example:
python -m pip install --upgrade psgfiglet
To install directly from the GitHub repo, this is the command to use:
python -m pip install --upgrade https://github.com/PySimpleGUI/psgfiglet/zipball/main
It's been a great way to test the pip installs prior to uploading, but it is something new that I've not heavily studied and may have problems I've not yet seen.
Again, thank you for your patience as this sprawling update continues to be rolled out. There are a lot of exciting additions that I'm looking forward to showing here. They're in the documentation, but there's a lot of documentation, and don't expect everyone to go through it all to find the fun new things in there.
PySimpleGUI 2024-02-27T13:56:32Z
Trinket Updated to PySimpleGUI 5
We've worked closely with the fine folks at Trinket for years. This weekend they updated the version of PySimpleGUI used in Trinkets to the latest PyPI release. All of the Trinkets you see embedded in our documentation are now running PySimpleGUI 5, as do the exercises that are part of the Udemy course.
Here's an example of the "All Elements" Trinket that is embedded in the docs:
https://docs.pysimplegui.com/en/latest/documentation/module/elements/#pseudo-elements
eCookbook
The eCookbook is now integrated into the documentation:
https://docs.pysimplegui.com/en/latest/cookbook/ecookbook/
One of the big advantages to it being fully integrated, in addition to one-stop-documentation, is that your searches of the documentation also search the eCookbook.
PySimpleGUI 2024-03-03T15:21:44Z
PySimpleGUI 5 Documentation Update
We've done a bit of reshuffling of the call reference. The tkinter call reference is here:
https://docs.pysimplegui.com/en/latest/call_reference/tkinter/
I'm really proud of the way the PSG5 documentation turned out. It's so much better than the previous version in numerous ways.
This change re-organized the table of contents. We also added to the Elements section. Elements are implemented using classes and some are implemented using simple functions. The Push
Element and pre-defined buttons like Ok
are examples of Elements that are implemented as functions.
Release 5.0.3
I'm posting 5.0.3 to PyPI later today. It has an important fix for licenses that contain what I'll call "special characters". A tooltips enhancement is also part of the release. You can see the contents of the latest development build from the Home Window and can also be found in this GitHub repo in the file:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/development_build_changelog.txt
You'll see that we're up to 5.0.2.11. To see the notes from the Home Window:
Click the red button
This opens the upgrade window.
Click the "Show Release Notes" button and you'll see a window with the release notes:
New PSG 5 Features
Several new features were added that I'll be creating and releasing Demo Programs for.
Window Parms print_event_values
and auto_save_location
A couple of new Window parameters
print_event_values
set to True
will cause the event and values variables to be printed for you when you read a window.. Timeout events are filtered out.
auto_save_location
will cause your window to be opened in the location where it was last located.
setting
Parm for Elements
This is a great feature for "settings" portions of your GUI. The value of the setting
parameter indicates the Element will automatically save/load values between runs. The value of the setting
parameter indicates the initial value you would like to start with. After a value is saved, it will no longer use the value of the parameter. Instead, the saved value is loaded.
To save the values, you'll make this call when you exit your program:
This will save the values of elements that have the setting
parm.
It'll be much more clear with a Demo Program. Here's a short example using these new features:
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-', setting='My initial value')],
[sg.Checkbox('Checkbox', key='-CB-', setting=True)],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Setting Example', layout, enable_close_attempted_event=True, print_event_values=True, auto_save_location=True)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit' or event == sg.WIN_CLOSE_ATTEMPTED_EVENT:
window.settings_save(values)
break
window.close()
PySimpleGUI 2024-03-16T10:33:54Z
Changes To Licensing Coming....
Thank you everyone that's sent email to ask questions and give feedback on the license model. It's been very helpful for us to hear your thoughts, questions, situations. As a result, we're making a couple of changes to the licensing that I personally like better, as a developer, and I believe a lot of you will like the changes too.
Thank you for the support, patience, understanding, encouragement, and kindness during this period of change and refinement. I'm going to keep doing my best every day to make PySimpleGUI a better library as I have since the launch in 2018. The goal, in all these changes, is to enable the library to continue into the future. I don't want for this to simply all end, and have the software be another project dies because it's not sustainable.
Can't wait to get the changes made and the information posted so stay tuned!