jarvisteach / appJar

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

Trying to detect size change #561

Closed tp-arachtingi closed 4 years ago

tp-arachtingi commented 5 years ago

Bug Report

Trying to .bind("", self.sizeChanged ) so I can rewrite a Message if the size of a pane changes. I've been unable to get the object to .bind


Context


Trying to create a simple app with 2 panes, a list and data associated with each entry in the list. If the list on the left pane is changed, the data for the new selection goes on the right pane in a Message. If the app or the panes change size I'd like to redo the message, in case parts of it were lost in the size change.

Expected Behaviour


Following the documentation Configuration -> Registering Other Events I tried to save the pane when I created it:

    self.itemFrame = self.win.panedFrameVertical("Right",sticky="nes")

And later tried to bind it

    self.itemFrame.bind("<Configure>", self.sizeChanged ) 

Which generated the following error:

  File "paneTest3.py", line 58, in __init__
    self.itemFrame.bind("<Configure>", self.sizeChanged )
AttributeError: '_GeneratorContextManager' object has no attribute 'bind'

The other method of getting at the widget:

    panl = self.win.getPanedFrameVertical("Right")
    panl.bind("<Configure>", self.sizeChanged ) 

results in

 appJar:WARNING [Line 56]: Unknown function: <getpanedFrameVertical> Check your spelling, do you need more camelCase?

Sample code, demonstrating the issue



""" To Do - calendar and reminder function """
import sys
import time
import logging 
from appJar import gui

class ToDoApplication :
    """ to do - create and run the GUI, maintain the list of items """

    def define(self):
        """ Define  variables used in this class 

        """
        self.SortTypes = []  # class variable for types of sorts
        self.itemList = []       # main list of ToDoItems 

        self.win = gui(title="To Do") # the main window
        self.win.setSize(600, 600)

        self.listFrame = None   # the pane to put the list in
        self.itemFrame = None # 

    def toolbar(self, btn) :
        if btn == 'Exit' : self.win.stop()
        elif btn == 'Reset' :
           s = createList()
           m = displayItem()

    def  __init__(self) :
        self.define()
        ##Debug code
        self.itemList = {'One':'The first item', 'Two': 'The second item'}
        ##
        self.listFrame = self.win.panedFrame("Left", sticky = "nws")
        with self.listFrame :
            self.win.label("LeftTitle","To Do List", relief="groove", sticky="n")
            self.win.addListBox("TheList" )
            self.win.setListBoxMulti("TheList", multi=False)
            self.win.setListBoxChangeFunction("TheList", self.list_changed)
            self.win.addListItems("TheList",self.itemList.keys())
            aList = list(self.itemList)
            print("keys are "+str(aList))
            self.win.selectListItemAtPos("TheList",0)
            # with panedFrames, all additional panes need to go inside the first one.
            self.itemFrame = self.win.panedFrameVertical("Right",sticky="nes")
            with self.itemFrame :
                self.win.label("RightLabel", "To Do Item" )
                self.win.addEmptyMessage("TheItem")
                # get key of selected item
                self.list_changed()
        # set actions for changing sizes

        #panl = self.win.getpanedFrameVertical("Right")
        #panl.bind("<Configure>", self.sizeChanged ) 
        self.itemFrame.bind("<Configure>", self.sizeChanged ) 
        #self.listFrame.bind("<Configure>", self.sizeChanged ) 
        print("We got here at least")
        self.win.addMenuList("File", ("Reset","Exit"), self.processButton)

        self.win.go()

    def list_changed(self) :
        """ executed when different To Do item is selected """
        print("List changed")
        key = self.win.getListBox("TheList")[0]
        # append key, \n, and value of item
        rightContents = key + '\n\n' + self.itemList[key] 
        self.win.clearMessage("TheItem")
        self.win.setMessage("TheItem", rightContents )

    def updateList(self):
        """eventually, will handing sorting by priority, reminders, active, etc """
        aList = self.itemList.keys()
        self.win.addListItems("TheList", aList )
        self.win.selectListItemAtPos("TheList",0)
        self.listChanged() 

    def clear_list(self):
        self.win.clearListBox("TheList")
        self.win.clearMessage("TheItem")

    def processButton(self, btn) :
        print("Button "+btn+" pressed.")

    def sizeChanged(self,event) :
        self.clear_list()
        self.updateList()

ToDoApplication()

What steps are needed to reproduce the bug


Just run the code python paneTest3.py

Version Information


appJar: 0.93.0 Python: 3.6.3 TCL: 8.6, TK: 8.6 Platform: Windows pid: 59636 locale: en_US

jarvisteach commented 5 years ago

Hi @tp-arachtingi - this definitely sounds like a useful feature.

There is already a built in .setChangeFunction() and that should support changes to panedFrames, I'll have to do some digging...

jarvisteach commented 5 years ago

I've added basic support for this, by calling: app.setPanedFrameChangeFunction('pane', change) you can register the change function to be called when the pane is resized.

Still need to test this against all the different configurations, and work out if it should be registered against a specific/all panes - but it's calling the function!

jarvisteach commented 4 years ago

Closing as feature implemented, will wait for feedback on usage.