This document describes the specificities of the Python code generation integrated into SpecTcl. We describe the general principles, then what attributes and methods will be auto-generated, and what code the user can customize. We finish with an example.
Unlike the "regular" SpecTcl, SpecPython fully uses the potential of the object-orientation of the Python language to generate re-usable graphic components. So, for a file named foo.ui, a file named foo.py will be generated, containing a single class named foo, which is a sub-class of the Tkinter Frame class. The Python file will also contain a piece of code allowing you to try out the class on its own by running "python foo.py" before integrating it into any application.
There is no specific extension for the SpecPython ui files, but it is possible to insert in widget characteristics some Python-specific features:
Oh: and the "Attach scrollbars" function works too... It has the same action than in the Tcl version.
The following attributes will be automatically generated:
The following methods will be automatically generated:
The part of the code the user can customize is inserted between two marker lines: "#~CUST_BEGIN" and "#~CUST_END". This part will at first only contain all the auto-generated methods described above.
The user can customize the code of the auto-generated methods and/or add new methods to this part. The customized or added methods will be kept by the code generation process. The only modification that may be occur within the customizable part is an addition of a method if, for example, a new button is created in the interface with a command field set to a method that do not exist yet.
Suppose you want to create the following dialog:
The "Yes" and "No" buttons do what they're supposed to do, and the "Can you repeat the question?" button opens the same dialog. A click on the "Yes" or "No" buttons on this new dialog must respectively confirm or cancel the two dialogs, and a new click on "Can you repeat the question?" opens a third dialog. And so on...
To achieve this behavior, create the dialog in SpecTcl as usual (if you don't know how, read the SpecTcl tutorial: select "Help contents" in the "Help" menu, then follow the link "SpecTcl tutorial"). The commands for the three buttons can be for example:
Save your file with the name YesNo.ui, and generate the code in Python mode. You must now have a file YesNo.py just near the .ui file.
Edit the file, and look for a comment block telling something like "Beginning of user-customizable code". After this block, you should have five empty methods:
The three last ones are the methods you specified as actions for the three buttons.
Now edit the code of the following methods:
self.confirmed = -1
self.confirmed = 1
self._parent.destroy()
self.confirmed = 0
self._parent.destroy()
## New window
wdw = Toplevel()
## New "YesNo" component in the window
onceMore = YesNo(wdw)
onceMore.pack(side=TOP)
## Wait for window to close
self.wait_window(wdw)
## Confirm if second dialog confirmed; cancel otherwise
if onceMore.confirmed: self.confirm()
else: self.cancel()
The dialog should now behave as expected. It's as simple as that...
Now we want to make a window looking like the following:
The "File" menu will have a "Quit" item, which will use our YesNo dialog to ask for confirmation.
So, design the window with SpecTcl, giving for the menubuttons the following menus:
Now generate thecode, and edit it to do the following:
self.fileMenu.add_command(label="Quit", command=self.confirmQuit)
def confirmQuit(self):
## Import the module for the YesNo dialog
from YesNo import YesNo
## Window for the dialog
wdw = Toplevel()
## Body of the dialog
yesNo = YesNo(wdw)
yesNo.pack(side=TOP)
## Wait for dialog to close
self.wait_window(wdw)
## If quit confirmed, really quit
if yesNo.confirmed: self.quit()
And it should work as expected... Once again, it's as simple as that...
Now, we want to add a "Quit" button in the window, looking for example like follows:
The button must have the same action than the "File->Quit" menu.
To do this, edit the MyWindow.ui interface file and add the button. Set its command field to "self.confirmQuit" and re-generate the code.
And that's it! Since the code generation has kept your former method definitions, the method confirmQuit is already defined and working...
Let's say we'll have a quite dull and stupid form as a contents for our window. The form should look for example like follows:
(Yeah, I know... Quite stupid indeed, but it's just to show you...)
So let's build our wonderful form with SpecPython, save it as WdwContents.ui, generate it, try it out a bit with "python WdwContents.py" to see if it does what it's supposed to do.
Once the form is OK, we just have now to edit again the MyWindow.py generated script to put the window contents insertion into the _init_specificAfter method. We'll need to insert it in the window's canvas (the one you should have put between the scrollbars) so we'll need its name. Let's say here that we haven't named it explicitely, so it'll have the default name "canvas#1". So, the new body of the _init_specificAfter method is now:
## "Quit" menu item creation (already present)
self.fileMenu.add_command(label="Quit", command=self.confirmQuit)
## Get the canvas in the window
canv = self._widgets['canvas#1']
## Creation of the window contents
from WdwContents import WdwContents
cont = WdwContents(canv)
## Create the window on the form in the canvas
canv.create_window(0, 0, anchor=NW, window=cont)
## Display update for computation of the form's dimensions
self.update()
## Configure the scroll region for the canvas from the contents' dimensions
canv.configure(scrollregion=(0, 0, cont.winfo_width(), cont.winfo_height()))
And if you now run "python MyWindow.py", you should see something like this:
If you correctly attached the scrollbars, they should be working without any problem. If you haven't, just edit your MyWindow.ui with SpecTcl and run the "Attach scrollbars" command in the "Commands" menu; that should do the stuff. And of course, our "File->Quit" menu and our quit button still work...