Paul McNett wrote:
> Carl Karsten wrote:
>> Paul McNett wrote:
>>> Carl Karsten wrote:
>>>> Paul McNett wrote:
>>>> it runs, but I see no button.
>>> Forgot that there's a platform inconsistency there. It works on Mac, BTW.
>> eh!?  Is anyone cataloging the platform inconsistencies?  I think I am now 
>> aware 
>> of 3,
>>
>> Any chance of a linux ver?
> 
> import dabo
> dabo.ui.loadUI("wx")
> 
> def onButtonHit(evt):
>          print "hit!", evt.EventObject
> 
> app = dabo.dApp(MainFormClass=None)
> app.setup()
> frm = dabo.ui.dForm()
> but = dabo.ui.dButton(frm, OnHit=onButtonHit, Caption="!")
> frm.show()
> app.start()
> 

hit! <dButton (baseclass dabo.ui.dButton)>

yay!  thanks.

> 
>>>> The plan was to pipe the call through a generic function that strips the 
>>>> event 
>>>> argument.
>>> The event argument is kind of important; I never thought of trying to 
>>> strip it out. Good luck with that. :)
>>>
>> So far the only use I have seen for the event argument is to identify what 
>> object raised the event, which can be dealt with by having each event call a 
>> unique function.  I am not sure which is better :)
>>
>> current way (kinda):
>> UI1 calls OnHitX(1)
>> UI2 calls OnHitX(2)
>> UI3 calls OnHitX(3)
>>
>> Without event arg:
>> UI1 calls OnHit1()
>> UI2 calls OnHit2()
>> UI3 calls OnHit3()
>>
>> def OnHitX(objID): pass
>> def OnHit1(): OnHitX(1)
>> def OnHit2(): OnHitX(2)
>> def OnHit3(): OnHitX(3)
> 
> I still don't get it. Why bang your head with this stuff when we've 
> already banged our heads for you? 

To make dabo better.

Like when I bumped into some class's init requiring a parameter, the initial 
response was "pass None" but then a few days later the code was changed making 
it optional.

 > You go down this route and you'll
 > severly limit the utility of event handling, I think.

At this point I am exploring, so I have no clear route in mind.  What I am 
currently finding is a small stream between the dabo wrapped UI controls and 
the 
BO.  so far it seems everyone that comes along has to wade across it.  no 
biggie, but maybe a bridge would be nice.


> 
>>>>>> or, why does it need that parameter?
>>>>> Because that's how event binding works, the callback function takes an 
>>>>> event argument.
>>>> um, you may as well say "because it is written that way."  The code you 
>>>> posted 
>>>> doesn't use the parameter for anything useful.  I can see the thought that 
>>>> it 
>>>> might be handy, but has anyone actually used it?
>>> Occasionally it is useful, 
>> That defines everything in a computer, but I sure don't everything passed :)
>>
>> I know in VFE I often wished that my BO code had a reference to the UI, but 
>> right now I can't really think of a good reason.
> 
> Why do you wish your BO had a reference to the UI? You aren't suggesting 
> that event handling callback functions are part of the BO layer, are you?

apparently you missed the part where I said "I can't really think of a good 
reason."

My guess it to work around something.  VFP has plenty of things that need 
working around.  VFE did a pretty good job of dealing with them, but it formed 
what I lovingly called the workaround web which was pretty easy to get tangled 
up in.

> 
> VFP shielded us from realizing that when we wrote code in the "init 
> event", we were actually just writing a normal method that was called 
> when the init event was emitted. IOW, VFP set up the callback methods 
> for us.
> 
> We could have gone that route, but I felt that it would be too limiting, 
> and wasteful to define a bunch of callback functions that would only 
> rarely be called. So I chose to leave it up to the developer to define 
> their own event bindings, the ones that they want to respond to.

So the Dabo code is really on the construction side, not the .. um.. event loop 
part?  I think I get it, but am not sure what words to use to describe what I 
think I get... ouch...

limiting - not sure I get how it would limit anything.

and wasteful - waste what?  memory? performance?  your time?  app developers 
time?

Here is what I am conjuring up:  a different flavor of .bindEvent() that causes 
some dabo side code to be bound to the wx object, then the dabo code calls the 
app code.  This probably sounds as crazy as an air ship sounded to a viking.  
it 
may very well be.

> 
> 
>>  > usually my code doesn't need it, but as I
>>> said above it is somewhat important to keep alive because of the way wx 
>>> events work. Once that event object goes out of scope, wx takes over 
>>> again and propagates it up a level. In order to keep things working 
>>> sanely, you really need to accept the evt arg even if you don't actually 
>>> use it.
>> When you say "out of scope" you really mean released/destroyed right?
>>
>> otherwise this would not work:
>>
>> def onButtonHit(evt):
>>          foo()
>>          return
>>
>> def foo():
>>          print "hit!"
> 
> I really meant "when the callstack falls back to zero". That event 
> object gets passed down the chain until somebody handles it.
> 
> 
>> Which means the evt arg could be kept alive in some framework code.
> 
> Yes it could, and it already is (by passing it down the chain).
> 
> 
>>>>>>> ... and yes, you do need to explicitly call update(): how else do you 
>>>>>>> expect Dabo to know that your object's attribute values have changed?
>>>>>> Few things come to mind:
>>>>>>
>>>>>> Given that most button clicks cause something to happen that requires 
>>>>>> the form 
>>>>>> to be updated, build it into the button.  If that causes a problem, add 
>>>>>> an 
>>>>>> switch to turn it off.
>>>>> You are saying that every time any button on the form gets clicked, call 
>>>>> but.Form.update()?
>>>> yes.  given my given, seems reasonable.  (course I am not sure how valid 
>>>> my 
>>>> given is.)
>>> Is it too much to ask the end programmer to make some explicit calls now 
>>> and then? 
>> Yes, if the framework can take care of it.  I pretty much don't want code in 
>> my 
>>   app that could be coded in the framework.
> 
> So why don't you code a framework with a single function:
> 
> carlFramework.DWIM()
> ;)

Sounds good to me.  I hate to say it, but Access has (had?) some usefulness in 
the world.  Three are cases where all you need is a pretty UI to a DB. 
basically what AppWiz generates.  If the only thing the app developer has to 
offer is the layout, and maybe some RI lookup stuff, I don't see much/any code 
needing to be written.

> 
> 
>> The Dabo framework has no idea how much processing is going to
>>> be triggered by a call to update(). Could be minimal, but could be huge. 
>>> I, for one, would like to have control over when it is called.
>>   "If that causes a problem, add an switch to turn it off."
>>
>> How many of your button's don't result in a .update()?
> 
> Very few result in an update of the entire form. Quite a few will say 
> things like 'self.Form.txtCustomerName.update()' though.

ah, for some reason I didn't think that was an option.

> 
> Hey you know what? Let's just make a timer that calls form.update() 
> every 100 ms. That would be convenient and now nobody will ever need to 
> call update() again!

Why not?  my CPU has 2 things to do: deal with my input (keyboard/mouse) and 
update my screen.  im guessing I can use .001% of it if I wiggle my mouse 
really 
fast.   Oh yeah, too many other people have taken that attitude, and now things 
like "check for usb device" and "update video" bog down a screaming cpu.

> 
> 
>>>>>> Create a class that is specifically for storing values that might be 
>>>>>> displayed 
>>>>>> using Dabo UI objects.  When the Dabo UI object is bound to the 'value 
>>>>>> object', 
>>>>>> it registers itself.  Now the value object has a reference to all the UI 
>>>>>> objects 
>>>>>> that are bound to it. When the value object's value is updated, it calls 
>>>>>> the 
>>>>>> .update() of the UI objects bound to it.  This may sound like a bit of 
>>>>>> overhead 
>>>>>> that will slow things down, but I bet it is faster than calling 
>>>>>> .update().
>>>>> FWIW, there is just such a device already: binding controls to a 
>>>>> dBizobj, and registering the bizobj with the dForm: whenever the bizobj 
>>>>> field value changes, the form calls update() automatically.
>>>> um, make up your mind...
>>>>
>>>> I'm guessing you meant .update() needed to be called somehow, and that I 
>>>> needed 
>>>> to do something to make that happen.  sounds like one thing that could be 
>>>> done 
>>>> is change
>>>> class myClass(object):
>>>> to
>>>> class myClass(dabo.biz.dBizobj):
>>>> and register the bizobj with the dForm -
>>>> which sounds pretty good.  course I have no idea how to register it with 
>>>> the 
>>>> form.  shouldn't this be something that happens when the UI control is 
>>>> bound?
>>> Ok, ok... it is when the dForm recognizes that the record pointer has 
>>> moved, or that a requery has happened, that update() is called 
>>> automatically. The dForm methods like next(), prior(), new(), delete(), 
>>> requery() all result in a update() being called. It only relies on a 
>>> bizobj being present because those form methods assume that a bizobj is 
>>> present.
>>>
>>> Remember, we designed Dabo assuming a database, mediated by a dBizobj, 
>>> and a form mediating the dBizobj calls.
>> I'm starting to think the n-tier thing didn't get done as well as it could.
> 
> Does anything ever get done as well as it could? Come on, name one thing.

