419 lines
16 KiB
HTML
419 lines
16 KiB
HTML
|
|
||
|
|
||
|
<!DOCTYPE html>
|
||
|
<html lang="en">
|
||
|
|
||
|
<head>
|
||
|
<title>EuGTK and Glade</title>
|
||
|
<link rel="stylesheet" href="style.css" type="text/css">
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
|
||
|
|
||
|
<heading>
|
||
|
<img src="../thumbnails/gtk-logo-rgb.gif" alt="GTK LOGO" />
|
||
|
<img src="../thumbnails/mongoose.png" alt="mongoose" />
|
||
|
<figure style="float:right; border:solid thin black;">
|
||
|
<img src="../screenshots/glade.png" alt="glade" align="right" width="400px" />
|
||
|
<figcaption>
|
||
|
Calendar program being edited in Glade
|
||
|
</figcaption>
|
||
|
</figure>
|
||
|
<h2> <hr />EuGTK 4.11.11 and Glade<hr /> </h2>
|
||
|
<h3>Drag and Drop interface construction</h3>
|
||
|
</heading>
|
||
|
|
||
|
<nav>
|
||
|
<div class="hdr">Quick Links</div>
|
||
|
<a href="StartingGlade.html"><button>Starting with Glade</button></a><br />
|
||
|
<a href="#overview"><button>Overview</button></a>
|
||
|
<a href="#namespaces"><button>Namespaces</button></a>
|
||
|
<a href="#problems"><button>Problems?</button></a>
|
||
|
<a href="#compile"><button>Compiling/Shrouding/Binding</button></a>
|
||
|
|
||
|
<br />
|
||
|
<div class="hdr">Other Files:</div>
|
||
|
<a href="HowItWorks.html"><button>How EuGTK Works</button></a>
|
||
|
<a href="README.html"><button>README</button></a>
|
||
|
<a href="guide_a.html"><button>Alphabetical Guide</button></a>
|
||
|
<a href="dialogs.html"><button>Built-in EuGTK Dialogs</button></a>
|
||
|
<a href="treeviews.html"><button>ListView/TreeView widgets</button></a>
|
||
|
<a href="pango_markup.html"><button>Markup</button></a>
|
||
|
<a href="printing.html"><button>Printing</button></a>
|
||
|
<a href="ServerHelp.html"><button>Web Server</button></a>
|
||
|
<a href="functions.html"><button>Quick Function List</button></a>
|
||
|
<a href="platforms.html"><button>Platforms</button></a>
|
||
|
<br />
|
||
|
</nav>
|
||
|
|
||
|
<a name="overview" />
|
||
|
|
||
|
<h3><hr />Overview<hr /></h3>
|
||
|
|
||
|
<p>
|
||
|
It is now possible to use <a href="http://glade.gnome.org">Glade</a> to design your EuGTK
|
||
|
program interface. I've tested with Glade versions 3.16 and 3.18.
|
||
|
You will still have to write snippets of code in Euphoria to handle
|
||
|
user events - just as you would when using Visual Basic™, Delphi™, etc.
|
||
|
</p>
|
||
|
|
||
|
<p>Begin by reading <a href="StartingGlade.html">Starting Glade I and II</a> for an
|
||
|
introduction, thenread the rest of this page for details.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Glade has a preview button so that you can see, to a limited extent, what your program
|
||
|
will look like. Controls won't be linked (can't respond to user interaction) until you
|
||
|
load the glade XML into your Euphoria program and provide the 'handler' functions.
|
||
|
Often, these handler functions will only require a few lines of code.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
EuGTK will try to help you with this task by supplying a ready-made template
|
||
|
for undeclared functions, which you copy and paste into your Euphoria code using whatever
|
||
|
text exitor you prefer.
|
||
|
</p>
|
||
|
|
||
|
<p>This template will appear on the terminal from which you run your
|
||
|
program. See the screenshot below.
|
||
|
</p>
|
||
|
|
||
|
<p>You <b><i>must</i></b> run programs from a terminal (x-term, for example) while
|
||
|
developing and testing. There's no way around this.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Your program begins as usual:<br />
|
||
|
<img src="../screenshots/template.png" alt="template" clear="left" align="right" width="400px" />
|
||
|
<code>
|
||
|
<pre> <em class="kw">include</em> GtkEngine.e</pre>
|
||
|
</code>
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Next, you tell EuGTK's built-in <i>builder</i> object
|
||
|
to load your program's XML description from the file created by Glade. The builder will
|
||
|
try to connect any signals for which you have declared a handler
|
||
|
(in the Glade Properties/Signals tabs). Finally, you call main() to start the GTK
|
||
|
processing loop.
|
||
|
<div class="quote"><tt><pre>
|
||
|
<em class="kw">include</em> GtkEngine.e
|
||
|
<em class="gtk">add</em>(builder,<em class="str">"~/demos/examples/widgets.glade"</em>)
|
||
|
<em class="gtk">main()</em><pre></tt></div>
|
||
|
</p>
|
||
|
|
||
|
<p>With just those three lines of code, you are now ready to run your program!<br /><br />
|
||
|
Of course, it won't do anything, except perhaps spit out a message telling you that
|
||
|
you haven't bothered to write handlers for events declared in Glade.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
You should run the program (preferably from WEE with terminal, the BEAR, Geany using
|
||
|
gneui.ex, or directly from an x-term).
|
||
|
EuGTK will prompt you with an error message and hopefully a function template for the
|
||
|
missing function.
|
||
|
You can copy and paste that into your editor, and then fill in the body of the function.
|
||
|
Put these functions after the call to main().
|
||
|
</p>
|
||
|
|
||
|
<div class="hint">
|
||
|
<img class="hint" src="../thumbnails/hint.png" alt="hint" width="100px" align="left" float="right" />
|
||
|
<p>
|
||
|
Note that when using Glade, your Euphoria code may use string identifiers to refer to
|
||
|
objects, rather than having to obtain a pointer (a.k.a. 'handle') to them first.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Glade will assign a unique identifier for widgets (which it calls the <b>ID:</b>).
|
||
|
The ID will be something like 'checkbutton1', 'checkbutton2', 'radiobutton1', etc.
|
||
|
</p>
|
||
|
|
||
|
<p> This ID property is found on the General tab of the Properties dialog.
|
||
|
You may change the IDs if you wish, sometimes changing them can make your code clearer.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Obviously, you should avoid naming two controls with the same name.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
If you are using <u>multiple</u> Glade files, you will almost certainly have more than
|
||
|
one 'button1', etc. but this isn't a problem, because a namespace will be prepended.
|
||
|
See <a href="#namespaces"> namespaces </a>below.
|
||
|
</p>
|
||
|
</div>
|
||
|
|
||
|
<br clear="all" />
|
||
|
|
||
|
<a name="namespaces" />
|
||
|
|
||
|
<h3><hr />Namespaces<hr /></h3>
|
||
|
<p>When writing a large program with multiple windows, Glade can become difficult to
|
||
|
navigate safely. Click on the wrong thing in Glade, and you may lose all your work.
|
||
|
This isn't good, so you should try to break up your program into small, safe 'modules',
|
||
|
each with it's own Euphoria include (.e) file and corresponding Glade (.glade) file.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Let's say, for example, I'm going to need a 'main' window, a pop-up 'edit' window, and
|
||
|
the usual "About..." dialog.
|
||
|
I'd create three Glade files, one named main.glade, the second edit.glade, and the third
|
||
|
about.glade.
|
||
|
After laying out these three windows using Glade, it's very likely that Glade will
|
||
|
have used identical names for controls in the files. 'button1', for example, might appear
|
||
|
in all three. You could, if you wish, wade thru all your Glade files and rename these as
|
||
|
necessary to prevent conflicts, but
|
||
|
EuGTK version 4.8.9 and up offers a less labor-intensive way.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
EuGTK namespacing allows you to refer to these controls by name in a manner familiar to
|
||
|
Euphoria programmers:<br />
|
||
|
"button1" (the button1 in main.ex); "edit:button1" and "about:button1"
|
||
|
(buttons in the respective edit.e and about.e files).<br />
|
||
|
<code><pre> <em class="gtk">set</em>(<em class="str"><b>"edit:window1"</b>,"background","blue"</em>)
|
||
|
</pre></code>
|
||
|
Note that these are strings. If you wish to convert them to Euphoria objects, you can,
|
||
|
starting with EuGTK 4.8.9, use the new pointer() function:
|
||
|
<pre><code> <em class="kw">constant</em> win1 = <em class="gtk">pointer</em>(<em class="str"><b>"edit:window1"</b></em>)
|
||
|
</code></pre>
|
||
|
Other files can now access the edit.e window in the normal Euphoria way:
|
||
|
<pre><code> <em class="gtk">set</em>(win1,<em class="str">"background"</em>,...)</code></pre>
|
||
|
</p>
|
||
|
|
||
|
<p>There seems to be no noticeable delay when accessing controls via the string names.
|
||
|
In a test which read and set label text using the constant 'handle' to the label, 20,000
|
||
|
iterations per second were reported.
|
||
|
When using the label's name in string form, 18,900 per second were reported. </p>
|
||
|
|
||
|
<div class="hint">
|
||
|
<img class="hint" src="../thumbnails/hint.png" alt="hint" width="100px" align="left" float="right" />
|
||
|
<p>
|
||
|
When using the string form, the namespace prefix will be the same as the Glade file name
|
||
|
(sans the .glade part) which the include file loaded into the GTK builder.<br /><br />
|
||
|
When exported as a Eu constant or variable, the namespace prefix will be whatever
|
||
|
namespace the included .e file declares. To prevent confusion, it's probably best to use
|
||
|
identical names. IOW, code in 'foo.e' would have the namespace foo.
|
||
|
</p>
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
To keep things neatly organized, you should put your Eu code in separate files as well:
|
||
|
main.ex, edit.e, and about.e.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Your Eu file main.ex would then include the line:
|
||
|
<pre><code> <em class="gtk">add</em>(builder,<em class="str">"main.glade"</em>)</code></pre>
|
||
|
</p>
|
||
|
|
||
|
<p>And your edit.e include file would have the lines:
|
||
|
<div class="quote"><tt><pre>
|
||
|
<em class="kw">namespace</em> edit
|
||
|
<em class="kw">include</em> GtkEngine.e
|
||
|
<em class="gtk">add</em>(builder,<em class="str">"edit.glade"</em>)
|
||
|
</pre></tt></div>
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
<img src="../screenshots/namespace.png" align="right" width="500px" />
|
||
|
|
||
|
To examine the namespaced names as loaded by EuGTK, add the line
|
||
|
<b><code> with define BUILDER </code></b>
|
||
|
to your main program prior to including GtkEngine.e,
|
||
|
or add <b><code>-d BUILDER</code></b> to the command-line.
|
||
|
The namespaced names will be shown on the xterm when you run your program. <i>(as shown above)</i>
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Glade objects loaded by the main (.ex) program will <i>not</i> be namespaced.
|
||
|
Those items can be addressed directly without a namespace qualifier.
|
||
|
This is done so that small programs which don't need multiple Glade 'includes' can
|
||
|
use code that isn't cluttered with unnecessary namespacery.</p>
|
||
|
|
||
|
<hr />
|
||
|
|
||
|
<p><b>Widget names</b><br /><br />
|
||
|
Confusingly, Glade also has a Widget name: property, found under the Common tab,
|
||
|
which you should avoid using except under special circumstances. It isn't normally
|
||
|
needed. EuGTK refers to widgets created by Glade by their ID:, e.g. the main window
|
||
|
of a program created by Glade would have the default ID of "window1", and your EuGTK
|
||
|
program would access that window as "window1".
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
There are a few 'trick' uses for this Widget name property, however:<br />
|
||
|
<p>One possible use is to pass data to functions which handle more than one control.
|
||
|
For example, you might have a set of radio buttons which all call a single handler
|
||
|
function. That function could examine the control's 'name' to determine what to do.
|
||
|
If, for example, the buttons select various colors, each button could have a different
|
||
|
color as the name property: 'red', 'green', or 'blue', etc.
|
||
|
</p>
|
||
|
|
||
|
<p>A more complex use might be to pass function names to a central 'dispatch' function,
|
||
|
which could then call the desired function by converting the 'name' into a routine_id.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Some of the demos in the glade subfolder utilize these tricks. See, for example, the
|
||
|
hello.* files: <a href="../glade/hello.ex">hello.ex</a>, <a href="../glade/es.e">es.e</a>,
|
||
|
etc...
|
||
|
</p>
|
||
|
|
||
|
<hr />
|
||
|
<p><b>Cautions</b><br /><br />
|
||
|
The XML file created by Glade may include a "requires..." line, demanding a certain GTK
|
||
|
version be present. You may find it helpful to remove that line under certain conditions,
|
||
|
for example when designing your program on Linux with a current version of GTK/Glade,
|
||
|
but running it on Windows™, which lags behind the other platforms.
|
||
|
Just use a plain-text editor to zap the offending line.
|
||
|
</p>
|
||
|
|
||
|
<a name="problems" />
|
||
|
|
||
|
<h3><hr />Common Problems<hr /></h3>
|
||
|
<p>
|
||
|
<ol>
|
||
|
<li>I run my program without errors but <i>can't see anything!</i><br />
|
||
|
<dfn>
|
||
|
You <u>must</u> click on the <i>'visible'</i> property checkbox for your main window.
|
||
|
This is found on the 'Common' tab under 'Widget Flags'.<br />
|
||
|
<i></i><b>Oh, and while you're there,</b></i> be sure to link the main window's <i>destroy</i>
|
||
|
signal to the built-in function Quit, so that your program will clean up after itself when finished!
|
||
|
You must do these two things for the main window of every program you write.</dfn>
|
||
|
</li>
|
||
|
|
||
|
<li>I put buttons in a dialog, such as FileChooserDialog, but they don't do anything!<br />
|
||
|
<dfn>Set a unique <i>'Response ID'</i> for each button.
|
||
|
This is found on the 'General' tab under 'Button Attributes'.<br />
|
||
|
This ID is returned when the dialog closes as a result of a button being clicked.
|
||
|
</dfn>
|
||
|
</li>
|
||
|
|
||
|
<li>How do I make menu items work like check menu items or radio menu items?<br />
|
||
|
<dfn>
|
||
|
I don't know how to do that using Glade.
|
||
|
You'll have to write code in Euphoria, or <gasp!> try to edit the .glade xml directly.
|
||
|
</dfn>
|
||
|
</li>
|
||
|
|
||
|
<li>I want to use widget x, but can't find it on the Glade palette<br />
|
||
|
<dfn>
|
||
|
Some things are hard to find, and some just aren't there.
|
||
|
New GTK widgets introduced since GTK 3.10 are partially missing.
|
||
|
If you're working on the 'bleeding edge' of GTK3, you probably should be
|
||
|
coding by hand.
|
||
|
</dfn>
|
||
|
</li>
|
||
|
|
||
|
<li>How do I know how to name the function that responds to a signal?<br />
|
||
|
<dfn>
|
||
|
If you click on the widget's Signals tab, you'll see a list of signals that can be linked.<br />
|
||
|
For example, a button has a 'clicked' signal.
|
||
|
You then click on the <type here> space adjacent to the signal name, and press the 'o' key. <br />
|
||
|
<em>(That's the letter o, not a zero!)</em><br />
|
||
|
When you do, a suggested function handler name will be plugged in.
|
||
|
You can, of course, type in any global function name you prefer here.
|
||
|
For example, the handler name for a Quit or Exit button should usually be <em class="black">Quit</em>
|
||
|
(no quotes)<br />This will call EuGTK's built-in Quit() function when the button is clicked.
|
||
|
</dfn>
|
||
|
</li>
|
||
|
|
||
|
<li>I want to write <i>one</i> Eu function to handle multiple controls.<br />
|
||
|
<dfn>
|
||
|
Instead of accepting the default handler name, supply your own
|
||
|
For example, if you have 3 buttons, Glade will supply handler names:
|
||
|
<ul><li>on_button1_clicked</li><li>on_button2_clicked</li><li>on_button3_clicked</li></ul>
|
||
|
You simply remove the 1,2,and 3 from the handler names, and name your Eu function
|
||
|
<em class="black">on_button_clicked</em>. All 3 buttons will call that function.
|
||
|
It's then your job to sort them out.
|
||
|
</dfn>
|
||
|
</li>
|
||
|
|
||
|
</ol>
|
||
|
|
||
|
</p>
|
||
|
|
||
|
<a name="compile" />
|
||
|
<h3><hr />Compiling, Binding, etc...<hr /></h3>
|
||
|
<p>
|
||
|
As usual, you can compile, bind, or shroud your program. If you do any of these, your program
|
||
|
will <i>still</i> load the GUI description from the Glade XML file at run-time. This could be either good or bad, depending upon your perspective.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
<u>The benefits:</u>
|
||
|
<ul>
|
||
|
<li>The GUI appearance can be adjusted without messing with the program logic</li>
|
||
|
</ul>
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
<u>The drawbacks:</u>
|
||
|
<ul>
|
||
|
<li>Anyone can easily trash your nice program by changing names or removing controls in the .glade file.
|
||
|
</li>
|
||
|
<li>The .glade file must be distributed along with the .ex file
|
||
|
</li>
|
||
|
</ul>
|
||
|
</p>
|
||
|
|
||
|
<div class="hint" style="width:80%;" >
|
||
|
<img class="hint" src="../thumbnails/hint.png" width="100px" alt="hint" align="left" float="right" />
|
||
|
<p style="margin-left: 40px">
|
||
|
<b>Knowing the way some users think...</b><br />
|
||
|
It's almost certain that someone will see that Glade™<sup><em>*</em></sup> file,<br />
|
||
|
think <i>"I don't care about air fresheners.."</i> and delete it.
|
||
|
<br /><br />
|
||
|
<small><i><sup><em>*</em></sup> brand name for a common type of room deodorizer in the U.S.</i></small>
|
||
|
</p>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
One easy solution to this problem is to copy the glade XML, paste it into a new file,
|
||
|
enclose it in triple quotes, and assign it to an exported constant. Below, the added code is in red, while the XML from Glade is shown in black:
|
||
|
<code><pre><em> export constant XML = """</em>
|
||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
<!-- Generated with glade 3.16.1 -->
|
||
|
<interface>
|
||
|
<requires lib="gtk+" version="3.10"/>
|
||
|
---etc---
|
||
|
<em>"""</em>
|
||
|
</pre></code></p>
|
||
|
<p>
|
||
|
|
||
|
Save this new file as an include, perhaps widgets.xml, with the widgets namespace, and then your code becomes:
|
||
|
<code><pre>
|
||
|
<em class="kw">include</em> GtkEngine.e
|
||
|
<em class="kw">include</em> widgets.xml
|
||
|
<em class="gtk">add</em>(builder,widgets:XML) <em>-- EuGTK can add objects from either a string variable or a filename</em>
|
||
|
<em class="gtk">main()</em>
|
||
|
</pre></code>
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Now you can bind or compile your program and the interface will be 'hard coded' into it. Changing or deleting
|
||
|
the widgets.xml or widgets.glade files will make no difference. No changes to your program interface can be made
|
||
|
without re-compiling or re-binding.
|
||
|
</p>
|
||
|
|
||
|
<footer>
|
||
|
<div class="hint">
|
||
|
<img class="hint" src="../thumbnails/mongoose.png" alt="hint" align="left" float="right" />
|
||
|
<p>
|
||
|
This page edited by The <a href="README.html#bear">Bear</a>,
|
||
|
a web-page and programming editor
|
||
|
written in <a href="OpenEuphoria.org">Euphoria</a>.
|
||
|
</p>
|
||
|
<p>
|
||
|
Updated for EuGTK version 4.11.11, Sept 1, 2016<br />
|
||
|
All code © 2016 by Irv Mullins
|
||
|
</p>
|
||
|
</div>
|
||
|
</footer>
|
||
|
|
||
|
</body>
|
||
|
</html>
|