jarvisteach / appJar

Simple Tkinter GUIs in Python
http://appJar.info
Other
615 stars 68 forks source link

AutoEntry in subwindows #594

Closed projectbtle closed 4 years ago

projectbtle commented 4 years ago

Bug Report


Adding an AutoEntry to a subwindow causes the auto-complete entries to be displayed on the main window, rather than on the subwindow. Adding an auto-entry to a subwindow, which itself is opened from another subwindow, doesn't seem to display any auto-complete entries at all.

Context


I have a GUI with a main window, from which a subwindow (let's say X) can be opened. From that subwindow X, another subwindow (say Y) can be opened. Subwindow Y contains an AutoEntry widget. However, even though the words list is definitely not empty (tested by printing it out before assigning it to the AutoEntry widget), nothing is displayed when you press the DOWN arrow, or type the first letter of one of the words.

Tried with a minimal example comprising a single subwindow, and found that the auto-complete entries seem to be displayed with respect to the parent window, not the subwindow.

I'm not sure whether I'm missing something here. Is there a way to set a parent for the AutoEntry widget?

Expected Behaviour


Auto-complete values should be displayed on the subwindow within which the AutoEntry field is declared.

Actual Behaviour


The following screenshots were taken when running the sample script below. When you hit the DOWN key from within the AutoEntry field of the subwindow, then the entry field will be displayed only if the subwindow is positioned over the main window at the time, but it will be displayed with respect to the main window (observable by moving the subwindow).

Auto-Entry field on main window works as expected

auto_entry_main_window_works

Hitting DOWN key on subwindow displays auto-complete values with respect to main window

auto_entry_sub_window_displays_in_main_0

Better observed by moving the subwindow

auto_entry_sub_window_displays_in_main_1

If DOWN key is pressed when subwindow is away from main window, then no auto-complete entries are displayed

auto_entry_sub_window_wont_display_if_away_from_main

Any error messages produced by appJar


None.

Sample code, demonstrating the issue


from appjar import gui

def showsub():
    app.showSubWindow('subwindow1')

app = gui("ISSUE WITH AUTO-ENTRY", "350x150")
app.setPadding(10,10)
app.addLabelAutoEntry('entry1', ['a1', 'b1', 'c1'], label='Entry1')

app.startSubWindow('subwindow1', modal=True)
app.setSize(300, 200)
app.startFrame('subwindowframe')
app.addLabelAutoEntry('subwindowentry', ['a2', 'b2', 'c2'])
app.stopFrame()
app.stopSubWindow()

app.addButton('Show subwindow', showsub)

app.go()

What steps are needed to reproduce the bug


Run the above as a standalone script.

Version Information


appJar: 0.94.0 Python: 3.7.3 TCL: 8.6, TK: 8.6 Platform: Windows

jarvisteach commented 4 years ago

Hi @projectbtle - thanks for raising lots of issues, really starting to iron out some less common bugs!

Looking at this, I think if you remove the code to create the frame in the subWindow then the autoEntry works (can you confirm).

This issue seems to be when there are nested containers in a subWindow, appJar is getting a bit confused about the topLevel container, and reverts back to the parent window.

The function def _getTopLevel() needs changing, so that if it detects a subWindow anywhere in the stack, it returns it. Instead of the situation now, where if the top item in the stack is a subWindow it returns that, otherwise it returns the topLevel container.

jarvisteach commented 4 years ago

Replacing the _getTopLevel() code with this will resolve it:

def _getTopLevel(self):
        for container in self.containerStack[::-1]:
            if container['type'] == WIDGET_NAMES.SubWindow:
                return container['container']

        return self.topLevel
jarvisteach commented 4 years ago

NB. I think this is also broken in the _getCanvas() function used for D'nD

projectbtle commented 4 years ago

Hopefully this doesn't re-open the issue...

Thanks for looking into this. I can confirm that the autoentry works without the frame.

I can't remove the frame in my actual code, because it's used to group some elements together, so I ended up creating a button that displays a subwindow containing a listbox with the required "auto-entry" items.