From: Patrick K. O'B. <po...@or...> - 2001-09-02 16:41:24
|
Because I'm a big fan of straightforward dot syntax, I've been helping Kevin and company with some of the "magic" aspects in python that allow code like the following in PythonCard: >>> comp.button1.font.size = 10 So far we have focused on exposing as many attributes as possible through dot syntax. At some point, however, we need to focus on which attributes *should* be exposed. To help us all keep in mind the fact that good OO design would have us limit the amount of exposure we give to an object, I'd like to start a discussion by recommending the following article by Allen Holub. If you like this one, he has several others on his website. Let me know what you think about this article on "What Is An Object" and what it might mean for PythonCard: http://www.holub.com/goodies/what_is_an_object.html --- Patrick K. O'Brien Orbtech (http://www.orbtech.com) "I am, therefore I think." |
From: Kevin A. <al...@se...> - 2001-09-02 17:46:24
|
> From: Patrick K. O'Brien > > So far we have focused on exposing as many attributes as possible through > dot syntax. At some point, however, we need to focus on which attributes > *should* be exposed. To help us all keep in mind the fact that good OO > design would have us limit the amount of exposure we give to an > object, I'd > like to start a discussion by recommending the following article by Allen > Holub. If you like this one, he has several others on his website. Let me > know what you think about this article on "What Is An Object" and what it > might mean for PythonCard: > > http://www.holub.com/goodies/what_is_an_object.html This is a good start for object-oriented issues, but I'm sure a lot of the OOP gurus lurking on the list can suggest some other ones. A lot of this article focuses on problems that arise due to the use of explicit types such as using an int versus a float which is always a problem with static typed languages like C. While we have some of these issues ourselves, Python reduces a lot of the type worries. For example, it is legal to specify a backgroundColor or foregroundColor as an rgb tuple (0, 0, 255), a named string "blue" or a hex string "#0000FF". Frankly, that makes a lot of OO programmers cringe, but I think it is easier for the user (programmer). Obviously, there are still exposed types there, and in C++ and Java you could do something like that too to support multiple argument types, so I guess my point isn't as relevant as it looked when I started this paragraph. :) Ah, now that feels like the OOP discussions I'm used to. The other part of the article hints at model-view-controller issues, but then goes in a direction that I find simply stupid, which is that every class has to know how to "draw yourself in this window" That is simply not doable, let alone maintainable, there are too many possibilities, so again you end up with a system that doesn't work except within extremely limited possibilities. ka |
From: Patrick K. O'B. <po...@or...> - 2001-09-02 17:48:32
|
Two more interesting articles: http://www.javaworld.com/javaworld/jw-07-1999/jw-07-toolbox.html http://www.javaworld.com/javaworld/jw-09-1999/jw-09-toolbox.html Don't let the java focus scare you. --- Patrick K. O'Brien Orbtech (http://www.orbtech.com) "I am, therefore I think." -----Original Message----- From: pyt...@li... [mailto:pyt...@li...]On Behalf Of Patrick K. O'Brien Sent: Sunday, September 02, 2001 11:45 AM To: Pythoncard Subject: [Pythoncard-users] Dot syntax and the risk of overexposure Because I'm a big fan of straightforward dot syntax, I've been helping Kevin and company with some of the "magic" aspects in python that allow code like the following in PythonCard: >>> comp.button1.font.size = 10 So far we have focused on exposing as many attributes as possible through dot syntax. At some point, however, we need to focus on which attributes *should* be exposed. To help us all keep in mind the fact that good OO design would have us limit the amount of exposure we give to an object, I'd like to start a discussion by recommending the following article by Allen Holub. If you like this one, he has several others on his website. Let me know what you think about this article on "What Is An Object" and what it might mean for PythonCard: http://www.holub.com/goodies/what_is_an_object.html --- Patrick K. O'Brien Orbtech (http://www.orbtech.com) "I am, therefore I think." _______________________________________________ Pythoncard-users mailing list Pyt...@li... https://lists.sourceforge.net/lists/listinfo/pythoncard-users |
From: Ronald D S. <rd...@ea...> - 2001-09-02 20:44:41
|
1. The resource editor and property editor are awesome! They work so simply that I can already add widgets and change properties easier than with any other program I have ever tried. 2. Where is the best description of the commands available for each widget type? 3. I like dot notation, for what its worth. 4. What is the best way to tie widget actions or commnads to Python logic or formulae? Maybe this isn't implemented yet, if so, how do you think it will work in future? Ron Stephens |
From: Kevin A. <al...@se...> - 2001-09-02 20:56:09
|
> From: Ronald D Stephens > > 1. The resource editor and property editor are awesome! They work > so simply that I can already add widgets and change properties > easier than with any other program I have ever tried. I really dislike the UI for the Property Editor and want to recode it so that it presents a grid of properties and values like VB, Boa, and most other tools that let you change the attributes of widgets. However, the one we have today is working, so it keeps getting knocked down on my priority list. > 2. Where is the best description of the commands available for > each widget type? Events and attributes for each widget are described in spec.py. widget.py has the full method list for each widget. There is no standalone documenation for either widget attributes or events yet. Initial attempts using pydoc and happydoc didn't work so well. Documentation continues to be high on my priority list, so I'll get into again once the labor day weekend is over and the guests staying with us are gone. > 3. I like dot notation, for what its worth. Yes, Neil and Patrick have done a good thing. > 4. What is the best way to tie widget actions or commnads to > Python logic or formulae? Maybe this isn't implemented yet, if so, how > do you think it will work in future? I'm not sure what you're asking here, can you go into more depth, provide an example of what you're trying to do, etc.? ka |
From: Neil H. <ne...@sc...> - 2001-09-02 21:29:22
|
> I really dislike the UI for the Property Editor and want to recode it so > that it presents a grid of properties and values like VB, Boa, and most > other tools that let you change the attributes of widgets. However, the one > we have today is working, so it keeps getting knocked down on my priority > list. On Linux/X/GTK+ the property editor often moves when you click on it making the UI quite difficult to use. The default font sizes are also very small there. I'm not sure which code is responsible for this but even after trying to do the right thing in Scintilla/SciTE, the setup for GTK+ has to choose 12 point to be similar to 10 point on Windows. Neil |
From: Kevin A. <al...@se...> - 2001-09-02 21:52:21
|
> From: Neil Hodgson > > > I really dislike the UI for the Property Editor and want to recode it so > > that it presents a grid of properties and values like VB, Boa, and most > > other tools that let you change the attributes of widgets. However, the > one > > we have today is working, so it keeps getting knocked down on > my priority > > list. > > On Linux/X/GTK+ the property editor often moves when you click on it > making the UI quite difficult to use. The default font sizes are also very > small there. I'm not sure which code is responsible for this but > even after > trying to do the right thing in Scintilla/SciTE, the setup for GTK+ has to > choose 12 point to be similar to 10 point on Windows. I'm pretty sure the window or panel jumping is a known Linux bug with wxPython, but I'm not sure if it is a specific to a particular version or whether it is fixed in the upcoming version 2.3.2. Rowland mentioned this when I first did the original proof. Here's an email from 2001-07-02: Kevin: My friend Rowland says that under Linux the window jumps down 20 pixels every time he hides/shows the window. Robin: This sounds like a bug in wxWindows that was just fixed today according to the CVS update messages. All of the 'Debug' windows are coded in wxPython directly, they are outside the PythonCard framework and event model, so that they don't impact the base application. Consequently, They can be coded with sizers and there could be some additional options for the default fonts or they could just pick up whatever the underlying default scheme or theme indicates. Perhaps you are already doing something like that for your code that we could apply? ka |
From: Ronald D S. <rd...@ea...> - 2001-09-02 22:05:23
|
> 4. What is the best way to tie widget actions or commnads to > > Python logic or formulae? Maybe this isn't implemented yet, if so, how > > do you think it will work in future? > > I'm not sure what you're asking here, can you go into more depth, provide an > example of what you're trying to do, etc.? > > ka I guess what I have in mind is this. I want to set up a collection of several sliders, to use as data input devices. Then, I need to do a calculation on the data, and send the output to a results slider. In other words, if S1 thorugh S5 are the input sliders, I need to do something like (S1 +5(S2) + 3(S3) -4(S4))/S5 and then output the result to an output slider. |
From: Kevin A. <al...@se...> - 2001-09-02 22:43:40
|
> From: Ronald D Stephens > > I guess what I have in mind is this. I want to set up a > collection of several sliders, to use as data input devices. Then, I need > to do a calculation on the data, and send the output to a results > slider. In other words, if S1 thorugh S5 are the input sliders, I > need to do something like > > (S1 +5(S2) + 3(S3) -4(S4))/S5 > > and then output the result to an output slider. Okay, this is a very specific problem, which I'll go into below. In general, you'll have to decide whether to use the widgets as data storage or whether they simply represent a 'view' of some internal variables you keep track of yourself. The samples have example of doing both. You want to use the 'value' attribute of the slider. For example, if you have a a slider with a name of 'sld1' then: self.components.sld1.value will give you an integer that you can use in your calculation. Then when you have your calculated value, do something like: def displayResult(self, result): self.components.sldResult.value = int(result) I would wrap up the calculation in its own method (as an example I'll just refer to it as 'calcResult'), which returns your result. You can have the result slider dynamically changed by responding to a 'select' event for all the sliders. def on_sld1_select(self, target, event): result = self.calcResult() self.displayResult(result) You would need a separate handler for each slider, so rather than do that, you could use a background handler. I remember you asking about background handlers before. Your background has a name, I'll assume it is 'bgMin' like the 'minimal.py' sample and that sliders one through five are named like the one above. def on_bgMin_select(self, target, event): name = target.name if name[:3] == 'sld' and int(name[3:]) in [1,2,3,4,5]: self.displayResult(self.calcResult()) There are other ways to solve your problem, but something like that should work. Your result slider will change dynamically as you drag sliders one through five. You'll want to initialize all your sliders with appropriate min/mix values, but you can change these dynamically while the program is running by setting the 'min' and 'max' attributes or using the 'setRange(min, max) method. If you later decide that you also want to display the results and inputs numerically as well as via a slider you can add StaticText or TextField (with 'editable' = 0) widgets that are updated as the slider values change. ka |
From: Ronald D S. <rd...@ea...> - 2001-09-03 00:58:45
|
PythonCard file, aaa.py #!/usr/bin/python """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2001/08/06 20:32:41 $" """ import PythonCardPrototype from PythonCardPrototype.loader import configOptions import os, sys class aaa(PythonCardPrototype.model.Background): def on_menuFileExit_select(self, menu, event): self.Close() def displayResult(self,result): self.components.sldResult.value=int(result) def on_sld1_select(self,target,event): result = self.calcResult() self.displayResult(result) def on_bgMin_select(self,target,event): name = target.name if name[:3] == 'sld' and int(name[:3]) in [1,2,3,4]: self.displayResult(self.calcResult()) if __name__ == '__main__': base, ext = os.path.splitext(sys.argv[0]) filename = base + ".rsrc.py" configOptions() app = PythonCardPrototype.model.PythonCardApp(filename) app.MainLoop() __________________________________________________________ ________________________________________________________ aaa.rsrc.py {'stack':{'type':'Stack', 'name':'Template', 'title':'Template Resource', 'position':(66, 0), 'size':(500, 600), 'backgrounds': [ {'type':'Background', 'file':'template.py', 'classname':'Template', 'name':'bgTemplate', 'components': [ {'type':'Slider', 'name':'sldResult', 'position':(6, 91), 'size':(200, 20), 'layout':'horizontal', 'max':400, 'min':1, 'value':55, }, {'type':'Slider', 'name':'sld1', 'position':(9, 160), 'size':(200, 20), 'layout':'horizontal', 'max':100, 'min':1, 'value':55, }, {'type':'Slider', 'name':'sld2', 'position':(10, 295), 'size':(200, 20), 'layout':'horizontal', 'max':100, 'min':1, 'value':64, }, {'type':'Slider', 'name':'sld3', 'position':(11, 227), 'size':(200, 20), 'layout':'horizontal', 'max':100, 'min':1, 'value':1, }, {'type':'Slider', 'name':'sld4', 'position':(10, 9), 'size':(200, 20), 'layout':'horizontal', 'max':100, 'min':1, 'value':28, }, ] # end components } # end background ] # end backgrounds } } attmpt to run results::: unable to load template.py Traceback (most recent call last): File "C:/Python21/PythonCardPrototype/samples/minimal/aaa.py", line 38, in ? app = PythonCardPrototype.model.PythonCardApp(filename) File "C:\PYTHON21\PythonCardPrototype\model.py", line 125, in __init__ clazz = module.__dict__[ bg.classname ] UnboundLocalError: local variable 'module' referenced before assignment Look, I promise to stop wasting your time soon... |
From: Andy T. <an...@cr...> - 2001-09-03 01:36:11
|
Morning all, I take a couple of days away from e-mail and the list goes bananas. Maybe I should take a couple of weeks off ;-) Anyway, Ron, you are almost there, I've annotated the lines you need to change; Ronald D Stephens wrote: > PythonCard file, aaa.py > > #!/usr/bin/python > > """ > __version__ = "$Revision: 1.1 $" > __date__ = "$Date: 2001/08/06 20:32:41 $" > """ > > import PythonCardPrototype > from PythonCardPrototype.loader import configOptions > import os, sys > > class aaa(PythonCardPrototype.model.Background): > > def on_menuFileExit_select(self, menu, event): > self.Close() > > > def displayResult(self,result): > self.components.sldResult.value=int(result) > > def on_sld1_select(self,target,event): > result = self.calcResult() > self.displayResult(result) > > > def on_bgMin_select(self,target,event): > name = target.name > if name[:3] == 'sld' and int(name[:3]) in [1,2,3,4]: > self.displayResult(self.calcResult()) > > > if __name__ == '__main__': > base, ext = os.path.splitext(sys.argv[0]) > filename = base + ".rsrc.py" > > configOptions() > > app = PythonCardPrototype.model.PythonCardApp(filename) > app.MainLoop() > __________________________________________________________ > ________________________________________________________ > > > aaa.rsrc.py > > {'stack':{'type':'Stack', > 'name':'Template', > 'title':'Template Resource', > 'position':(66, 0), > 'size':(500, 600), > > 'backgrounds': [ > {'type':'Background', > 'file':'template.py', -- 'file':'aaa.py', > 'classname':'Template', -- 'classname':'aaa', > 'name':'bgTemplate', > 'components': [ > > {'type':'Slider', > 'name':'sldResult', > 'position':(6, 91), > 'size':(200, 20), > 'layout':'horizontal', > 'max':400, > 'min':1, > 'value':55, > }, > > {'type':'Slider', > 'name':'sld1', > 'position':(9, 160), > 'size':(200, 20), > 'layout':'horizontal', > 'max':100, > 'min':1, > 'value':55, > }, > > {'type':'Slider', > 'name':'sld2', > 'position':(10, 295), > 'size':(200, 20), > 'layout':'horizontal', > 'max':100, > 'min':1, > 'value':64, > }, > > {'type':'Slider', > 'name':'sld3', > 'position':(11, 227), > 'size':(200, 20), > 'layout':'horizontal', > 'max':100, > 'min':1, > 'value':1, > }, > > {'type':'Slider', > 'name':'sld4', > 'position':(10, 9), > 'size':(200, 20), > 'layout':'horizontal', > 'max':100, > 'min':1, > 'value':28, > }, > > ] # end components > } # end background > ] # end backgrounds > } } > > > attmpt to run results::: > > > unable to load template.py > Traceback (most recent call last): > File "C:/Python21/PythonCardPrototype/samples/minimal/aaa.py", line 38, in ? > app = PythonCardPrototype.model.PythonCardApp(filename) > File "C:\PYTHON21\PythonCardPrototype\model.py", line 125, in __init__ > clazz = module.__dict__[ bg.classname ] > UnboundLocalError: local variable 'module' referenced before assignment > > Look, I promise to stop wasting your time soon... > No wasting, you've identified an interesting point. By not changing the 'file' and 'classname' attributes of your stack you managed to confuse the loader. Its an interesting conundrum, because we run aaa.py which causes the framework to load aaa.rsrc.py which *must* point back to aaa.py otherwise you see the error you got. Smacks of a bit of a circular reference to me and maybe something worth looking at? I know the original intention was for a run time engine which would first look at the rsrc file, thus the reference to aaa.py and class aaa makes sense. Perhaps it is just our round about unit testing strategy that causes the confusion. I leave it to the team to decide ... I haven't looked at the documentation but I suspect we need another paragraph in 'getting started'. I'll have a look at adding it later. Regards, Andy -- ----------------------------------------------------------------------- From the desk of Andrew J Todd esq. "Shave my poodle!" |
From: Kevin A. <al...@se...> - 2001-09-03 01:39:05
|
We should probably have a different error checking mechanism rather than throwing a generic exception, but the error: unable to load template.py shows that the problem is that there isn't a 'template.py' file to load. The problem is that your .rsrc.py and main source file don't match up. You must have used the resourceEditor sample to create your layout and so it generated default values for the stack and background names. You have: {'stack':{'type':'Stack', 'name':'Template', 'title':'Template Resource', 'position':(66, 0), 'size':(500, 600), 'backgrounds': [ {'type':'Background', 'file':'template.py', 'classname':'Template', 'name':'bgTemplate', 'components': [ at a minimum, you need to change the background info. After you do your first 'Save As...' with the resourceEditor, you can quit, open up the file you saved with an editor, and change the stack and background info, then you won't have to worry about it unless you decide to change background names... later. To test your code, I renamed the files to 'sliders.py' and 'sliders.rsrc.py' 'backgrounds': [ {'type':'Background', 'file':'sliders.py', 'classname':'aaa', 'name':'bgMin', 'components': [ I left the 'name' of the background the same, you can change it to something more meaningful, but then you need to make sure that the method def matches. def on_bgMin_select(self,target,event): By convention, 'classname' should start with a capital letter and should be meaningful, but 'aaa' is still valid, so I didn't change it. You don't need the 'on_sld1_select' method since you have a background one, so I commented that out. It turns out my original message had a typo and a logic problem, so the following line: if name[:3] == 'sld' and int(name[:3]) in [1,2,3,4]: ^ should be: if name[:3] == 'sld' and int(name[3:]) in [1,2,3,4]: however, that doesn't work because trying to do int('Result') throws an exception, so assuming that you only have four regular sliders and a result slider you would want to do: if name[:3] == 'sld' and name[3:]) != 'Result': Finally, you didn't have a calcResult method, so I added it below, but didn't finish the calculation for you, so you'll need to change that. The last thing that the code below doesn't do is deal with your calculation giving you a result outside the min and max values for your result slider. You'll have to decide how you want to deal with that possibility. That gives us changed this code for the class: class aaa(PythonCardPrototype.model.Background): def on_menuFileExit_select(self, menu, event): self.Close() def calcResult(self): s1 = self.components.sld1.value s2 = self.components.sld2.value s3 = self.components.sld3.value s4 = self.components.sld4.value result = 10 # put your calculation here return result def displayResult(self,result): self.components.sldResult.value=int(result) def on_bgMin_select(self,target,event): name = target.name if name[:3] == 'sld' and (name[3:]) != 'Result': self.displayResult(self.calcResult()) I noticed that your sliders are in a strange order in your layout: sld4 sldResult sld1 sld3 sld2 Perhaps you should exchange their y values to make the UI better. ka > -----Original Message----- > From: pyt...@li... > [mailto:pyt...@li...]On Behalf Of Ronald > D Stephens > Sent: Sunday, September 02, 2001 6:07 PM > To: pyt...@li... > Subject: [Pythoncard-users] Braindead debugging > > > PythonCard file, aaa.py > > #!/usr/bin/python > > """ > __version__ = "$Revision: 1.1 $" > __date__ = "$Date: 2001/08/06 20:32:41 $" > """ > > import PythonCardPrototype > from PythonCardPrototype.loader import configOptions > import os, sys > > class aaa(PythonCardPrototype.model.Background): > > def on_menuFileExit_select(self, menu, event): > self.Close() > > > def displayResult(self,result): > self.components.sldResult.value=int(result) > > def on_sld1_select(self,target,event): > result = self.calcResult() > self.displayResult(result) > > > def on_bgMin_select(self,target,event): > name = target.name > if name[:3] == 'sld' and int(name[:3]) in [1,2,3,4]: > self.displayResult(self.calcResult()) > > > if __name__ == '__main__': > base, ext = os.path.splitext(sys.argv[0]) > filename = base + ".rsrc.py" > > configOptions() > > app = PythonCardPrototype.model.PythonCardApp(filename) > app.MainLoop() > __________________________________________________________ > ________________________________________________________ > > > aaa.rsrc.py > > {'stack':{'type':'Stack', > 'name':'Template', > 'title':'Template Resource', > 'position':(66, 0), > 'size':(500, 600), > > 'backgrounds': [ > {'type':'Background', > 'file':'template.py', > 'classname':'Template', > 'name':'bgTemplate', > 'components': [ > > {'type':'Slider', > 'name':'sldResult', > 'position':(6, 91), > 'size':(200, 20), > 'layout':'horizontal', > 'max':400, > 'min':1, > 'value':55, > }, > > {'type':'Slider', > 'name':'sld1', > 'position':(9, 160), > 'size':(200, 20), > 'layout':'horizontal', > 'max':100, > 'min':1, > 'value':55, > }, > > {'type':'Slider', > 'name':'sld2', > 'position':(10, 295), > 'size':(200, 20), > 'layout':'horizontal', > 'max':100, > 'min':1, > 'value':64, > }, > > {'type':'Slider', > 'name':'sld3', > 'position':(11, 227), > 'size':(200, 20), > 'layout':'horizontal', > 'max':100, > 'min':1, > 'value':1, > }, > > {'type':'Slider', > 'name':'sld4', > 'position':(10, 9), > 'size':(200, 20), > 'layout':'horizontal', > 'max':100, > 'min':1, > 'value':28, > }, > > ] # end components > } # end background > ] # end backgrounds > } } > > > attmpt to run results::: > > > unable to load template.py > Traceback (most recent call last): > File "C:/Python21/PythonCardPrototype/samples/minimal/aaa.py", > line 38, in ? > app = PythonCardPrototype.model.PythonCardApp(filename) > File "C:\PYTHON21\PythonCardPrototype\model.py", line 125, in __init__ > clazz = module.__dict__[ bg.classname ] > UnboundLocalError: local variable 'module' referenced before assignment > > Look, I promise to stop wasting your time soon... > > > > _______________________________________________ > Pythoncard-users mailing list > Pyt...@li... > https://lists.sourceforge.net/lists/listinfo/pythoncard-users > |