Paul McNett wrote:
> Carl Karsten wrote:
>> Paul McNett wrote:
>>> Carl Karsten wrote:
>>>> Paul McNett wrote:
>>>>> Carl Karsten wrote:
>>>>>>> Where are these files again? Please don't point me to the list 
>>>>>>> archives, 
>>>>>>> as I can't easily copy/paste code from that webpage.
>>>>>> Oh yeah, that whole html eats whitespace thing...
>>>>>>
>>>>>> hnmm, looks like I botched the file name too. - was called bd1, renamed 
>>>>>> the 
>>>>>> files to cdxml2objDemo1 but didn't change dabo.ui.createForm()
>>>>>>
>>>>>> http://dev.personnelware.com/carl/temp/May31/a/cdxml2objDemo1.tgz
>>>>> Ok, your code runs, and when I click "swap" it swaps. What's the problem?
>>>>>
>>>> I am trying to replace this code in this file:
>>>>
>>>> # cdxml2objDemo1-code.py
>>>> ## *!* ## Dabo Code ID: dButton-dForm
>>>> def onHit(self, evt):
>>>> self.Form.myObj1.swap()
>>>> self.Form.update()
>>>>
>>>> With something in the cdxml file that connects the button to myObj1.swap() 
>>>> in a 
>>>> similar way that the text box's are connected to the attributes.  (once 
>>>> that 
>>>> happens, the displaced .update() can be dealt wtih.)
>>> Well, it appears that Ed hasn't yet added the ability to put a 
>>> OnHit="self.Form.myObj1.swap" in the attributes for the button, but 
>>> that's how you would do it if it were supported. You'd also have to add 
>>> an evt arg to your swap function:
>>>
>>>    def swap(self, evt=None):
>>
>> um, if it hasn't been implemented, then how do you know it would need the 
>> parameter?
> 
> Because that's how event binding works - the callback takes an argument 
> that contains the event object. This *has been* implemented in Dabo for 
> years now. What hasn't been implemented in cdxml is the ability to 
> specify the binding in the constructor. Here, in raw-dabo:
> 
> import dabo
> dabo.ui.loadUI("wx")
> 
> def onButtonHit(evt):
>       print "hit!", evt.EventObject
> 
> app = dabo.App()
> app.setup()
> but = dabo.ui.dButton(app.MainForm, OnHit=onButtonHit, Caption="!")
> app.start()
> 

OK, so it could be implemented without that:

well, first it has to run with it....
     app = dabo.App()
AttributeError: 'module' object has no attribute 'App'

ok, no prob, I can add a d...

it runs, but I see no button.

The plan was to pipe the call through a generic function that strips the event 
argument.

> 
>> 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?


> 
> 
>>> ... 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.)

> 
> 
>> 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?

> 
> 
>> I am somewhat surprised that the wx controls don't do this automatically, 
>> but I 
>> have 0.0 idea what wx controls can/can't do.
> 
> You have to do programming to specify what the wx controls 
> should/shouldn't do. You say that a wx.Button should call 
> dabo.ui.dForm.update(), when wx is completely unaware of the existence 
> of Dabo?

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.)

> 
> 
>>> Until the OnHit works within cdxml, you can put the following at the 
>>> bottom of your main .py file:
>>>
>>> if __name__ == "__main__":
>>>
>>>     app = dabo.dApp(MainFormClass=None)
>>>     app.setup()
>>>     frm = dabo.ui.createForm('cdxml2objDemo1.cdxml')
>>>     frm.myObj1=myClass()
>>> ## - new line below
>>>     frm.but.bindEvent(dabo.dEvents.Hit, frm.myObj1.swap)
>>> ## - new line above
>>>     frm.show()
>>>     app.start()
>>>
>>> ...and then get rid of the -code.py file.
>>>
>> Traceback (most recent call last):
>>    File "cdxml2objDemo1.py", line 31, in ?
>>      frm.but.bindEvent(dabo.dEvents.Hit, frm.myObj1.swap)
>> AttributeError: 'dForm_276318141' object has no attribute 'but'
>>
>> <dButton sizerInfo="{'BorderSides': ['All'], 'Proportion': 0, 'HAlign':
>> 'Center', 'VAlign': 'Middle', 'Border': 0, 'Expand': False}"
>> code-ID="dButton-dForm" designerClass="controlMix" Caption="Swap" />
>>
>> Where did the 'but' in frm.but.bindEvent come from?
> 
> Sorry, forgot to tell you to add RegID="but" in the dButton attributes 
> in the xml.
> 

bingo.

OK, added some code:

    def swap(self, evt):
      self.myAttrib1, self.myAttrib2 = self.myAttrib2, self.myAttrib1
      print evt.EventObject
      code.interact(local=locals())


 >>> dir(evt)
['Application', 'BaseClass', 'BasePrefKey', 'Class', 'Continue', 'EventData', 
'EventObject', 'LogEvents', 'Name', 'Parent', 'PreferenceManager', 
'_EventBindings', '__class__', '__delattr__', '__dict__', '__doc__', 
'__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', 
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__slots__', '__str__', '__weakref__', '_addCodeAsMethod', '_afterInit', 
'_args', '_autoBindEvents', '_baseClass', '_beforeInit', '_call_afterInit', 
'_call_beforeInit', '_call_initProperties', '_continue', '_eventData', 
'_eventObject', '_expandPropStringValue', '_extractKey', 
'_extractKeyWordEventBindings', '_extractKeywordProperties', '_getApplication', 
'_getBaseClass', '_getBasePrefKey', '_getClass', '_getContinue', 
'_getEventBindings', '_getEventData', '_getEventObject', '_getLogEvents', 
'_getName', '_getParent', '_getPreferenceManager', '_initProperties', 
'_insertEventData', '_kwargs', '_logEvent', '_removeAutoBindings', 
'_setBasePrefKey', '_setContinue', '_setEventBindings', '_setEventData', 
'_setEventObject', '_setKwEventBindings', '_setLogEvents', '_setName', 
'_setParent', '_setPreferenceManager', '_uiEvent', 'afterInit', 
'appliesToClass', 'autoBindEvents', 'beforeInit', 'bindEvent', 'bindEvents', 
'doDefault', 'getAbsoluteName', 'getEventList', 'getMethodList', 
'getProperties', 'getPropertyInfo', 'getPropertyList', 'getValidEvents', 
'initEvents', 'initProperties', 'raiseEvent', 'setProperties', 
'setPropertiesFromAtts', 'stop', 'super', 'unBindEvent', 'unbindEvent']

What is the point of the evt parameter?

Is there any way I can use it to get to the form to call .update?
(not that I think that is a good idea, just trying to get a grip on what I can 
do with that parameter.)

> 
>>>> 4. To me it is poor style to have code in the UI, and I thought Ed claimed 
>>>> the 
>>>> x-code.py file was just for the convince of the developer that wanted to 
>>>> edit 
>>>> code using the Dabo CD.
>>> I don't see how you'll get rid of all UI code. I have a ton of UI code 
>>> and don't feel badly about it at all.
>> I think we need to define what this UI code is I want to get rid of.  I see 
>> a 
>> typical 3-tier framework app having 6 places code can live: each of the 3 
>> tiers 
>> will have framework code and 'app developer code.'  For the UI tier, if the 
>> app's UI is not doing anything that the Framework UI code can't handle, then 
>> the 
>> closest thing to code will be config data describing how to setup the 
>> controls 
>> (exactly what is in the .cdxml)
>>
>> 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?

> 
> 
>>>> Assuming this is correct:
>>>>  >>        Just add that line to the object's afterInit() method.
>>>> (which it isn't - object, [event], and .myMethod need to be replaced with 
>>>> the 
>>>> right names, and my object doesn't have an afterInit() method.  but 
>>>> assuming it 
>>>> is correct anyway...)
>>> That's where you edit it from within the -code.py file. You add the 
>>> afterInit() method there.
>>>
>> huh?  I can't even guess what you are talking about.  please elaborate.
> 
> Open up your -code.py file, and after the "def onHit.." block, add:
> 
> def afterInit(self):
>       print "afterInit", self
> 
> Now run the main .py file. You should see:
> afterInit <dButton_9370141723 (baseclass dabo.ui.dButton)>
> 
> 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.

> 
>>>> It seems awkward to have to have the BO layer attach itself to the UI 
>>>> objects, 
>>>> especially when some of the UI object attach themselves to the BO object 
>>>> (like 
>>>> the text box.)  Not to mention that means you can't use that BO object 
>>>> without 
>>>> the UI, unless you write some conditional code, which seems beyond awkward.
>>> I don't understand. How does the BO layer "attach itself" to the UI 
>>> objects? dBizobj isn't even aware that the UI layer exists. 
>> I was assuming I had to add that line to my BO class.  I don't know what 
>> else 
>> "the object's afterInit() method" would refer to.
> 
> I interpreted it to be the button, but whatever, afterInit() is a hook 
> method of all Dabo objects. It is in fact one of the most commonly-used 
> hook methods, and I'm surprised you didn't know about it yet.

I kinda know about it, but in what I posted there just isn't anything 
applicable.  The only 2 things I could think of were  myClass(object) which 
isn't a dabo object, and it sure seemed like the button couldn't get to the 
instance of my class for scope reasons or something.

> 
> 
>> I see you added it to the app's 'main' which is 'better' but still not the 
>> "Don't Repeat Yourself" mentality that I would expect from a framework. 
>> Actually nothing is being repeated... but it seems there is an extra step.  
>> hmm, 
>> maybe it is just the 2 places to set things up: in the .cdxml for text 
>> boxes, 
>> and app's main for the button.  bah, this is just a side effect of the 
>> workaround to an unconfirmed missing feature.  This paragraph may not have 
>> anything to do with reality :)
> 
> 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.

 > I think you had your code the best
> with how you originally posted it earlier today. The ui code was in the 
> ui layer.
> 

The next time this comes up for me I'll take a shot at implementing OnHit in 
the 
cdxml.

>>> I use 
>>> dBizobj without a UI regularly.
>> You also code your UI by hand, which seems to have more features than what 
>> can 
>> be currently be done with .cdxml.
> 
> The cdxml wraps Dabo, not the other way around, so I think this will 
> always be the case.
> 
> 
>>> Understand, I haven't played much with the cdxml-way of doing things, so 
>>> my answers may not be well-informed enough.
>> there's the problem... you are missing out on its potential goodness that 
>> hasn't 
>> been coded yet because you don't need it :)
> 
> Thinking about it, I think I misspoke about OnHit not being implemented 
> yet in cdxml. This is a constructor argument, and the xml doesn't define 
> what goes to the constructor, but what the properties are to be set to. 
> So... this feature is either already implemented in cdxml and I'm not 
> aware of it, or it will not be implemented in cdxml because there are 
> already other ways to do it (doesn't apply).
> 

One thing I have been contemplating is re-writing the code that implements what 
the cdxml describes.  I don't like the "write a big wad of .py and execute it" 
way.  I have a feeling the objects can be instantiated "on the fly" which might 
help.  but not any time soon.

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