diff options
Diffstat (limited to 'doc/html/designer-manual-5.html')
-rw-r--r-- | doc/html/designer-manual-5.html | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/doc/html/designer-manual-5.html b/doc/html/designer-manual-5.html index cc669704e..e617f70c6 100644 --- a/doc/html/designer-manual-5.html +++ b/doc/html/designer-manual-5.html @@ -32,7 +32,7 @@ body { background: #ffffff; color: black; } <td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><p align="right">[<a href="designer-manual-4.html">Prev: Creating Dialogs</a>] [<a href="designer-manual.html">Home</a>] [<a href="designer-manual-6.html">Next: Subclassing and Dynamic Dialogs</a>]</p> <h2 align="center"> The Designer Approach</h2> <a name="the-designer-approach"></a><h3><a name="1"></a>Introduction</h3> -<p>In TQt 2.x, <em>TQt Designer</em> was a visual form designer for editing files in the <tt>.ui</tt> file format. <em>TQt Designer</em>'s primary goal was to turn the most tedious part of GUI programming -- dialog design -- into a pleasant experience. From an architectural point of view, <em>TQt Designer</em> in 2.x is a fairly simple program. It reads and writes <tt>.ui</tt> files. Each <tt>.ui</tt> file contains an XML description of a single dialog form. A second utility -- the user interface compiler <tt>uic</tt> -- is used during the build process of an application to generate C++ code from those XML descriptions.</p> +<p>In TQt 2.x, <em>TQt Designer</em> was a visual form designer for editing files in the <tt>.ui</tt> file format. <em>TQt Designer</em>'s primary goal was to turn the most tedious part of GUI programming -- dialog design -- into a pleasant experience. From an architectural point of view, <em>TQt Designer</em> in 2.x is a fairly simple program. It reads and writes <tt>.ui</tt> files. Each <tt>.ui</tt> file contains an XML description of a single dialog form. A second utility -- the user interface compiler <tt>tquic</tt> -- is used during the build process of an application to generate C++ code from those XML descriptions.</p> <p>For TQt 3.0 our ambitions for <em>TQt Designer</em> have grown beyond single dialog editing. In addition to many new design features like the ability to creating main windows and actions, the new version introduces:</p> <ul><li><p><em>project management</em> for the user interface part of your application;</p> <li><p><em>code in forms</em> <em>TQt Designer</em> provides a code editor so that you can code your slots directly; the code is stored in <tt>.ui.h</tt> files and eliminates the need for sub-classing (although you can still subclass if you prefer);</p> @@ -58,35 +58,35 @@ body { background: #ffffff; color: black; } <p>When you've opened or created a project you can set up its database connections using the <em>Edit Database Connections</em> dialog (invoked by the <b>Project|Database Connections</b> menu option). The connections you make are stored in a <tt>.db</tt> file. When you reload a project you can reconnect by going to the <em>Edit Database Connections</em> dialog, clicking a connection in the list and clicking the <b>Connect</b> button.</p> <p>In most non-trivial database applications you will want to access the database from more than one form. This is why the <tt>.db</tt> file is part of a project, not just part of a single form.</p> <h4><a name="2-4"></a>.pro files</h4> -<p><em>TQt Designer</em> needs to store information on projects, for example, the list of forms, the image collection and information about available databases and how to access them. The majority of TQt users already use a project file format to create multiplatform makefiles: <tt>tmake</tt> (and with TQt 3.0 <tt>qmake</tt>) project <tt>.pro</tt> files. These files already contain the list of forms, <tt>.ui</tt> files, used in the project for <tt>uic</tt>.</p> +<p><em>TQt Designer</em> needs to store information on projects, for example, the list of forms, the image collection and information about available databases and how to access them. The majority of TQt users already use a project file format to create multiplatform makefiles: <tt>tmake</tt> (and with TQt 3.0 <tt>qmake</tt>) project <tt>.pro</tt> files. These files already contain the list of forms, <tt>.ui</tt> files, used in the project for <tt>tquic</tt>.</p> <p>We've extended the sections in the <tt>.pro</tt> file to include the extra information that <em>TQt Designer</em> needs to manage projects. For example, when you add a form to your project in <em>TQt Designer</em>, it is automatically added to the FORMS section of the project file, and thus <tt>qmake</tt> will generate the required build rules without any further work. Similarly, the images are added to the IMAGES section and thus gets automatically compiled into your executable.</p> <p>We don't force you to use <tt>qmake</tt>; if you prefer another build system, for example automake/autoconf or jam, you can still continue to use it. Look upon the <tt>.pro</tt> file as a file that describes the GUI part of your application. All you need to do -- as previously -- is add the <tt>.ui</tt> files and the images collection to your own Makefiles.</p> <h3><a name="3"></a>Extending the functionality of a form</h3> <p>First let us look at a small figure that shows the relationship between <tt>.ui</tt> files, generated code and application code:</p> <p align="center"><img align="middle" src="designer1.jpg"> </p> -<p><em>TQt Designer</em> reads and writes <tt>.ui</tt> files, e.g. <tt>form.ui</tt>. The user interface compiler, <tt>uic</tt>, creates both a header file, e.g. <tt>form.h</tt>, and an implementation file, e.g. <tt>form.cpp</tt>, from the <tt>.ui</tt> file. The application code in <tt>main.cpp</tt> <tt>#include</tt>s <tt>form.h</tt>. Typically <tt>main.cpp</tt> is used to instantiate the TQApplication object and start off the event loop.</p> -<p>While this approach is simple, it isn't sufficient for more complex dialogs. Complex dialogs tend to have quite a lot of logic attached to the form's widgets, more logic than can usually be expressed with predefined signals and slots. One way of handling this extra logic is to write a controller class in the application code that adds functionality to the form. This is possible because <tt>uic</tt> generated classes expose a form's controls and their signals to the public space. The big disadvantage of this method is that it's not exactly TQt-style. If you were not using <em>TQt Designer</em>, you would almost always add the logic to the form itself, where it belongs.</p> -<p>This is why the capability of adding custom slots and member variables to a form was added to <em>TQt Designer</em> early on. The big additional benefit with this approach is that you can use <em>TQt Designer</em> to connect signals to those custom slots, in the same elegant graphical way that is used to connect signals to predefined slots. The <tt>uic</tt> then adds an empty stub for each custom slot to the generated <tt>form.cpp</tt> implementation file.</p> -<p>The big question now is how to add custom implementation code to those custom slots. Adding code to the generated <tt>form.cpp</tt> is not an option, as this file gets recreated by the <tt>uic</tt> whenever the form changes -- and we don't want a combination of generated and handwritten code. There are two possible solutions, which we'll cover next.</p> +<p><em>TQt Designer</em> reads and writes <tt>.ui</tt> files, e.g. <tt>form.ui</tt>. The user interface compiler, <tt>tquic</tt>, creates both a header file, e.g. <tt>form.h</tt>, and an implementation file, e.g. <tt>form.cpp</tt>, from the <tt>.ui</tt> file. The application code in <tt>main.cpp</tt> <tt>#include</tt>s <tt>form.h</tt>. Typically <tt>main.cpp</tt> is used to instantiate the TQApplication object and start off the event loop.</p> +<p>While this approach is simple, it isn't sufficient for more complex dialogs. Complex dialogs tend to have quite a lot of logic attached to the form's widgets, more logic than can usually be expressed with predefined signals and slots. One way of handling this extra logic is to write a controller class in the application code that adds functionality to the form. This is possible because <tt>tquic</tt> generated classes expose a form's controls and their signals to the public space. The big disadvantage of this method is that it's not exactly TQt-style. If you were not using <em>TQt Designer</em>, you would almost always add the logic to the form itself, where it belongs.</p> +<p>This is why the capability of adding custom slots and member variables to a form was added to <em>TQt Designer</em> early on. The big additional benefit with this approach is that you can use <em>TQt Designer</em> to connect signals to those custom slots, in the same elegant graphical way that is used to connect signals to predefined slots. The <tt>tquic</tt> then adds an empty stub for each custom slot to the generated <tt>form.cpp</tt> implementation file.</p> +<p>The big question now is how to add custom implementation code to those custom slots. Adding code to the generated <tt>form.cpp</tt> is not an option, as this file gets recreated by the <tt>tquic</tt> whenever the form changes -- and we don't want a combination of generated and handwritten code. There are two possible solutions, which we'll cover next.</p> <h4><a name="3-1"></a>The subclassing approach</h4> <p>A very clean way to implement custom slots for generated forms is via C++ inheritance as shown in the next figure:</p> <p align="center"><img align="middle" src="designer2.jpg"> </p> -<p>Here the user wrote an additional class <b>FormImpl</b>, which is split into the header file <tt>formimpl.h</tt> and the implementation file <tt>formimpl.cpp</tt>. The header file includes the <tt>uic</tt> generated <tt>form.h</tt> and reimplements all the custom slots. This is possible because <tt>uic</tt> generated custom slots are virtual. In addition to implementing custom slots, this approach gives the user a way to do extra initialization work in the constructor of the subclass, and extra cleanups in the destructor.</p> +<p>Here the user wrote an additional class <b>FormImpl</b>, which is split into the header file <tt>formimpl.h</tt> and the implementation file <tt>formimpl.cpp</tt>. The header file includes the <tt>tquic</tt> generated <tt>form.h</tt> and reimplements all the custom slots. This is possible because <tt>tquic</tt> generated custom slots are virtual. In addition to implementing custom slots, this approach gives the user a way to do extra initialization work in the constructor of the subclass, and extra cleanups in the destructor.</p> <p>Because of these benefits and its flexibility, this approach became the primary way of using <em>TQt Designer</em> in TQt 2.x.</p> <p><b>Note:</b> To keep the namespace clean, most users did not follow the Form and FormImpl naming scheme shown in the figure, but instead named their <em>TQt Designer</em> forms FormBase and their subclasses Form. This made a lot of sense, because they always subclassed and were using those subclasses in application code.</p> <h4><a name="3-2"></a>The ui.h extension approach</h4> <p>Despite its flexibility and cleanness, the subclassing approach has some disadvantages:</p> <ul><li><p>Subclassing is not natural and easy for everybody. Newcomers to object-oriented techniques may feel uneasy about being <em>forced</em> to subclass for such a simple and natural thing like the implementation of a custom slot.</p> -<li><p>Inheriting generated classes is an additional possible source of programming mistakes, especially if the number of reimplemented functions is high and the signatures change often during the design process. To make the development process smoother, <tt>uic</tt> generates empty stubs for custom slots rather than pure virtual functions. While this approach keeps the code compiling and running, programmers can find themselves in a situation where they miss a runtime warning message and lose time before they find a small spelling error in their subclass.</p> +<li><p>Inheriting generated classes is an additional possible source of programming mistakes, especially if the number of reimplemented functions is high and the signatures change often during the design process. To make the development process smoother, <tt>tquic</tt> generates empty stubs for custom slots rather than pure virtual functions. While this approach keeps the code compiling and running, programmers can find themselves in a situation where they miss a runtime warning message and lose time before they find a small spelling error in their subclass.</p> <li><p>In larger projects with hundreds of forms, the additional subclasses can make a noticeable difference in terms of compilation speed and code size.</p> </ul><p>There may be more disadvantages, but these were reason enough for us to investigate alternative solutions. For TQt 3.0, we came up with a new concept, the <em>ui.h extension</em>.</p> <p>This is how it works:</p> <p align="center"><img align="middle" src="designer3.jpg"> </p> <p>In addition to the <tt>.ui</tt> file, <tt>form.ui</tt>, <em>TQt Designer</em> reads and writes another associated file <tt>form.ui.h</tt>. This <tt>.ui.h</tt> file is an <em>ordinary C++ source file</em> that contains <em>implementations</em> of custom slots. The file gets included from the generated form implementation file <tt>form.cpp</tt> and thus can be totally ignored by other user code. The reason we use a <tt>.h</tt> extension for the <tt>.ui.h</tt> file even though it contains C++ code is because it is always <em>included</em>, and because it is easier to integrate into the build process with a <tt>.h</tt> extension.</p> -<p>The <tt>form.ui.h</tt> file has a special position among all other files. It is a <em>shared</em> source file that gets written and read by both the user and <em>TQt Designer</em>. As such it is an ordinary revision controlled source file and not generated by <tt>uic</tt>. <em>TQt Designer</em>'s responsibility is to keep the file in sync with the custom slot definitions of the associated form:</p> +<p>The <tt>form.ui.h</tt> file has a special position among all other files. It is a <em>shared</em> source file that gets written and read by both the user and <em>TQt Designer</em>. As such it is an ordinary revision controlled source file and not generated by <tt>tquic</tt>. <em>TQt Designer</em>'s responsibility is to keep the file in sync with the custom slot definitions of the associated form:</p> <ol type=1><li><p>Whenever the users adds a new slots to the form, <em>TQt Designer</em> adds a stub to the <tt>.ui.h</tt> file.</p> <li><p>Whenever the user changes a custom slot's signature, <em>TQt Designer</em> updates the corresponding implementation.</p> <li><p>Whenever the user removes a custom slot, <em>TQt Designer</em> removes it from the <tt>.ui.h</tt> file.</p> |