📄 designer-manual-2.html
字号:
</p><blockquote><p align="center"><em>Previewing Multiclip</em></p></blockquote><!-- index Layouts!Splitters --><!-- index Layouts!Rubber band --><p>Click the splitter then click the <b>Break Layout</b> toolbar button; the splitter will be removed. Now click the form itself, near the bottom, and drag the rubber band so that it touches both the list box and some of the buttons, then release. The list box group and the buttons group are selected; click the <b>Lay Out Horizontally</b> toolbar button. Click the form then click the <b>Lay Out Vertically</b> toolbar button. The form is now laid out as we require. Preview the form (press <b>Ctrl+T</b>) and try resizing it.</p><!-- index Undo and Redo!Layouts --><p>It would be useful if you experimented further with layouts since they work visually and are best learnt through practice. To remove a layout click the <b>Break Layout</b> toolbar button; to apply a layout select the relevant widgets or groups and click a layout button. You can preview as often as you like and you can always undo any changes that you make.</p><!-- index Layouts!Grid --><!-- index Layouts!Break layout --><p>Let's try an experiment, to see how the grid layout works. Click the list box, then press <b>Ctrl+B</b> (break layout). Click one of the buttons and press <b>Ctrl+B</b>. Click the form at the bottom and drag until all the widgets are touching or within the rubber band, (but excluding the Current Clipping label and the currentLineEdit line edit); then release. Press <b>Ctrl+G</b> (lay out in a grid). Click the form, then click <b>Ctrl+L</b> (lay out vertically). Our original design is back -- but this time using a grid layout.</p><h4><a name="5-4"></a>Changing the Tab Order</h4><!-- index Tab Order --><!-- index Tab Order Mode!Tab Order --><p>Keyboard users press the <b>Tab</b> key to move the focus from widget to widget as they use a form. The order in which the focus moves is called the tab order. Preview multiclip (press <b>Ctrl+T</b>) and try tabbing through the widgets. The tab order may not be what we want so we'll go into tab order mode and change it to the order we want.</p><!-- index Tab Order --><p>When you click the <b>Tab Order</b> toolbar button a number in a blue circle will appear next to every widget that can accept keyboard focus. The numbers represent each widget's tab order, starting from 1. You change the tab order by clicking the widgets in the order you want to be the new tab order. If you make a mistake and need to start again, double click the widget you want to be first, then click the other widgets in the required order as before. When you've finished press <b>Esc</b> to leave tab order mode. If you made a mistake or preferred the previous tab order you can undo your changes by leaving tab order and undoing (press <b>Esc</b> then <b>Ctrl+Z</b>).</p><!-- index Tab Order --><p>Click the <b>Tab Order</b> toolbar button, then click the current clipping <em>Line Edit</em> -- even if it is already number one in the tab order. Next click the previous clipping <em>ListBox</em>, then the auto add clippings <em>CheckBox</em>. Click each button in turn from top (add clipping) to bottom (quit). Press <b>Esc</b> to finish tab order mode, then preview the form and try tabbing through the widgets.</p><p>Note that you can stop clicking if the tab order numbers for all the widgets is correct; just press <b>Esc</b> to leave tab order mode.</p><p align="center"><img align="middle" src="qd-chapdialog-taborder.png" width="557" height="338"></p><blockquote><p align="center"><em>Setting the Tab Order</em></p></blockquote><h3><a name="6"></a>Connecting Signals and Slots</h3><!-- index Signals and Slots --><!-- index Connecting!Signals and Slots --><p>Qt provides the signals and slots mechanism for communicating between widgets. Signals are emitted by widgets when particular events occur. We can connect signals to slots, either pre-defined slots or those we create ourselves. In older toolkits this communication would be achieved using callbacks. (For a full explanation of Qt's signals and slots mechanism see the on-line <a href="http://doc.trolltech.com/signalsandslots.html">Signals and Slots</a> documentation.)</p><h4><a name="6-1"></a>Connecting Predefined Signals and Slots</h4><!-- index Signals and Slots --><p>Some of an application's functionality can be obtained simply by connecting pre-defined signals and slots. In multiclip there is only one pre-defined connection that we can use, but in the richedit application that we'll build in <a href="designer-manual-3.html">Creating Main Windows with Actions, Toolbars and Menus</a> we will use many pre-defined signals and slots to get a lot of the functionality we need without having to write any code.</p><p>We will connect the Quit button's<!-- index clicked() --> <tt>clicked()</tt> signal to the form's<!-- index accept() --> <tt>accept()</tt> slot. The<!-- index accept() --> <tt>accept()</tt> slot notifies the dialog's caller that the dialog is no longer required; since our dialog is our main window this will close the application. Preview the form (press <b>Ctrl+T</b>); click the <b>Quit</b> button. The button works visually but does nothing. Press <b>Esc</b> or close the preview window to leave the preview.</p><!-- index Signals and Slots --><!-- index Slots!Signals and Slots --><p>Click the <b>Connect Signals/Slots</b> toolbar button. Click the Quit button, drag to the form and release. The <em>Edit Connections</em> dialog will pop up. The top left hand list box lists the Signals that the widget we've clicked can emit. At the top right is a combobox which lists the form and its widgets; any of these are candidates for receiving signals. Since we released on the form rather than a widget the slots combobox shows the form's name, 'MulticlipForm'. Beneath the combobox is a list box which shows the slots available in the form or widget shown in the combobox. Note that only those slots that can be connected to the highlighted signal are shown. If you clicked a different signal, for example the<!-- index --> toggled() <tt>toggled()</tt> signal, the list of available slots would change. Click the<!-- index clicked() \SignalOrSlot clicked() --> signal, then click the<!-- index accept() \SignalOrSlot accept() slot. --> The connection will be shown in the Connections list box. Click <b>OK</b>.</p><p align="center"><img align="middle" src="qd-chapdialog-signalsandslots.png" width="663" height="465"></p><blockquote><p align="center"><em>Connecting the clicked() Signal to the accept() Slot</em></p></blockquote><p>We will make lots of signal/slot connections as we work through the examples, including connections to our own custom slots. Signal/slot connections (using pre-defined signals and slots) work in preview mode. Press <b>Ctrl+T</b> to preview the form; click the form's <b>Quit</b> button. The button now works correctly.</p><h4><a name="6-2"></a>Creating and Connecting Custom Slots</h4><!-- index Signals and Slots --><!-- index Subclassing --><p>In the first version of <em>Qt Designer</em> you could create the signatures of your custom slots and make the connections, but you could not implement your slots directly. Instead you had to subclass the form and code your slots in the subclass. The subclassing approach is still available, and makes sense in some situations. But now you can implement your slots directly in <em>Qt Designer</em>, so for many dialogs and windows subclassing is no longer necessary. (<em>Qt Designer</em> stores the slot implementations in a <tt>.ui.h</tt> file; see <a href="designer-manual-4.html#3-2">The ui.h extension approach</a> in <a href="designer-manual-4.html">The Designer Approach</a> chapter for more about these files.)</p><p>The multiclip application requires four slots, one for each button, but only three need to be custom slots since we connected a signal to a pre-defined slot to make the Quit button functional. We need a slot for the Add Clipping button; this will add the current clipping to the list box. The Copy Previous button requires a slot which will copy the selected list box item to the current clipping line edit (and to the clipboard). The Delete Clipping button needs a slot to delete the current clipping and the current list box item. We will also need to write some initialization code so that when the application starts it will put the current clipboard text (if any) into the line edit. The code is written directly in <em>Qt Designer</em>; the snippets are taken from the generated <tt>qt/tools/designer/examples/multiclip/multiclip.ui.h</tt> file.</p><!-- index Clipboard --><p>We'll need Qt's global clipboard object throughout the code which would mean calling<!-- index QApplication::clipboard() \Func --> QApplication::clipboard() or<!-- index qApp->clipboard() --> <tt>qApp->clipboard()</tt> in several places. Rather than perform all these function calls we'll keep a pointer to the clipboard in the form itself. Click the Source tab of the Object Explorer. (If the Object Explorer isn't visible click <b>Window|Views|Object Explorer</b>.) The Source tab shows us the functions in our form, the class variables, the forward declarations and the names of the include files we've asked for.</p><!-- index Forward declarations --><!-- index Includes --><!-- index Adding!Code --><!-- index Adding!Forward declarations --><!-- index Adding!Includes --><!-- index Adding!Class variables --><!-- index Deleting!Forward declarations --><!-- index Deleting!Includes --><!-- index Deleting!Class variables --><!-- index Class variables --><!-- index Forms!Forward declarations --><!-- index Forms!Class variables --><!-- index Forms!Code editing --><p>Right click the Class Variables item (near the bottom; you may have to click the scrollbar), then click <b>New</b> on the popup menu. (If there had been any existing variables the popup menu would also have a Delete option.) Type in 'QClipboard *cb;' and press <b>Enter</b>. We will create an<!-- index init() --> <tt>init()</tt> function in which we will assign this pointer to Qt's global clipboard object. We also need to declare the clipboard header file. Right click Includes (in Declaration), then click <b>New</b>. Type in '<qclipboard.h>' and press <b>Enter</b>. Since we need to refer to the global application object, <tt>qApp</tt>, we need to add another include declaration. Right click Includes (in Implementation), then click <b>New</b>. Type in '<qapplication.h>' and press <b>Enter</b>. The variable and declarations will be included in the code generated from <em>Qt Designer</em>'s<!-- index .ui --> <tt>.ui</tt> file.</p><p>We will invoke <em>Qt Designer</em>'s code editor and write the code.</p><!-- index Code Editing --><!-- index init() --><p>We'll create the <tt>init()</tt> function first. One way of invoking the code editor is to click the Source tab, then click the name of the function you want to work on. If you have no functions or wish to create a new function you need to use the Source tab. Right click the 'protected' item in the Source tab's Slots list, then left click <b>New</b> to launch the <em>Edit Slots</em> dialog. Change the slot's name from 'newSlot' to 'init()' then click <b>OK</b>. You can then click inside the editor window that appears to enter your code.</p><p>Note that you are not forced to use <em>Qt Designer</em>'s code editor; so long as you add, delete and rename your slots all within <em>Qt Designer</em>, you can edit the implementation code for your slots using a separate external editor and <em>Qt Designer</em> will preserve the code you write.</p><pre> void MulticlipForm::init() { lengthLCDNumber->setBackgroundColor( darkBlue ); currentLineEdit->setFocus(); cb = qApp-><a href="qapplication.html#clipboard">clipboard</a>(); <a href="qobject.html#connect">connect</a>( cb, SIGNAL( dataChanged() ), SLOT( dataChanged() ) ); if ( cb->supportsSelection() ) <a href="qobject.html#connect">connect</a>( cb, SIGNAL( selectionChanged() ), SLOT( selectionChanged() ) ); dataChanged(); }</pre> <p>The first couple of lines change the LCD number's background color and make the form start with the focus in the line edit. We take a pointer to Qt's global clipboard and keep it in our class variable, cb. We connect the clipboard's<!-- index dataChanged() \SignalOrSlot --> dataChanged() signal to a slot called<!-- index dataChanged() --> <tt>dataChanged()</tt>; we will create this slot ourselves shortly. If the clipboard supports selection (under the X Window system for example), we also connect the clipboard's<!-- index --> selectionChanged() <tt>selectionChanged()</tt> signal to a slot of the same name that we will create. Finally we call our<!-- index --> dataChanged() <tt>dataChanged()</tt> slot to populate the line edit with the clipboard's text (if any) when the application begins.</p><p>Since we've referred to the<!-- index dataChanged() --> <tt>dataChanged()</tt> and<!-- index selectionChanged() --> <tt>selectionChanged()</tt> slots we'll code them next, starting with<!-- index dataChanged() --> <tt>dataChanged()</tt>.</p><pre> void MulticlipForm::dataChanged() { <a href="qstring.html">QString</a> text; <a href="#text-prop">text</a> = cb->text(); clippingChanged( <a href="#text-prop">text</a> ); if ( autoCheckBox->isChecked() ) addClipping(); }</pre> <p>We take a copy of the clipboard's text and call our own <tt>clippingChanged()</tt> slot with the text we've retrieved. If the user has checked the Auto Add Clippings checkbox we call our <tt>addClipping()</tt> slot to add the clipping to the list box.</p><!-- index Clipboard!Cross-platform --><!-- index Cross-platform!Clipboard --><!-- index Windows, Microsoft --><p>The<!-- index selectionChanged() \SignalOrSlot selectionChanged() slot is --> only applicable under the X Window System. Users of MS Windows can still include the code to ensure that the application works multiplatform.</p><pre> void MulticlipForm::selectionChanged() { cb->setSelectionMode( TRUE ); dataChanged(); cb->setSelectionMode( FALSE ); }</pre> <p>We tell the clipboard to use selection mode, we call our<!-- index --> dataChanged() <tt>dataChanged()</tt> slot to retrieve any selected text, then set the clipboard back to its default mode.</p><p>In the<!-- index dataChanged() \SignalOrSlot dataChanged() slot we called --> another custom slot, <tt>clippingChanged()</tt>.</p><pre> void MulticlipForm::clippingChanged( const <a href="qstring.html">QString</a> & clipping ) { currentLineEdit->setText( clipping ); lengthLCDNumber->display( (int)clipping.<a href="qstring.html#length">length</a>() ); }</pre> <p>We set the line edit to whatever text is passed to the <tt>clippingChanged()</tt> slot and update the LCD number with the length of the new text.</p><!-- index Signals and Slots --><p>The next slot we'll code will perform the Add Clipping function. This slot is called by our code internally (see the<!-- index dataChanged() --> <tt>dataChanged()</tt> slot above), and when the user clicks the Add Clipping button. Since we want <em>Qt Designer</em> to be able to set up a connection to this slot instead of just typing it in the editor window we'll let <em>Qt Designer</em> create its skeleton for us. Click <b>Edit|Slots</b> to invoke the <em>Edit Slots</em> dialog. Click <b>New Slot</b> and replace the default name of 'new_slot()' with 'addClipping()'. There is no need to change the access specifier or return type. Now that we've created our slot we can implement it in the code editor where it has now appeared.</p><p>The Add Clipping button is used to copy the clipping from the Current Clipping line edit into the list box. We also update the length number.</p><pre> void MulticlipForm::addClipping() { <a href="qstring.html">QString</a> text = currentLineEdit->text(); if ( ! text.<a href="qstring.html#isEmpty">isEmpty</a>() ) { lengthLCDNumber->display( (int)text.<a href="qstring.html#length">length</a>() ); int i = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -