473,722 Members | 2,240 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Call for suggestions: Declaring data entry forms using Pythonclasses

Hello all,

I'm posting this to the list with the intention to form a group of
people interested in this type of solution. I'm not going to spam the
list with it, unless for occasional and relevant announcements. If
you're interested, drop me a note. But if for some reason you think
that this discussion is fine here at the c.l.py, please let me know.

** LONG POST AHEAD **

I'm doing good progress on my form declarative language library. The
idea (for those who haven't read about it) is to be able to specify a
form declaration in the following format:

class ComplexForm(For m):
class Header(Form):
nickname = TextBox(length= 15, default="")
password = TextBox(length= 10, default="", password=True)
name = TextBox(length= 40, default="")
class Comment(Form):
comments = TextBox(length= 200, default="", multiline=True)

This is an experimental approach, with the intention to allow one to
write the form description in pure Python code, with the least
syntactic clutter possible. The main alternative is to use a data
driven approach -- feeding dicts or XML based representation to a
constructor -- but as I said, that's not the goal of this experiment.

I'm already able to properly build the example mentioned above. The
result is a conventional class filled with all attributes, and an
extra <_fields> member which is a ordered list of field object
instances. The metaclass constructor checks for some issues:

1) For the purposes of GUI description, field attributes are
order-dependant. But the dict passed to the metaclass constructor
isn't ordered. My first solution used stack information (using the
inspect module) to solve this problem. Thomas Heller and Andrew Dalke
proposed a simpler solution using a global counter that I've included
in the current incarnation (I'm wondering why did I try that hack
before, this solution is *much* better).

2) The inner classes (Header and Comment, in the example above) are
converted to *instances* of the same name during the construction of
the outer class (ComplexForm, in the example). The goal was to achieve
consistency; if some field members are classes and other instances,
then you have to check types while iterating the _fields structure to
render the GUI -- that's not what I had in mind.

Building GUIs

I'm just starting to work on this part. A renderer object will take
the form as a parameter, and will build the GUI accordingly with the
structure contained there.

To build the GUI, the renderer has to iterate over its fields. It's a
recursive process, because a form can contain other forms, either
declared directly as classes as in the example above, or through
normal attributes. I''m working on a generic iterator interface for
the form, which would allow to proceed without recursion on the
renderer side, but I'm not sure if this is the best approach. I'm
still thinkering with this part of the code. Suggestions are welcome.

#============== =========
Enough talk, that's the code. Use it as you want, but please, give it
proper attribution if you're going to use it elsewhere.
#============== =========

from inspect import isclass

# auxiliar functions

def getmyposition() :
"""
Returns the position of the caller, relative to the sequence of
statements that were executed during class creation.

Three possible methods were evaluated: using a global counter; using
a timestamp; or using the line number retrieved from the call stack.
For all purposes here, a simple counter is enough. It doesn't need
to be thread aware, because all that matters is the relative
ordering of statements that, by definition, will be executed within
the same thread during the class initialization.
"""
counter = 0
while True:
counter += 1
yield counter

# decorates getmyposition to hide the internal static var
getmyposition = getmyposition() .next

def getfields(dct):
"""
takes a dictionary of class attributes and returns a decorated list
containing all valid field instances and their relative position.
"""
for fname, fobj in dct.items():
if isinstance(fobj ,Component):
print "found box: ", fname, fobj._mypos
yield (fobj._mypos, (fname, fobj))
elif isclass(fobj) and issubclass(fobj ,Component):
print "found container: ", fname, fobj._mypos
# substitutes the contained class for its instance
yield (fobj._mypos, (fname, fobj()))
else:
print "unknown: ", fname, fobj, type(fobj)
# returns the original object with tag order = 0
yield (0, (fname, fobj))

def makefieldsdict( dct):
# build the field list and sort it
fields = list(getfields( dct))
fields.sort()
# undecorate the list and return it converted to dict; the _field
# attribute is added automatically to refer to the sorted list
sorted_field_li st = [field[1] for field in fields]
field_dict = dict(sorted_fie ld_list)
field_dict['_fields'] = [field for field in sorted_field_li st
if isinstance(fiel d[1],Component)]
return field_dict

# metaclasses

class Container(type) :
def __new__(cls, name, bases, dct):
# creates the class using only the processed field list
newclass = type.__new__(cl s, name, bases, makefieldsdict( dct))
newclass._mypos = getmyposition()
return newclass

# Component is the ancestor of all elements in a
# form, including containers and boxes

class Component(objec t):
pass

# BoxElement is the ancestor of all elements that are
# instantiated as objects inside the container classes

class Box(Component):
def __init__(self):
self._mypos = getmyposition()

# a form is a container of other components

class Form(Component) :
__metaclass__ = Container
# I'm trying several versions of the iterator interface, I really don't
# know which one is going to be useful in real cases -- I'll have to write
# more code an try some alternatives first

def iterfields1(sel f):
# this iterator returns field objects without recursion
for fname, fobj in self._fields:
yield (fname, fobj)

def iterfields2(sel f, _level=0):
# this iterator recursively returns tuples of
# (parent, level, iscontainer, name, component)
for fname, fobj in self._fields:
if hasattr(fobj, '_fields'):
yield (self, _level, True, fname, fobj)
for parent, level, iscont, name, field in
fobj.iterfields 2(_level=_level +1):
yield (parent, level, iscont, name, field)
else:
yield (self, _level, False, fname, fobj)

def iterfields3(sel f):
# this iterator returns a nested list representation that is
# built recursively
for fname, fobj in self._fields:
if hasattr(fobj,'_ fields'):
yield (self, fname, list(fobj.iterf ields3()))
else:
yield (self, fname, fobj)

# data entry controls

class TextBox(Box):
def __init__(self, length=40, default="", password=False, multiline=False ):
Box.__init__(se lf)
self._length = length
self._default = default
self._password = password
self._multiline = multiline

# forms

class UserForm(Form):
nickname = TextBox(length= 15, default="")
password = TextBox(length= 10, default="", password=True)
name = TextBox(length= 40, default="")

class ComplexForm(For m):
class Header(Form):
nickname = TextBox(length= 15, default="")
password = TextBox(length= 10, default="", password=True)
name = TextBox(length= 40, default="")
class Comment(Form):
comments = TextBox(length= 200, default="", multiline=True)
summary = TextBox(length= 200, default="", multiline=True)

# simple test for the iterators
x = ComplexForm()
print
print "ComplexForm.it erfields1"
print "\n".join([str(item) for item in x.iterfields1()])
print
print "ComplexForm.it erfields2"
print "\n".join([str(item) for item in x.iterfields2()])
print
print "ComplexForm.it erfields3"
print "\n".join([str(item) for item in x.iterfields3()])
print
--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmai l.com
mail: ca********@yaho o.com
Jul 18 '05 #1
5 2399
On Thu, 23 Sep 2004 13:36:19 -0300, Carlos Ribeiro <ca********@gma il.com> wrote:
Hello all,

I'm posting this to the list with the intention to form a group of
people interested in this type of solution. I'm not going to spam the
list with it, unless for occasional and relevant announcements. If
you're interested, drop me a note. But if for some reason you think
that this discussion is fine here at the c.l.py, please let me know.

No comment for now other than suggesting replacing pass with def __repr__ in

class Component(objec t):
def __repr__(self): return '<Comp %r>' % type(self).__na me__

for a more userfriendly printout. Interesting stuff. I wonder about
one-dimensional position vs composing with various top/left/right/bottom/fill
aggregation indicator info etc.

Also wonder if just plain defining your own python-inspired but not python-constrained
language for expressing what you want to express might not be a viable alternative,
given the nice tools for language processing that are part of the open python kit.

IOW, you are using python in a certain way in order to be able to "spell" your
form-descriptions in a certain way. How would you spell them if you were not
constrained by python syntax?

Regards,
Bengt Richter
Jul 18 '05 #2
On 23 Sep 2004 19:53:37 GMT, Bengt Richter <bo**@oz.net> wrote:
On Thu, 23 Sep 2004 13:36:19 -0300, Carlos Ribeiro <ca********@gma il.com> wrote:
Hello all,

I'm posting this to the list with the intention to form a group of
people interested in this type of solution. I'm not going to spam the
list with it, unless for occasional and relevant announcements. If
you're interested, drop me a note. But if for some reason you think
that this discussion is fine here at the c.l.py, please let me know.
No comment for now other than suggesting replacing pass with def __repr__ in

class Component(objec t):
def __repr__(self): return '<Comp %r>' % type(self).__na me__

for a more userfriendly printout. Interesting stuff. I wonder about
one-dimensional position vs composing with various top/left/right/bottom/fill
aggregation indicator info etc.


I'm doing stuff like this right now. My debug display was awful, it's
nicer after some __repr__() customization. I've also changed some
class names and moved the basic metaclass stuff in a module of their
own, called "metacontainer" . It will make easier to reuse the basic
engine while I'm testing it.
IOW, you are using python in a certain way in order to be able to "spell" your
form-descriptions in a certain way. How would you spell them if you were not
constrained by python syntax?


I regard this as an experiment. I don't know if it will be successful
or not, but I have to try it first ;-). I have a hunch that it will be
more usable in the long run, even with all constraints imposed by
Python syntax, than to define yet another language.

BTW, one can think about the constraints as problems, but they have a
definitive advantage: they limit the scope of the problem to a much
more manageable size. I've seen plenty of projects for description
languages go nowhere, partly because people would spend a lot of time
arguing on how should things be structured :-)

Finally, I ask you to think about it for a while. It's still not
usable, but it may be really soon. I'm confident that, once one starts
using it, it will feel more natural than to have to work with yet
another language (as Tanebaum once said, there's a nice thing about
standards -- there are so many to choose from).

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmai l.com
mail: ca********@yaho o.com
Jul 18 '05 #3
Carlos Ribeiro wrote:
# decorates getmyposition to hide the internal static var
getmyposition = getmyposition() .next


Codewise this is probably cleaner

import itertools
getmyposition = itertools.count ().next

More than that requires I know how to use metaclasses. :)

If it works like I think it does then it's pretty neat.

Andrew
da***@dalkescie ntific.com
Jul 18 '05 #4
Carlos Ribeiro wrote:

I'm doing good progress on my form declarative language library. The
idea (for those who haven't read about it) is to be able to specify a
form declaration in the following format:

class ComplexForm(For m):
class Header(Form):
nickname = TextBox(length= 15, default="")
password = TextBox(length= 10, default="", password=True)
name = TextBox(length= 40, default="")
class Comment(Form):
comments = TextBox(length= 200, default="", multiline=True)


[snip]

By a strange coincidence, this intermediate representation is eerily
similar to the one used in vb2py when converting Visual Basic forms to
Python ones (implemented in PythonCard).

The process is,

1. Read VB form
2. Write intermediate representation (see below)
3. Convert intermediate to a PythonCard (wxWidgets based) form

The intermediate representation looks like,

class vbobj_frmForm(r esource.Form):
Caption = "Form1"
ClientHeight = 3090
ClientLeft = 60
ClientTop = 450
ClientWidth = 4680

class vbobj_btnCheckL ike(resource.Co mmandButton):
Caption = "Like ?"
Height = 375
Left = 1440
TabIndex = 2
Top = 1560
Width = 1815

class vbobj_txtTwo(re source.TextBox) :
Height = 405
Left = 240
TabIndex = 1
Text = "Text2"
Top = 840
Width = 4095

class vbobj_txtOne(re source.TextBox) :
Height = 375
Left = 240
TabIndex = 0
Text = "Text1"
Top = 240
Width = 4095
I've found that the inner class approach works pretty well although I
must admit that the implementation of the transformation in vb2py is
pretty ugly!

I'm very interested in where you are headed with this - what is your
target UI? Are you planning on releasing this under an OS license?

Regards,

Paul
=============== =============== ==
vb2Py - Visual Basic to Python Conversion
http://vb2py.sourceforge.net
Jul 18 '05 #5
On Fri, 24 Sep 2004 01:30:33 GMT, Paul Paterson
<pa**********@u sers.sourceforg e.net> wrote:
By a strange coincidence, this intermediate representation is eerily
similar to the one used in vb2py when converting Visual Basic forms to
Python ones (implemented in PythonCard).
I don't think it is a coincidence; I think that's because this is the
natural way to represent this structure in Python. If you look at the
way Delphi forms are stored when you choose text format (the default
for newer versions), it's strikingly similar -- just change "class"
for "object". I assume VB internals are structured in the same way.
The intermediate representation looks like,

[...long sample...]


I think that my current code can be easily adapted for your needs. I'm
now working on a generic renderer interface. I'm figuring out how to
make it general enough but still simple to sue. The current
implementation is already able to walk the class attributes in the
order of the original declaration, which is important to preserve some
behavior (specially the implicit tab ordering that is normally used in
GUI design).

As for your last question: yes, it's open source, I just haven't yet
figured out which license to choose from -- either BSD or LGPL, I
think. Part of the problem is that I don't have a nice host to put it
for download yet. I this point BSD would be nice -- it's too little
code to make a fusss about it being used inside some other product --
but if the library gets bigger I tend to go towards LGPL.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmai l.com
mail: ca********@yaho o.com
Jul 18 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
5901
by: Tim ffitch | last post by:
Hi I have created a VB dll file that contains common functions I use across various projects in VB, Access and Excel. Rather than have to code the functions in each I decided to use the dll route. The problem being that I can't call these functions from the query designer in Access. I decided that I would try the route of declaring the functions from the dll file the same way you would for the Windows API. Access then complains that...
10
8203
by: Clint | last post by:
Hey all - I'm having a really confusing problem concerning a web service. Right now, I have an application that needs to call a web service that does nothing but return "true" (this will obviously change once the program's fully built to actually do something, but for testing, it works). The only code I added to the service is below:
3
2881
by: Uma sakshi | last post by:
Hi I have one VB.NET application,in that application i have one datagrid control.The datagrid control contains somedata.I want to copy the data in a particular cell and paste it into my C#.NET application or notepad where i want to paste it to be.How can i do it?If anyone knows source code or any website URL's please let me know. Umasakshi
1
2090
by: Steve | last post by:
Hello, Is it possible to call a sub routine from 2 different threads at the same time? Or should I create a class containing this sub and instantiate the class for each thread? The sub pulls data from different data sources but the same structure. Right now I have 2 separate forms with the same sub. If I call both forms from the 2 threads I can pull the data faster than calling the sub for datasource1 and then calling the sub for...
0
861
by: Michael | last post by:
Hi Everyone, I'm in the process of designing a app that will load control dynamically from an xml file and need a few questions. 1. Once the form is loaded with the controls needed, how do you access the properties of the control. I just started to play with it today, and noticed that I can't seem to get the values from the controls. Here is the code snippit that I'm using: Dim btnOk as New System.Windows.Forms.Button btnok.Name =...
2
5056
by: filbennett | last post by:
Hi Everyone, I'm generally unfamiliar with Access form design, but have programmed Cold Fusion applications for a couple of years. I'd like to build a data entry form in Access that allows the following. First, the data schema: Three tables are involved. The first is a PERSONS table which has two fields, SSNUMBER (primary key), and NAME.
0
1784
by: bpo_ccs | last post by:
We are into BPO and Software development business for past six and half years. We are looking for the following any kind of business from your end. Back Office Process Data Entry, Large Volume Data Processing, Data Conversion, Forms Processing, Process flow & Quality Data Entry Text, Numeric or Alphanumeric entry, Printed or Handwritten matter, Hardcopies or Scanned Images, Some typical examples include, Mortgage Documents, Abstract...
2
2469
by: x | last post by:
hi i am a pilot by profession. i want to create a database of my logbook using ms access 2002. i am facing a problem regarding the format of time field. when i select "Data/Time" data type for my time field then this format gives the liberty to record times uptill a figure of 59 in different sub-formats, whereas i want the format to be able to record the times like 80:35 or 1:10 or 1138:00. which means that i have these many hours on a...
2
4523
by: gmccallum | last post by:
I have a data entry screen using controls bound through a bindingSource, TableAdaptor and a BindingNavigator to move through the records. When I have an data entry error (such as Null for a value) I get the following error raised all the way to the App.Run command. This is not a dataGridView, so I can not use that DataError event to catch it. I have tried the BindingSource_DataError event, but that does not seem to get fired. There is...
0
8863
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8739
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9384
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9238
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8052
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5995
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4762
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3207
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2602
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.