Skip to content
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

[Community] Did you try PySimpleGUI because it does not require writing classes? #775

Closed
MikeTheWatchGuy opened this issue Nov 24, 2018 · 10 comments

Comments

@MikeTheWatchGuy
Copy link
Collaborator

I have a theory about the relative popularity of PySimpleGUI. I think the straightforward, procedural-styled interfaces are appealing to many of the users. Perhaps you haven't covered Classes in your Python class yet. Or maybe you're just not feeling entirely comfortable programming using classes.

If you're one of those people, I would like to hear from you. Or maybe you're not one of those people and you still chose PySimpleGUI despite it not requiring the use of classes.

In reality, classes are being used by users. Each of the Elements is a class. The Window is a class, etc. You're USING classes and class interfaces, it's just in a rather controlled kind of fashion where those interfaces are supplied to you by the way of design patterns such that you don't need to figure out how to make the calls, they have been given to you as a starting point.

@RussellJQA
Copy link

I'm comfortable programming using classes, but have starting using PySimpleGUI because it makes it so simple to create a basic GUI. I also like that it's so easy to switch between PySimpleGUI and PySimpleGUIQt.

@till314
Copy link

till314 commented Dec 1, 2018

Same here. Classes are not the problem but the amount of boilerplate you normally need for a simple throw-away GUI. Most programmers are lazy, or rather, averse to pointless context switching between the stuff you really want to think about and the stuff you would have to think about to set up an GUI.

@btnpushnmunky
Copy link

I agree with the previous posts. The reduction in boilerplate is the most attractive feature.

@eagleEggs
Copy link

Boilerplate bandwagon +1

@clarg18
Copy link

clarg18 commented Dec 2, 2018

