Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'python.': 0.02; 'example:': 0.03; '16,': 0.03; 'syntax': 0.04; 'argument': 0.05; 'subject:Python': 0.06; 'class,': 0.07; 'arguments': 0.09; 'bindings': 0.09; 'wrapper': 0.09; 'cc:addr:python-list': 0.11; 'python': 0.11; 'def': 0.12; 'gui': 0.12; 'jan': 0.12; "wouldn't": 0.14; 'dictionaries': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'modules,': 0.16; 'positional': 0.16; 'syntax,': 0.16; 'world",': 0.16; 'flexibility': 0.16; 'language': 0.16; 'wrote:': 0.18; 'code.': 0.18; 'possible,': 0.19; 'thu,': 0.19; 'work,': 0.20; 'written': 0.21; 'cc:addr:python.org': 0.22; 'convenient': 0.24; 'helper': 0.24; 'manager.': 0.24; 'question': 0.24; 'cc:2**0': 0.24; 'sort': 0.25; 'extension': 0.26; 'possibly': 0.26; 'this:': 0.26; 'developing': 0.27; 'gets': 0.27; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'skip:p 30': 0.29; 'am,': 0.29; "doesn't": 0.30; 'message- id:@mail.gmail.com': 0.30; "i'm": 0.30; 'code': 0.31; 'usually': 0.31; 'clicked': 0.31; 'class': 0.32; 'probably': 0.32; 'alone': 0.33; 'could': 0.34; 'classes': 0.35; 'something': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'keyword': 0.36; 'similar': 0.36; 'error.': 0.37; 'button': 0.38; 'skip:o 20': 0.38; 'easiest': 0.38; 'skip:. 20': 0.38; 'window': 0.38; 'structure': 0.39; 'called': 0.40; 'how': 0.40; 'skip:u 10': 0.60; 'easy': 0.60; 'first': 0.61; 'name': 0.63; 'such': 0.63; 'happen': 0.63; 'more': 0.64; 'potentially': 0.81; "it'd": 0.84; 'skip:) 10': 0.84; 'to:none': 0.92; 'children.': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=BIJr6cCOG3fD+umebLZu1SWmY1aNCSsFP5cDY8Nj7kI=; b=Quf0BjrlQiwYyrlyZoBciDpbaw08hfhTYmLH5tvMkwBbStQfwNHGLhoPJ9pphgcFSX HNFfdQH57u1OCXJWjgi6UvLtRLPCqkKazGP2gnIosFr+X5NhuzRvNrpfWA0Fmos692Ux 9ZPTvhQQFoxxdTNoJskoUqco5VCcyu14mfovjuPvnMiUDq2iZ4GWdh0I70dwyvSnJKDe 0D0vkFFrs/SxvDEaXdssFjWjGiPFwpr5ApoozX62vMxLF4uTFBeBAj/okRxEnwXmVevV j4nIX6nHWvRG3NNkui07SzvrgRpvQ7RGJLNNQTeyoy2g+PlG9JNM5EsVmw+jhEoPXS5U CQxg== MIME-Version: 1.0 X-Received: by 10.66.160.2 with SMTP id xg2mr4211520pab.23.1389807201879; Wed, 15 Jan 2014 09:33:21 -0800 (PST) In-Reply-To: <1389805328.32401.6.camel@linux-fetk.site> References: <1389805328.32401.6.camel@linux-fetk.site> Date: Thu, 16 Jan 2014 04:33:21 +1100 Subject: Re: Python declarative From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 79 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1389807212 news.xs4all.nl 2948 [2001:888:2000:d::a6]:48420 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:64008 On Thu, Jan 16, 2014 at 4:02 AM, Sergio Tortosa Benedito wrote: > Hi I'm developing a sort of language extension for writing GUI programs > called guilang, right now it's written in Lua but I'm considreing Python > instead (because it's more tailored to alone applications). My question > it's if I can achieve this declarative-thing in python. Here's an > example: > > Window "myWindow" { > title="Hello world"; > Button "myButton" { > label="I'm a button"; > onClick=exit > } > } > print(myWindow.myButton.label) Probably the easiest way to do that would be with dictionaries or function named arguments. It'd be something like this: myWindow = Window( title="Hello World", myButton=Button( label="I'm a button", onClick=exit ) ) print(myWindow.myButton.label) For this to work, you'd need a Window class that recognizes a number of keyword arguments (eg for title and other attributes), and then takes all other keyword arguments and turns them into its children. Possible, but potentially messy; if you happen to name your button "icon", it might be misinterpreted as an attempt to set the window's icon, and cause a very strange and incomprehensible error. The syntax you describe there doesn't allow any flexibility in placement. I don't know how you'd organize that; but what you could do is something like GTK uses: a Window contains exactly one child, which will usually be a layout manager. Unfortunately the Python GTK bindings don't allow such convenient syntax as you use here, so you'd need some sort of wrapper. But it wouldn't be hard to set up something like this: def clickme(obj): print("You clicked me!") obj.set_label("Click me again!") myWindow = Window( title="Hello World", signal_delete=exit ).add(Vbox(spacing=10) .add(Button(label="I'm a button!", signal_clicked=exit)) .add(Button(label="Click me", signal_clicked=clickme)) ) This is broadly similar to how I create a window using GTK with Pike, and it's easy to structure the code the same way the window is structured. If the number of helper classes you'd have to make gets daunting, you could possibly do this: myWindow = GTK(Gtk.Window, title="Hello World", signal_delete=exit ).add(GTK(Gtk.Vbox, spacing=10) .add(GTK(Gtk.Button, label="I'm a button!", signal_clicked=exit)) .add(GTK(Gtk.Button, label="Click me", signal_clicked=clickme)) ) so there's a single "GTK" class, which takes as its first positional argument a GTK object type to clone. This is all perfectly valid Python syntax, but I don't know of a convenient way to do this with the current modules, so it may require writing a small amount of wrapper code. ChrisA