designer-manual-7.html

来自「QT 下载资料仅供参考」· HTML 代码 · 共 407 行 · 第 1/4 页

HTML
407
字号
<li><p>We must change the <tt>BookForm::newCurrentAuthor()</tt> slot to specify the parameter name and perform the necessary action:</p><pre>    void BookForm::newCurrentAuthor( <a href="qsqlrecord.html">QSqlRecord</a> *author )    {        BookDataTable-&gt;setFilter( "authorid=" + author-&gt;<a href="qsqlrecord.html#value">value</a>( "id" ).toString() );        BookDataTable-&gt;refresh();    }</pre> <p>All that's required now is to change the BookDataTable's filter and refresh the <b>QDataTable</b> to show the results of the filter.</p></ol><h5><a name="2-3-2"></a>Preparing the Interface for Drilldown</h5><!-- index Databases!Drilldown --><!-- index Drilldown --><p>We can now browse and edit authors and see their books in the BookDataTable. In the next section we explore <b>QDataBrowser</b>, which will allow us to drill down to a dialog through which we can edit books. For now we will add some buttons to the main BookForm which we will use to invoke the book editing dialog.</p><ol type=1><li><p>Click the form, then click the <b>Break Layout</b> toolbar button. Resize the form to make room for some buttons at the bottom.</p><li><p>Add two buttons to the bottom of the form. Change their names and labels to the following:</p><ul><li><p>EditPushButton -- &amp;Edit Books</p><li><p>QuitPushButton -- &amp;Quit</p></ul><p>Hold down the Shift key and Click both buttons (i.e. <b>Shift+Click</b> the buttons) and click the <b>Lay Out Horizontally</b> toolbar button. Click the form and click the <b>Lay Out Vertically</b> toolbar button.</p><li><p>We will provide the Quit button with functionality now and work on the rest shortly. Click <b>Connect Signals/Slots</b>, then click the Quit button and drag to the form; release the mouse on the form. The <em>Edit Connections</em> dialog will appear. Click the<!-- index clicked() --> <tt>clicked()</tt> signal and the<!-- index accept() --> <tt>accept()</tt> slot. Click <b>OK</b>.</p></ol><h3><a name="3"></a>Using <b>QDataBrowser</b> and <b>QDataView</b></h3><p align="center"><img align="middle" src="book-dialog.png" width="548" height="405"></p><blockquote><p align="center"><em>The Book Application's Edit Books Dialog</em></p></blockquote><h4><a name="3-1"></a>Drilling Down to a Form using <b>QDataBrowser</b></h4><h5><a name="3-1-1"></a>Setting up a <b>QDataBrowser</b></h5><!-- index Databases!Drilldown --><!-- index Drilldown --><!-- index Databases!Data Browser Wizard --><!-- index Wizards!Data Browser --><p>We will now create a new form to allow users to edit book records. Click the <b>New</b> toolbar button, click the Dialog template from the <em>New File</em> dialog and click <b>OK</b>. Change the name of the form to EditBookForm and its caption to 'Edit Books'. Click the <b>Save</b> toolbar button and call the file <tt>editbook.ui</tt>. Now that we have the form we can add a <b>QDataBrowser</b> to show the book records.</p><ol type=1><li><p>Click the <b>Data Browser</b> toolbar button, then click the form. The Data Browser Wizard will appear.</p><li><p>The <em>Database Connection and Table</em> wizard page is used to set up a connection if one doesn't exist and to choose the table or view for the <b>QDataBrowser</b>. (See <a href="designer-manual-7.html#1-1">Setting Up Qt Designer's Connections</a>.)</p><p>Click the connection you wish to use, listed in the Connection list box, e.g. "(default)". The available tables and views will appear in the Table list box. Click the book table and then click the <b>Next</b> button.</p><li><p>The <em>Displayed Fields</em> wizard page provides a means of selecting which fields should be displayed in the <b>QDataBrowser</b> and in what order. By default all fields except the primary key (if there is one) are in the right hand Displayed Fields list box. The left and right blue arrow buttons can be used to move fields between the Displayed Fields and the Available Fields list boxes. The blue up and down arrow buttons are used to select the display order of the displayed fields.</p><p>We don't want to see the authorid foreign key field on the form, so move it to the Available Fields list box. Also, move the title field to the top of the Displayed Fields list. Click the <b>Next</b> button.</p><li><p>The <em>Navigation and Editing</em> wizard page allows us to choose which navigation and editing buttons should appear on the form.</p><p>We will accept the defaults and simply click the <b>Next</b> button.</p><li><p>The <em>SQL</em> wizard page is used to set the <b>QDataBrowser</b>'s Filter and Sort properties. The Filter is an SQL <tt>WHERE</tt> clause (without the word 'WHERE'). For example, to only list books that cost less than 50 (of some currency, e.g. dollars), we would enter <tt>price &lt; 50</tt>. We will leave the filter empty. The Available Fields list box lists all the fields. The Sort By list box lists the fields that the <b>QDataBrowser</b> is to sort by and the direction of their sorting (ASCending or DESCending). The left and right blue arrows are used to move fields between the two list boxes. The up and down blue arrows move fields up and down within the Sort By list box. The ASC or DESC setting is changed with the sort order button.</p><p>Move the title field into the Sort By list box and click <b>Next</b>.</p><li><p>The <em>Layout</em> wizard page is used to specify the initial layout of the form.</p><p>Change the Number of Columns to 1, then click <b>Next</b>. Now click <b>Finish</b>.</p><li><p>The <b>QDataBrowser</b> will now appear on the form. Resize the form to make it shorter. Click the <b>QDataBrowser</b> then click the <b>Break Layout</b> toolbar button. Click the buttons then click the <b>Break Layout</b> toolbar button. Add another button called 'PushButtonClose' with the text '&amp;Close' and place it to the right of the Delete button.</p><li><p><b>Shift+Click</b> the Insert, Update, Delete and Close buttons, then click the <b>Lay Out Horizontally</b> toolbar button. Click the <b>QDataBrowser</b>, then click the <b>Lay Out in a Grid</b> toolbar button. Finally click the form and click the <b>Lay Out Vertically</b> toolbar button. Now click the <b>QDataBrowser</b> and rename it 'BookDataBrowser'.</p><li><p><em>Qt Designer</em> will generate the necessary code to make the browser operational (including generating the appropriate cursor, sort and filter code).</p><p>For finer control over the form, we will be creating our own database cursor. Therefore, set the BookDataBrowser's frameworkCode property to FALSE in the Properties window to prevent <em>Qt Designer</em> from generating redundant code for the cursor.</p></ol><blockquote><p align="center"><b> <b>QDataBrowser</b> User Interface Interaction</b></p><p>The user-interface behaviour for <b>QDataBrowser</b>s is created by connecting slots and signals. The slots provided are:</p><ul><li><!-- index insert() --><p><tt>insert()</tt>,<!-- index update() --> <tt>update()</tt> and<!-- index del() --> <tt>del()</tt> for editing;</p><li><!-- index first() --><p><tt>first()</tt>,<!-- index next() --> <tt>next()</tt>,<!-- index prev() --> <tt>prev()</tt>, and<!-- index last() --> <tt>last()</tt> for navigation;</p><li><!-- index refresh() --><p><tt>refresh()</tt> to refresh the cursor from the database;</p><li><!-- index readFields() --><p><tt>readFields()</tt> to read data from the cursor's edit buffer and<!-- index writeFields() --> <tt>writeFields()</tt> to write the form's data to the cursor's edit buffer;</p><li><!-- index clearValues() --><p><tt>clearValues()</tt> to clear the form's values.</p></ul><p>If you use <em>Qt Designer</em>'s <b>QDataBrowser</b> wizard you will be given the option of creating a default set of buttons for navigation and editing. The behaviour of these buttons is set up using the slots described above to provide the following functionality:</p><ul><li><p><tt>INSERT</tt> is initiated by pressing the <b>Ins</b> (Insert) button. The user moves between fields using <b>Tab</b> and <b>Shift+Tab</b>. If the user presses the Update button the <tt>INSERT</tt> will take place and the user will be taken to the record they have just inserted. If the user presses the Insert button (i.e. a second time) the <tt>INSERT</tt> will take place and a new insertion will be initiated. If autoEdit is TRUE the <tt>INSERT</tt> will take place if the user navigates to another record. <tt>INSERT</tt> is cancelled by pressing the <b>Esc</b> key or by pressing the <b>Del</b> (Delete) button. If autoEdit is FALSE then navigating to another record also cancels the <tt>INSERT</tt>. Setting confirmInsert to TRUE will require the user to confirm each <tt>INSERT</tt>.</p><li><p><tt>UPDATE</tt> is automatically initiated whenever the user navigates to a record. An update will take place if the user presses the Update button. If autoEdit is TRUE the update will take place if the user navigates to another record. <tt>UPDATE</tt> is cancelled by pressing the <b>Esc</b> key or by pressing the <b>Del</b> button. If autoEdit is FALSE then navigating to another record also cancels the <tt>UPDATE</tt>. Setting confirmUpdate to TRUE will require the user to confirm each <tt>UPDATE</tt>.</p><li><p><tt>DELETE</tt> is achieved by pressing the <b>Del</b> button. Setting confirmDelete to TRUE will require the user to confirm each <tt>DELETE</tt>.</p></ul></blockquote><h5><a name="3-1-2"></a>Performing the Drilldown</h5><!-- index Databases!Drilldown --><!-- index Drilldown --><p>We now have a working form for editing book records. We need to start the form when the user clicks our 'Edit Books' button, and to navigate to the record they have selected in the BookDataTable. We also need to provide a means of editing the foreign keys, e.g. authorid.</p><ol type=1><li><p>We need to make a new slot to connect the Edit Books' button's<!-- index clicked() --> <tt>clicked()</tt> signal to. Click on the Book form to make it <em>Qt Designer</em>'s active form. Invoke the <em>Edit Slots</em> dialog and create a new slot called <tt>editClicked()</tt>. Now click the <b>Connect Signals/Slots</b> toolbar button. Click the Edit Books button and drag to the form; release the mouse on the form. In the <em>Edit Connections</em> dialog connect the<!-- index clicked() --> <tt>clicked()</tt> signal to the <tt>editClicked()</tt> slot. Click <b>OK</b> to leave the dialog.</p><!-- index Object Hierarchy --><li><p>In the Object Hierarchy window click Source and then click the <tt>editClicked</tt> function. We need to change it to the following:</p><pre>    void BookForm::editClicked()    {        EditBookForm *dialog = new EditBookForm( this, "Edit Book Form", TRUE );        <a href="qsqlcursor.html">QSqlCursor</a> cur( "book" );        dialog-&gt;BookDataBrowser-&gt;setSqlCursor( &amp;cur );        dialog-&gt;BookDataBrowser-&gt;setFilter( BookDataTable-&gt;filter() );        dialog-&gt;BookDataBrowser-&gt;setSort(QSqlIndex::<a href="qsqlindex.html#fromStringList">fromStringList</a>(            BookDataTable-&gt;sort(), &amp;cur ) );        dialog-&gt;BookDataBrowser-&gt;refresh();        int i = BookDataTable-&gt;currentRow();        if ( i == -1 ) i = 0; // Always use the first row        dialog-&gt;BookDataBrowser-&gt;seek( i );        dialog-&gt;exec();        delete dialog;        BookDataTable-&gt;refresh();    }</pre> <p>We create our dialog as before. We also create a cursor over the book table and set the dialog's <b>QDataBrowser</b>, BookDataBrowser, to use this new cursor. We set the <b>QDataBrowser</b>'s filter and sort to those that applied to the main form's book <b>QDataTable</b>. We refresh the <b>QDataBrowser</b> and seek to the same record the user was viewing on the main form. Then we exec the dialog and delete it when the user has finished with it. Finally we update the BookDataTable in the main form to reflect any changes that were made in the dialog.</p><li><p>Because our code refers to a class declared in <tt>editbook.h</tt> and to a <b>QDataBrowser</b> we need to add two additional include files. Click on the BookForm, then click on the Source tab of the Object Hierarchy window. Right click the 'Includes (In Declaration)' item and click New. Type in <tt>"editbook.h"</tt>. Now add a second include, this time, <tt></tt>&lt;qdatabrowser.h&gt;.</p></ol><p>Now when we navigate through the author and book records in the BookForm we can click the Edit Books button to launch our Edit Books dialog. Although the dialog supports <tt>UPDATE</tt>, <tt>DELETE</tt> and navigation over the book table, we cannot edit the foreign keys nor perform inserts. We will deal with insertion in the same way as we did with the <b>QDataTable</b>, then we will handle the foreign key relationship to author.</p><h5><a name="3-1-3"></a>Inserting into a <b>QDataBrowser</b></h5><p>We will create a slot to receive the Edit Books form's<!-- index primeInsert() --> <tt>primeInsert()</tt> signal so that we can insert a unique primary key.</p><ol type=1><li><p>Click on the Edit Books form, then create a new Slot called <tt>primeInsertBook(QSqlRecord*)</tt>.</p><p>Click <b>Edit|Slots</b>, then click the <b>New Slot</b> button and type the new slot name in the Slot Properties Slot edit box. Click <b>OK</b>.</p><li><p>Connect the BookDataBrowser's<!-- index primeInsert() --> <tt>primeInsert()</tt> signal to the <tt>primeInsertBook()</tt> slot.</p><p>Click the <b>Connect Signals/Slots</b> toolbar button, then click the BookDataBrowser and drag to the form; release the mouse on the form. Now click the<!-- index primeInsert() --> <tt>primeInsert()</tt> signal and the primeInsertBook slot. Click <b>OK</b>.</p><li><p>In the Object Hierarchy window click Source and then click the <tt>primeInsertBook</tt> slot. We need to change it to the following:</p><pre>    void EditBookForm::primeInsertBook( <a href="qsqlrecord.html">QSqlRecord</a> * buffer )    {        <a href="qsqlquery.html">QSqlQuery</a> query;        query.<a href="qsqlquery.html#exec">exec</a>( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='book';" );        query.<a href="qsqlquery.html#exec">exec</a>( "SELECT sequence FROM sequence WHERE tablename='book';" );        if ( query.<a href="qsqlquery.html#next">next</a>() ) {            buffer-&gt;<a href="qsqlrecord.html#setValue">setValue</a>( "id", query.<a href="qsqlquery.html#value">value</a>( 0 ) );        }    }</pre><li><!-- index clicked() --><!-- index accept() --> <p>We will also tidy up the user interface slightly. Click the Update button and set its default property to True. Connect the Close button's <tt>clicked()</tt> signal to the EditBookForm's <tt>accept()</tt> slot.</p></ol><h5><a name="3-1-4"></a>Handling Foreign Keys in a <b>QDataBrowser</b></h5><!-- index Foreign Keys --><!-- index Databases!Foreign Keys --><p>Qt's SQL module provides two approaches to dealing with foreign keys. The most powerful and flexible is to subclass widgets and use property maps to relate the widgets to the database. This approach is described in the <a href="http://doc.trolltech.com/sql.html#Custom_Editor_Widgets">Qt SQL Module documentation</a>, particularly the StatusPicker example. A simpler approach that can be taken wholly within <em>Qt Designer</em> is presented here.</p><p>We will add a new field to the EditBookForm so that authors can be edited along with the title and price. Once we've handled the visual design we'll write the code to make it all work.</p><ol type=1><li><p>First we'll add the new widgets. Click the BookDataBrowser and click the <b>Break Layout</b> toolbar button. Resize the form to make it larger and drag each set of buttons down to make some room below the title and price QLineEdits. Click the <b>Text Label</b> toolbar button and click on the form beneath the Price label. Click the <em>Text Label</em> and change its text to 'Author'. Click the <b>ComboBox</b> toolbar button and click on the form beneath the price QLineEdit. In the Property Window change the <em>ComboBox</em>'s <em>name</em> to ComboBoxAuthor and change its <em>sizePolicy</em> <em>hSizeType</em> to Expanding.</p><li><p>Now we'll lay out the dialog. <b>Shift+Click</b> the Author label and the <em>ComboBox</em> then click the <b>Lay Out Horizontally</b> toolbar button. Now click the BookDataBrowser and click the <b>Lay Out in a Grid</b> toolbar button.</p></ol><p>We need to write some code so that the <em>ComboBox</em> will be populated with author names and scroll to the current book's author. We also need to ensure that we put the author's id into the book table's authorid field when a book record is inserted or updated. We'll ensure the code is executed at the right time by putting it in slots and connecting signals to our slots.</p><ol type=1><li><p>Create two new slots called <tt>beforeUpdateBook(QSqlRecord *buffer)</tt> and <tt>primeUpdateBook(QSqlRecord *buffer)</tt>. (Click <b>Edit|Slots</b>, then in the <em>Edit Slots</em> dialog click New Slot and enter the first new slot. Click New Slot again and enter the second slot then click <b>OK</b>.)</p><li><p>When the user navigates through the dialog, each time they move to a new record, a<!-- index primeUpdate() --> <tt>primeUpdate()</tt> signal is emitted. We connect to this so that we can update the <em>ComboBox</em>'s display. Just before a record is updated or inserted into the database a<!-- index beforeUpdate() --> <tt>beforeUpdate()</tt> or<!-- index beforeInsert() --> <tt>beforeInsert()</tt> signal is emitted. We connect our <tt>beforeUpdateBook()</tt> slot to both these signals so that we can ensure that the book's authorid field is correctly populated.</p><p>Click the BookDataBrowser and drag the mouse to the form; release the mouse and the <em>Edit Connections</em> dialog will appear. Connect the<!-- index beforeUpdate() --> <tt>beforeUpdate()</tt> signal to our <tt>beforeUpdateBook()</tt> slot. Connect the<!-- index beforeInsert() --> <tt>beforeInsert()</tt> signal to our <tt>beforeUpdateBook()</tt> slot. Finally connect the<!-- index primeUpdate() --> <tt>primeUpdate()</tt> signal to our <tt>primeUpdateBook()</tt> slot.</p>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?