didn't you say the sample I posted was as good as it could be? :)

> 
> 
>> otoh, I may be trying to take some short cuts and screwing things up.
> 
> These never-ending emails are short cuts? :)

I think I have learned more in this thread than I did spelunking the code for a 
week.

> 
> 
>>>> No, I am saying that the wx text box should update itself (just the text 
>>>> box) 
>>>> when the value it is bound to changes.  (again, I have no clue how 
>>>> feasible that 
>>>> is.)
>>> wx has no notion of data binding at all. To set the value, you call 
>>> wx.TextCtrl.SetValue(), and to get the value, you call GetValue(). Data 
>>> binding is one of the things Dabo adds to the picture.
>>>
>>>
>> Oh... see, your comment about learning raw dabo could be extended to 
>> learning 
>> wxPyton, and on to pure wx - none of witch I have enough desire to do :)
> 
> Each layer of the picture aims to shield you from having to know more 
> than you need to know to get things done. However, I've generally found 
> that it is beneficial to be comfortable with the next layer down from 
> the layer you are trying to work with.
> 
> It is one of the reasons I appreciate open source so much.

I like the option of investigating, but I don't think it is a good place to 
start.  and from a dabo-user point of view, the next layer down is dabo, not wx.

> 
>>>> What is the point of the evt parameter?
>>> 1) It gives you a hook into the event propagation process. Call 
>>> evt.stop() and no other handlers bound to that event will be called. 
>>> This includes base native behavior.
>> I think this caused something to click:
>>
>> frm.but.bindEvent(dabo.dEvents.Hit, frm.myObj1.swap)
>>
>> This is connecting the wx event to frm.myObj1.swap - no Dabo code will be 
>> run, 
>> right?
> 
> Wrong. This is connecting the Dabo event to frm.myObj1.swap. Dabo code 
> will be run to wrap the wx event and pass that wrapped event (an 
> instance of dEvent) to the event callback functions. The raw wx event 
> does get passed as well though (wrapped up in the dEvent).

huh.  OK, I need to study the code before go building any bridges.

> 
> 
>> If so, then I totally see the point in "all of this."  Not sure I like it, 
>> but I 
>> sure don't know enough to have an opinion that matters :)
> 
> Perhaps you should go try to code some event handling in raw wxPython 
> for a while. Then you may start to   the simplifications we've 
> made. Get over the evt argument: it is a useful argument easily ignored.
> 

Perhaps I should hit myself with a hammer 5 times a day, then I will appreciate 
how better it is when I only do it once a day. :)

> 
>>> 2) If you have a generic event handler that could receive events from 
>>> several objects, you may well need to know what object emitted the 
>>> event, so you'd get that reference using evt.EventObject.
>> I can shoot that one down in a heartbeat: Don't have a generic event handler.
>>
>> That reason could be applied to every single function: you need to pass a 
>> reference of the calling object in case the function needs to know who 
>> called 
>> it.  no, that's dumb.
> 
> Remember, it isn't the object that calls the event callback function: 
> it's the event manager that does that.

I would love to remember that, but I don't know what that is.

Is there a line of code that you can point me to that "calls the event callback 
function" ?  (only if it is dabo or wxPython, or some other python code.  if 
that gets into wx C land, forget it.)

> 
> 
>>> 3) Some data is included with the event that may or may not otherwise be 
>>> available from the object directly, such as the exact position of the 
>>> mouse on the screen when the event occurred (mouse could be in a 
>>> completely different place by the time our event handler responds to the 
>>> event), what modifier keys were down when the event occurred, what list 
>>> item was selected when the event occurred, etc. etc.
>>>
>> yeah, I'm seeing that whatever gets called is the first place any 'app side' 
>> code can run, maybe even framework code.  I may actually be breaking n-tier 
>> rules by having the wx object call my BO method - (n>3 in this case.  i'm 
>> seeing 
>> wx in it's own tier, above some python UI code (mix of dabo and app), above 
>> the 
>> BO code.
> 
> You should not be putting your event callback functions for ui-generated 
> events inside your biz layer.
> 
> 

Which is why I am thinking there needs to be a framework thing between wx and 
my 
BO, just like if I have no BO, there is some framework code between the UI and 
my data.


>>>> Is there any way I can use it to get to the form to call .update?
>>> No, and I don't understand why you are resisting just calling 
>>> self.Form.update() when needed.
>> cuz self is my BO, which has no Form or any other reference to the form.
> 
> Bingo, your event handler is in the wrong layer.
> 

see, I can be learned.

> 
>>>>>> If the app needs some loopy UI gizmo like "increase the font every time 
>>>>>> the 
>>>>>> mouse passes over it" then I need to write some UI code.
>>>>> Most UI code is layout code, yes. But also event handlers for acting 
>>>>> when the user clicks a button or something.
>>>> so tying the button to some method code, and the method code isn't UI 
>>>> specific, 
>>>> right?
>>> Well, it receives the event parameter, which is ui specific. But 
>>> typically my event handler will call some bizobj method to actually do 
>>> the logical processing of whatever needs to happen, and get the return 
>>> value to work with at the UI level.
>> right.
>>
>> So typically you don't need the event parameter.  same here, and I bet same 
>> with 
>> many other developers.  May want to consider a framework feature that deals 
>> with 
>> this so the app developers can concentrate on there app an not this extra 
>> parameter.
> 
> Somebody that cares passionately about this issue (non-issue in my mind) 
> can see what they can come up with. I like seeing the evt arg, as it is 
> a signature saying "I'm an event handler".
> 
> Let me guess, you'd like to delve into Python to see about removing the 
> 'self' arg, too.

I actually pondered that :)

What I came up with:  the way it is implemented is easier to parse and 
document. 
  VFP's 'this' is a keyword.  I kinda like the 'one less keyword' way.

But... what I don't like is the way Python slides in the parameter.  I have yet 
to see why it couldn't have just been left up to the person making the call to 
include the object reference as part of the call if it was going to be used. 
But I do have a feeling for why, and given that I have 0.0 chance of having an 
impact on 'that' I dropped it.

> 
> 
>> VFE had a button with a prop that contained the name of a method to call.  
>> at 
>> run time, when the button was clicked, it magically figured out what object 
>> had 
>> the method.  it was handy, but I did not like the way the magic was 
>> implemented 
>> - cuz sometimes I had to help it, and i still wonder if it was worth the 
>> hassle 
>> it caused.
> 
> So you are still proposing adding more magic to Dabo?

no!  I use magic to describe things I don't like.


> 
>>>>> Now put whatever code Ed wanted you to put there in that method. It gets 
>>>>> called after the button's init cycle is complete.
>>>> Ok, that seems plausible.  kinda goes against the goal of eliminating the 
>>>> -code.py file.
>>> That was your goal, not mine. Eliminating the -code.py file is akin to 
>>> confining yourself to writing no code at all in the ui level. A bit 
>>> limiting, to say the least.
>> If I have no special (non framework provided) UI needs, I should not be 
>> writing 
>> UI code.  After using a framework for 10 years you may get on board with 
>> this 
>> concept :)
> 
> You don't need to position your buttons and define what actions need to 
> be taken in response to things like button clicks?

I do, but via a config file (like the cdxml), not code.

> 
> 
>>>>> I think maybe you should take cdxml out of the picture for a while. Get 
>>>>> comfy with raw-dabo. You'll have a better understanding and appreciation 
>>>>> for what cdxml brings to the table. 
>>>> I can see the value, but I am skeptical it is worth the time.  I think my 
>>>> biggest problem is knowing what limitations the cdxml imposes.
>>> It imposes some limits, sure. Not a lot of limits, I don't think. It's 
>>> biggest benefit is saving time laying out the controls. But it is in 
>>> active flux, and always changing, while the underlying Dabo is actually 
>>> quite stable. In the future I think people could start with cdxml and be 
>>> just fine; currently, I think everyone should spend the time to learn 
>>> the base Dabo way to do things first. But that's just me, I think.
>> In the end, I was able to use the CD much more effectively than trying to do 
>> it 
>> by hand.  The stuff I did by hand looked like total crap.  With the CD and 
>> less 
>> time I created a UI that was good enough.
>>
>> BTW, thanks for waling me though this.  I think I learned something.
> 
> You are welcome. You just owe me a keg of Anchor Steam by now is all. :)
> 


Only one?  you are too kind.

Carl K


_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users
Searchable Archives: http://leafe.com/archives/search/dabo-users
This message: http://leafe.com/archives/byMID/dabo-users/[EMAIL PROTECTED]

Reply via email to