I understand classes but I have never 'written' a GUI before. (I've used tools like Visual Studio and forms using VBA) I've never really been interesting in 'writing' a GUI so I avoided it with python and stuck to command line stuff. With PySimpleGUI it's quick and easy to write a gui for my scripts so that's why I am using it.

@RayJohnson2
Copy link

I just began learning Python. I know a thing or two about Windows programming but am not terribly comfortable with classes.
I spent some time looking at the various GUI frameworks available for Python. Not straightforward because each has pros and cons.
I am just scratching the surface of Python, so I rather do not want to spend a lot of time learning the ins and outs of a GUI framework (such as QT for example).
I was primarily searching for a GUI framework that has a Visual Designer (I'm a fan of click-drag-drop .. :-) ). Except for QT, not many Visual Designers around for Python ...
For this reason, I skipped PySimpleGUI at first, but somehow it drew my attention again.
And I decided ... to use it! What attrackts me now so much in PSG is its remarkable ease of use! You are up and running in literally 5 mins. Also the row/column concept is so straightforward that you can build a GUI in a very short time.
Also the sequential nature of a PSG GUI is really clear and simple. In contrast of the typical event-driven GUI's.
I'm sure, sooner or later I will bump into a limitation of PSG, but we will have to find a workaround then.
For now, I'm a big fan for the above reasons.
A big thank you to the developers!!

@MCilento93
Copy link

Hello,
I was just looking for a post like this to add my concerns about.

I am a python user from vbasic and particular matlab, where writing the most oh my code procedural.

That's for at first GLANCE of documentation I started using PSG.

But now, I have in my hands a quite large interface (the main window with many elements) and I was looking for a more smart way to hide/show elements with a logic behind.
I have the feeling that this issue structured procedural is not so efficient, maybe OOP paradigm would be better: but I do now find out demos with PSG embedded in OOP fashion design.

@PySimpleGUI
Copy link
Owner

Hi @MCilento93

I'm taking a break from answering GitHub issues so sorry for the quick in and out. I'll be back to normal soon-ish. I've got some pressing matters to deal with first. This topic has been on my mind as I've been working on training for PySimpleGUI users.

The reason for this particular issue was to gain a better understanding of the PySimpleGUI user base.

I've tried to be clear in the PySimpleGUI architecture and why it's done the way it is and that OO in itself is not a bad thing. PySimpleGUI itself makes use of classes throughout the code. Every element is a class.

How one chooses to architecture their entire solution is determined by the user, not PySimpleGUI. That's the bigger point behind why PySimpleGUI is different than the other GUI solutions is that it does not force you into an OO paradigm. It leaves that decision up to you.

What I've not recommended is subclassing the elements and the Window objects. I don't think it's the best way to use the package.

There are no demos that are large enough to warrant breaking up the program into a larger design because the demos are tightly targeted at how to utilize each of the elements in a simple manner. Also, I've not wanted to lose anyone that's not that far along in their Python education.

I've used OO designs with PySimpleGUI. Early on I had a client that needed a fairly large solution and OO made sense in that situation.

For decades largescale systems have been built without the Object Oriented methodology, and they continue to be. How one goes about breaking a problem down and encapsulating functionality can be done with functions, modules/files, etc.

The short answer is that I don't have demos posted that are large programs. Maybe in the future, but for now, there's been too much work being done that I have viewed as a higher priority.

I urge you to look for tutorials and discussions on the net about ways to break apart large Python projects. Maybe OOP is the answer to the way you think about breaking up problems. If so, go that route. If you have multiple windows, perhaps encapsulate each into a class that contains the event loop and the layout. I do this in a few examples posted in other repos from what I recall.

Lately I've been placing parts of layouts into functions. Setup windows are in functions. Window creation is done in a function with the layout in a different function. Breaking apart the problem is definitely possible OOP or not.

I've heard complaints about long strings of if/else statements in event loops. There are some demos that show alternate 'dispatchers' that handle the logic using dictionaries instead of if statements. Python is rich with ways of taking an initial simple, flat, straightforward way of doing things and turning it into something more modular.

I'll be able to get into this more when I return. I'm sorry for the brief answer and that I've not been able to research it further. II didn't want to see you sitting still though believing you don't have options due to the PySimpleGUI architecture. Hopefully, you've got some clues from the post. If not, I'll try again further down the road.

Thanks for trying PySimpleGUI, making something larger than most, and posting here looking for help.

@MCilento93
Copy link

I'll be able to get into this more when I return. I'm sorry for the brief answer and that I've not been able to research it further. II didn't want to see you sitting still though believing you don't have options due to the PySimpleGUI architecture. Hopefully, you've got some clues from the post. If not, I'll try again further down the road.

Dear developer,
your long answer confirm your 'verbose' and lovely attention that you offer to the user of this joyful project. Your answer for me is clear, the clearest clue actually is the name of the package itself.
And 80% of the case starting using PSG comes to be a powerful weapon for every fast project/problem our life sets in front of us nowaday.

Overally, I will deepen my research googling around for more complex and structured OOP PSG paradigms, fitting better my case.

I look forward to reading you soon on the argument again about,
Regards.

@MCilento93
Copy link

MCilento93 commented Dec 25, 2020

Anyway,
I am speding my Xmas family lunch by writing a little bit of MVC architecture for PySimpleGUI.
As said above, I am looking for something like this for complex GUIs, with tons of elements and complex objects in the model backend.

Do you see something like this may be interesting of am I wronging something under the architecture point of view ? From one side I know that we as users are free to use PSG as we wish ... from the other side I have no references with this package to write something robust and efficient.

# -*- coding: utf-8 -*-
"""
Created on Fri Dec 25 10:22:39 2020

@author: mario
"""

### MODULES

import PySimpleGUI as sg
sg.theme('LightGrey1')

### GLOBALS

LIST_FILMS=['The Dead Zone','Frailty','Shutter Island']

### CLASSES

class Model():
    
    def __init__(self):
        self.list=LIST_FILMS
        
    @property
    def names(self):
        return self.list
    
    def delete_by_index(self,index):
        self.list.pop(index)
        
    def add(self,name):
        self.list.append(name)
        
class View():
    
    def __init__(self,window,layout):
        
        # general
        self.w=window
        self.l=layout
        
        # local
        self.key=None
        self.values=None
        
    def update(self,event, values):
        self.key=event
        self.values=values
        
    def refresh(self,model):
        self.element('-LIST-').update(values=model.names)
        self.element('-NAME-').update(value='')
        
    #----key element
    def element(self,key):
        return self.w[key]
    
    def value(self,key):
        return self.values.get(key)
        
    def show(self,key):
        self.w[key].update(visible=True)
    
    def hide(self,key):
        self.w[key].update(visible=False)
        
    def index_selected_list(self,key):
        return self.element(key).GetIndexes()[0]
        
    #----current element
    @property
    def __element(self):
        if self.key != '__TIMEOUT__':
            return self.w[self.key]
        else:
            return None
        
class Controller():
    
    def __init__(self,model,view):
        self.m=model
        self.v=view
        self._index_selected=None
        self._modifying_list=False
        
    def update(self,event):
        
        if event == '-LIST-':
            if self.v.index_selected_list('-LIST-') == self._index_selected:
                self.v.refresh(self.m)
                self._index_selected=None
            else:
                self.v.element('-NAME-').update(value=self.v.value('-LIST-')[0])
                self._index_selected=self.v.index_selected_list('-LIST-')
                self._modifying_list=True
            
        if event == '-ADD-':
            if self.v.value('-NAME-'):
                self.m.add(self.v.value('-NAME-'))
                self.v.refresh(model=self.m)
                self._modifying_list=False
                self._index_selected=None
        
        if event == '-DELETE-':
            if self._index_selected:
                self.m.delete_by_index(int(self._index_selected))
                self.v.refresh(model=self.m)
                self._modifying_list=False
                self._index_selected=None
            
        if self.v.value('-NAME-')!='':
            self._modifying_list=True
        else:
            self._modifying_list=False
            
        if self._modifying_list:
            self.v.show('-ADD-')
            self.v.show('-DELETE-')
        else:
            self.v.hide('-ADD-')
            self.v.hide('-DELETE-')
            
### METHODS

def main():
       
    # Model
    m=Model()
    
    # GUI
    layout = [[sg.Listbox(values=m.names,size=(20,6),key='-LIST-',select_mode=sg.LISTBOX_SELECT_MODE_SINGLE,enable_events=True)],
              [sg.Text('Name: ', size=(15, 1)), sg.InputText(key='-NAME-')],
              [sg.Button('Add',key='-ADD-',visible=False),sg.Button('Delete',key='-DELETE-',visible=False)],
              [sg.Button('Exit')]]
    
    window = sg.Window('Movie Listbox', layout,grab_anywhere=False,finalize=True)
    
    # View
    v=View(window, layout)
        
    # Controller
    c=Controller(m,v)
    
    # Polling
    while True:
        
        event, values = window.read(timeout=100)
        
        if event == sg.WIN_CLOSED or event == 'Exit': # if user closes window or clicks cancel
            break
        
        # update of the view parameters (can be included in controller)
        v.update(event, values)
       
        # update of controller
        c.update(event)

        # more if statements not involving models/view (for exemple trigger new windows ...)
        
    window.close()
    return m
        
### MAIN

if __name__=='__main__':
    model=main()

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

No branches or pull requests

10 participants