Issue with sub windows - modal not working #108

Closed
jacobthetechy opened this Issue Mar 10, 2017 · 8 comments

Comments

Projects
None yet
2 participants
@jacobthetechy
Contributor

jacobthetechy commented Mar 10, 2017

def openLogin():
    app.showSubWindow('L')


app = gui('SLA Sendback Entry')

# Login #
app.startSubWindow("L", modal=True)
app.addLabelEntry('Username')
app.setFocus('Username')
app.addLabelSecretEntry('Password')
app.addButton('Login', login)
app.stopSubWindow()

app.addLabelEntry('Entry')
app.setFocus('Entry')

openLogin()

Above code will not open any window. When you remove modal=true it works.

python 2.7.12
Windows 7

@jarvisteach

This comment has been minimized.

Show comment
Hide comment
@jarvisteach

jarvisteach Mar 11, 2017

Owner

There's an issue in the above code, in that it doesn't call app.go().
That results in lots of setup not being completed, including the eventLoop not being started.
So, that may be causing some issues...

However, I see two things to investigate here:

  1. Is the modal flag working properly - I know there have been some issues with it in the past, especially cross-platform.

  2. How best to support multiple windows... appJar is designed to have a main window (the app), but grew to support subWindows - allowing popUps to be launched. I'm seeing more & more use cases like this, where people want the subWindows to launch first, and only to show the main window, once the user has logged in (for example).

I'll keep this issue open as an investigation into modal, and will raise a new issue to consider how to best implement a sequence of windows being used, and how to specify showing a subWindow first, rather than the main app...

Owner

jarvisteach commented Mar 11, 2017

There's an issue in the above code, in that it doesn't call app.go().
That results in lots of setup not being completed, including the eventLoop not being started.
So, that may be causing some issues...

However, I see two things to investigate here:

  1. Is the modal flag working properly - I know there have been some issues with it in the past, especially cross-platform.

  2. How best to support multiple windows... appJar is designed to have a main window (the app), but grew to support subWindows - allowing popUps to be launched. I'm seeing more & more use cases like this, where people want the subWindows to launch first, and only to show the main window, once the user has logged in (for example).

I'll keep this issue open as an investigation into modal, and will raise a new issue to consider how to best implement a sequence of windows being used, and how to specify showing a subWindow first, rather than the main app...

@jarvisteach jarvisteach self-assigned this Mar 11, 2017

@jarvisteach jarvisteach added the bug label Mar 11, 2017

@jarvisteach jarvisteach added this to the 0.06 milestone Mar 11, 2017

@jarvisteach jarvisteach changed the title from Issue with subwindows to Issue with sub windows - modal not working Mar 11, 2017

@jacobthetechy

This comment has been minimized.

Show comment
Hide comment
@jacobthetechy

jacobthetechy Mar 11, 2017

Contributor

The work around was to take the modal out and to place a transparency on the main window until the user logged in. When that was successful i then hid the subwindow and changed the transparency back to the main window.

Ill post the code tomorrow morning when I'm back at work.

Work around

def login(btn):
    u = app.getEntry('Username')
    p = app.getEntry('Password')
    if u == '' or p == '':
        app.errorBox('Login Error', 'Enter in both username and password!')
    else:
        user = db.query(User).filter_by(username = u).one_or_none()
        if user != None:
            if user.check_password(p):
                print('yay')
                app.clearEntry('Username')
                app.clearEntry('Password')
                app.setTransparency(100)
                app.hideSubWindow('L')
            else:
                app.errorBox('Login Error', 'Incorrect password!')
                app.clearEntry('Password')
                app.setFocus('Password')
        else:
            app.errorBox('Login Error', 'No user by {}!'.format(u))
            app.clearEntry('Username')
            app.clearEntry('Password')
            app.setFocus('Username')

def openLogin():
    app.showSubWindow('L')
    app.setFocus('Username')


employee_list = [str(i[0]) for i in db.query(Finisher.initials).\
                                       filter(Finisher.active == True).all()]

app = gui('SLA Sendback Entry')

# Login #
app.startSubWindow("L")
app.setLocation(900,400)
app.addLabelEntry('Username')
app.setFocus('Username')
app.addLabelSecretEntry('Password')
app.addButton('Login', login)
app.stopSubWindow()

# Data Entry
app.addLabel('l1', 'Sendback Data Entry')
app.addAutoEntry('Employee', employee_list, row)
app.setFocus('Employee')
app.addLabelEntry


app.setTransparency(0)
openLogin()
app.go()
Contributor

jacobthetechy commented Mar 11, 2017

The work around was to take the modal out and to place a transparency on the main window until the user logged in. When that was successful i then hid the subwindow and changed the transparency back to the main window.

Ill post the code tomorrow morning when I'm back at work.

Work around

def login(btn):
    u = app.getEntry('Username')
    p = app.getEntry('Password')
    if u == '' or p == '':
        app.errorBox('Login Error', 'Enter in both username and password!')
    else:
        user = db.query(User).filter_by(username = u).one_or_none()
        if user != None:
            if user.check_password(p):
                print('yay')
                app.clearEntry('Username')
                app.clearEntry('Password')
                app.setTransparency(100)
                app.hideSubWindow('L')
            else:
                app.errorBox('Login Error', 'Incorrect password!')
                app.clearEntry('Password')
                app.setFocus('Password')
        else:
            app.errorBox('Login Error', 'No user by {}!'.format(u))
            app.clearEntry('Username')
            app.clearEntry('Password')
            app.setFocus('Username')

def openLogin():
    app.showSubWindow('L')
    app.setFocus('Username')


employee_list = [str(i[0]) for i in db.query(Finisher.initials).\
                                       filter(Finisher.active == True).all()]

app = gui('SLA Sendback Entry')

# Login #
app.startSubWindow("L")
app.setLocation(900,400)
app.addLabelEntry('Username')
app.setFocus('Username')
app.addLabelSecretEntry('Password')
app.addButton('Login', login)
app.stopSubWindow()

# Data Entry
app.addLabel('l1', 'Sendback Data Entry')
app.addAutoEntry('Employee', employee_list, row)
app.setFocus('Employee')
app.addLabelEntry


app.setTransparency(0)
openLogin()
app.go()
@jarvisteach

This comment has been minimized.

Show comment
Hide comment
@jarvisteach

jarvisteach Mar 18, 2017

Owner

Next_release will have .hide() & .show() for the main window, along with a parameter to the .go() function to allow starting with a SubWindow. See issue #112

So, the final three lines of code above can be replaced with:

app.go(startWindow="L")

And, instead of increasing transparency to show the main window, you simply call:

app.show()
Owner

jarvisteach commented Mar 18, 2017

Next_release will have .hide() & .show() for the main window, along with a parameter to the .go() function to allow starting with a SubWindow. See issue #112

So, the final three lines of code above can be replaced with:

app.go(startWindow="L")

And, instead of increasing transparency to show the main window, you simply call:

app.show()
@jarvisteach

This comment has been minimized.

Show comment
Hide comment
@jarvisteach

jarvisteach Apr 12, 2017

Owner

@jacobthetechy I've looked into this some more.

Setting the popup as modal=True and then calling openLogin() pauses the code at that point. Execution never gets to the call to app.go(), which means none of the windows ever get drawn on the screen.

When modal=False the call to openLogin() doesn't block, allowing app.go() to be reached, and therefore the windows to be drawn.

This explains the issues you had with your original code.

The changes mentioned above also break when modal=True. Calling app.hide() when a modal dialog is showing will hide both the main window and the modal window - I guess the two are quite closely linked.

The changes above also don't cater for having the main window launch, with a dialog drawn above it - which may have been your original use case?

Owner

jarvisteach commented Apr 12, 2017

@jacobthetechy I've looked into this some more.

Setting the popup as modal=True and then calling openLogin() pauses the code at that point. Execution never gets to the call to app.go(), which means none of the windows ever get drawn on the screen.

When modal=False the call to openLogin() doesn't block, allowing app.go() to be reached, and therefore the windows to be drawn.

This explains the issues you had with your original code.

The changes mentioned above also break when modal=True. Calling app.hide() when a modal dialog is showing will hide both the main window and the modal window - I guess the two are quite closely linked.

The changes above also don't cater for having the main window launch, with a dialog drawn above it - which may have been your original use case?

@jarvisteach

This comment has been minimized.

Show comment
Hide comment
@jarvisteach

jarvisteach Apr 12, 2017

Owner

Modal dialogs have a few few function calls available:

  1. <modal_win>.focus_set() - give the dialog focus
  2. <modal_win>.transient(<parent_win>) - links it to the parent, rather than being standalone
  3. <modal_win>.grab_set() creates modality - it stops events firing on any other windows
  4. <parent_win>.wait(<modal_win>) tells the parent to effectively not close until modal has been closed

If the user is declaring a modal window, they definitely want 1 & 3.

2 & 4 are not necessarily characteristics of modal windows, they should be configurable separately:

  • .setBlocking() to tell the modal not to return
  • .setTransient() to tell the modal to not act like a normal window
Owner

jarvisteach commented Apr 12, 2017

Modal dialogs have a few few function calls available:

  1. <modal_win>.focus_set() - give the dialog focus
  2. <modal_win>.transient(<parent_win>) - links it to the parent, rather than being standalone
  3. <modal_win>.grab_set() creates modality - it stops events firing on any other windows
  4. <parent_win>.wait(<modal_win>) tells the parent to effectively not close until modal has been closed

If the user is declaring a modal window, they definitely want 1 & 3.

2 & 4 are not necessarily characteristics of modal windows, they should be configurable separately:

  • .setBlocking() to tell the modal not to return
  • .setTransient() to tell the modal to not act like a normal window

jarvisteach added a commit that referenced this issue Apr 12, 2017

@jarvisteach

This comment has been minimized.

Show comment
Hide comment
@jarvisteach

jarvisteach Apr 12, 2017

Owner

.startSubWindow() now has two additional parameters: transient & blocking these are configured when creating the SubWindow, and will be applied accordingly.

Final thing to look into is grouping - it's being configured in the SubWindow, and there is a parameter for it, but it's not documented.

Also can update testing now, to include some modal windows...

Owner

jarvisteach commented Apr 12, 2017

.startSubWindow() now has two additional parameters: transient & blocking these are configured when creating the SubWindow, and will be applied accordingly.

Final thing to look into is grouping - it's being configured in the SubWindow, and there is a parameter for it, but it's not documented.

Also can update testing now, to include some modal windows...

@jarvisteach

This comment has been minimized.

Show comment
Hide comment
@jarvisteach

jarvisteach Apr 12, 2017

Owner

Also, app.go() with a blocking dialog should fail - with an error message...

Owner

jarvisteach commented Apr 12, 2017

Also, app.go() with a blocking dialog should fail - with an error message...

jarvisteach added a commit that referenced this issue Apr 13, 2017

Added blocking check to go() (#108)
Throw exception if user tries to start appJar with a blocking SubWindow.

Slight change to grouping - will raise a new issue for this.

Updated testing to include modals.
@jarvisteach

This comment has been minimized.

Show comment
Hide comment
@jarvisteach

jarvisteach Apr 13, 2017

Owner

Grouping raised as a new issue (#144)

Closing issue, as all investigation and changes have been made here...

Owner

jarvisteach commented Apr 13, 2017

Grouping raised as a new issue (#144)

Closing issue, as all investigation and changes have been made here...

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