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

[FEATURE] provide access to callee in cmd event #48

Open
mrx23dot opened this issue Nov 4, 2024 · 13 comments
Open

[FEATURE] provide access to callee in cmd event #48

mrx23dot opened this issue Nov 4, 2024 · 13 comments
Labels
enhancement New feature or request

Comments

@mrx23dot
Copy link

mrx23dot commented Nov 4, 2024

I define a simple command function
def ui_evt_save(event=None):
wire it in into a button,
but when it triggers the event parameter is still None,

I would need a way to get the caller instance (e.g. multiple buttons wired into one cmd handler)

def ui_evt_save(event=None):
   event.callee.setSomething()
@mrx23dot mrx23dot added the enhancement New feature or request label Nov 4, 2024
@ObaraEmmanuel
Copy link
Owner

There are two ways to add callback functions

  1. Using the Event pane which will bind an event for you
  2. Using a widget's command attribute

The latter does not pass an event object to the callback and that's just how Tkinter works. However, passing custom parameters to a callback is a feature that exists on the master branch. It will be in the next release. To pass a parameter to callback, just set the command attribute as the call to that function along with your desired arguments e.g ui_evt_save(event=4) or ui_evt_save(4). The argument can be anything but it has to be in scope of whatever you pass to connect_callbacks function.

@mrx23dot
Copy link
Author

mrx23dot commented Nov 5, 2024

Couldn't the framework just add a 2nd paramater automatically?

ui_evt_save(event=None, instance=None):
app.passInstance = True

this would be backward compatible with existing code (not breaking event parameter), otherwise it is just another thing that we have to keep in sync with the UI.

or a wrapper object into event parameter that contains the instance.

ui_evt_save(event=None):
   if isinstance(event, widgetEvent)
   txt = event.instance.get()

@ObaraEmmanuel
Copy link
Owner

If you want the event object, bind an event using the Event pane instead of using the command attribute.

image

I will try to see if it is possible to pass an instance to a command callback.

@mrx23dot
Copy link
Author

mrx23dot commented Nov 8, 2024

Overloading 'command' wouldn't be strange to tkinter, see the callback of r scrollbar, it can have 2 or 3 parameters depending how you clicked it.

@ObaraEmmanuel
Copy link
Owner

ObaraEmmanuel commented Nov 9, 2024

I have added a way to get the widget passed as an argument to both the command and Event pane methods. Given a function/method shown below:

def ui_evt_save(callee):
    print(callee)

you can set the command to ::ui_evt_save and the preceeding double-colon would indicate to the loader that the widget should be passed as the first argument. You can pass other argument using the usual call format ::ui_evt_save(20, 50) and the widget will always be the first argument

def ui_evt_save(callee, arg1, arg2):
    print(callee, arg1, arg2) # <widget> 20 50

@mrx23dot
Copy link
Author

mrx23dot commented Nov 11, 2024

Master head has a msg:
9ddf030

formation-studio
ERROR:root:Failed to load external module customtkinter.py: module 'customtkinter' has no attribute 'CTkBaseClass'

also when I try to open my xml in it, it just exits without reason.

but from code I can still open the xml
from formation.loader import AppBuilder

So I can't test it yet.

@ObaraEmmanuel
Copy link
Owner

I hope you were not using any customtkinter stuff. It is super buggy. Can you send over the offending XML.

@mrx23dot
Copy link
Author

mrx23dot commented Nov 11, 2024

Don't even know what that is :D
with this one it exits, before the update it worked:
layout.zip
exception trace would be nice, to see where it fails, or on which line.

You could keep a collection of xml files and run them from cli to see if they still work with the new version, like a regression test.

@ObaraEmmanuel
Copy link
Owner

I already have very comprehensive tests so I can catch any major regressions. The XML seems to be working on my end. What exactly is exiting without reason?

@mrx23dot
Copy link
Author

mrx23dot commented Nov 11, 2024

pip uninstall formation-studio
pip3 install git+https://github.com/ObaraEmmanuel/Formation.git@master
// commit 9ddf0303980cf271bbedf5c34eaed40232607abb
formation-studio
open layout.xml as usual

it simply exits, on console it waits an extra enter from me,
image

Something has to do with the themes, after I changed every

tkinter.ttk.Button to tkinter.Button
tkinter.ttk.Combobox to tkinter.Combobox

it opens. Although I still have tkinter.ttk. left.

so this one works for me
layout_ok.zip

I'm on Windows 10 (don't judge).

Not sure if it helps but this is the new dropdown I see
image

My Windows theme looks like
image

@ObaraEmmanuel
Copy link
Owner

I am unable to reproduce the issue. Might be related to the fact that you are installing the master branch from git so the entrypoints are not being configured properly. For now, just try to test the callback feature.

@mrx23dot
Copy link
Author

Weird, it also works on Windows 7.
Can you just not capture any exceptions? Then it will show up on console.
I will test the callbacks.

@mrx23dot
Copy link
Author

callee works great! Thank you!
Will also need documenting, since it's not evident,
could also mix the two:

def ui_evt_onEnter(calleeOrEvt=None): 
  if isinstance(calleeOrEvt, tk.Event):
     # event
  else:
     # element

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants