New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Announcements #142

Open
MikeTheWatchGuy opened this Issue Sep 6, 2018 · 253 comments

Comments

Projects
None yet
5 participants
@MikeTheWatchGuy
Owner

MikeTheWatchGuy commented Sep 6, 2018

Announcements - New Features, Design Patterns, and Methods

I'm unsure how GitHub sends out updates. I don't think people are informed about Wiki changes for example. I've been announcing new features and more importantly, new ways of doing things, on the Wiki. I'm going to put announcements here so they are more visible. If there are objections about the traffic, well, what can I say, it's a busy/active project.

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 6, 2018

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:

layout = [[sg.Text('My text', key='text')]]

Later in your code you can update this Text Element by making this call, assuming the variable form is your FlexForm object:

form.FindElement('text').Update('new text')

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 6, 2018

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.

borderless grayed buttons

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 7, 2018

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 = Falsein 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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 7, 2018

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.

light table

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 7, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 8, 2018

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.

floating launcher

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 8, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 8, 2018

RELEASED 3.0.2

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 8, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 9, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 9, 2018

Floating Desktop Widgets

I've discovered that in about 30 lines of code you can create a floating desktop widget.

snap0276

If you click the pause button, it switches to Run.

snap0275

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 10, 2018

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..

snap0204

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 10, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 10, 2018

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?

tear off

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 10, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 11, 2018

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!

enabled
disabled

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 11, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 12, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 12, 2018

Two new Demo programs - CPU Desktop Widget, Spinner Compound Element

Added another Desktop Widget to the demos. This one shows the CPU utilization.

cpu widget

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.

spinner compound

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 13, 2018

Table Element, Complete rework of Popups, Death of MsgBox

You can blame the Popup changes on this issue:
#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.

scrolled table

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 14, 2018

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.

ping graph linux
toolbar linux
all linux
ping linux

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 14, 2018

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:

form.Layout(layout)
form.Finalize()
element.Update(.....)
while True:
     b, v = form.Read()

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 15, 2018

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.

onelineprogressmeters

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 15, 2018

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....

  1. The ability to turn off displaying row numbers
  2. 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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 16, 2018

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.

ping graph

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 16, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 16, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 16, 2018

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:

  1. Draw Line
  2. 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.

snap0282

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.

snap0283

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Sep 17, 2018

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

scrollingping

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 7, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 7, 2018

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.

snag-0207

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 7, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 8, 2018

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.

snag-0208

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 8, 2018

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.

snag-0210

Here's the verdict on load times. It's not close enough to be a contest.

snag-0211

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 8, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 8, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 9, 2018

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.

snag-0218

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 9, 2018

Qt Table Element

Told you I was working hard to get that Table Element working... and now I've got a crude version working!

snag-0219

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 9, 2018

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

  1. Text
  2. Single Line Input
  3. Multiline input
  4. Multiline output (2 different ones now)
  5. Output (stdout)
  6. Button
  7. Listbox
  8. Combobox
  9. Spinner
  10. Radio
  11. Checkbox
  12. Slider
  13. Table
  14. Column
  15. Labelled Frame
  16. Dial (brand new element!)

Elements to be completed:

  1. Graph
  2. Image
  3. Tree
  4. Option menu (may not be possible)
  5. Progress Meter
  6. 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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 9, 2018

Qt Table Reads Work...

Well, that was quick. Thank you HowDoI!!

Just like the original PySimpleGUI, the Qt version returns which rows are selected.

snag-0220

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 9, 2018

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

snag-0226

snag-0227

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 9, 2018

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

dial element

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 10, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 10, 2018

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:
snag-0232
snag-0233

And this is the Qt version

snag-0230
snag-0231

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:

snag-0234

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 10, 2018

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.

snag-0235

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 10, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 11, 2018

"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!

snag-0237

The source code was 100% backwards compatible. Even the transparency was correct.

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 11, 2018

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!

cpu core dash - both qt and tkinter

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 11, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 11, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 11, 2018

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 11, 2018

TABS!

Yes, Tabs are among the slain features. It took a lot of wrestling with Qt

snag-0243

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 MikeTheWatchGuy referenced this issue Nov 11, 2018

Merged

Tabs! #705

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 11, 2018

Trees!

snag-0244

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 12, 2018

Base 64 Images

snag-0245

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 12, 2018

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')]]

snag-0246

Having the stretch on the left side of the Button caused the button to go to the far right.

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 12, 2018

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!

snag-0247

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

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 12, 2018

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.

progress meter

And even better news.... the Progress Meter code is 10 times faster.


Here is what the final list of Elements looks like:

snag-0252

@MikeTheWatchGuy

This comment has been minimized.

Owner

MikeTheWatchGuy commented Nov 12, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment