index.lxp@lxpwrap=x4274_252ehtm.htm
来自「GUI Programming with Python」· HTM 代码 · 共 1,446 行 · 第 1/3 页
HTM
1,446 行
to represent the widget on the form, instead of a more faithful representation of the widget. When you preview the form, you won't see the widget either; but wen you generate the form, everything will be all right.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>A form using the DoubleListBox custom widget..</P></DIV></P></DIV></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">Layout management</A></H2><P>It is possible to design your dialogs and widgets by plonking down elements, sizing them to your liking and placing them where you want, down to the last pixel. If you fix the size of the form and the font, you can have a perfect layout — but it will also be a layout that your users won't like. People want to resize dialogs, either to have more data visible at the same time, or to minimize the amount of space the dialog takes on their already crowded screens. Visually impaired users want to change the font size to something they <SPAN><ICLASS="EMPHASIS">can</I></SPAN> see. Furthermore, there are vast differences in default fonts between Windows systems and some other systems, like KDE, which define a different default font dependent upon screen resolution. Your pixel-precise dialog won't look so good if the user views it with a font that he chooses, not in terms of pixel size, but of points per inch — where an inch can have between 75 and 120 pixels. A twelve-point Helvetica has a lot more pixels if generated for a resolution of 120 pixels to the inch, then if it were generated for 75 pixels to the inch.</P><P>All these are good reasons to let the computer manage the layout for you. There are other reasons, too. With complex forms, doing the layout yourself quickly becomes a bore. If your application is used by people with a right-to-left alphabet, like Hebrew or Arabic, the whole layout should be mirrored. From version 3, Qt can do that for you, if only you let Qt manage your layouts. The same goes for the size of labels. If you pixel-position your controls to the width of the labels, then there won't be room for languages that use ‘fichier' for ‘file', or ‘annuleren' for ‘cancel'.</P><P>All these arguments have never before swayed developers to use automatic layout management, but with PyQt and BlackAdder, layout management is ridiculously easy (and certainly easier than manual layout). This, at least, should convert the developing masses to automatic layouting!</P><P>The Designer module of BlackAdder offers three layout managers, and a helpful tool called the <SPAN><ICLASS="EMPHASIS">spacer</I></SPAN>. The layout managers are:</P><P></P><UL><LI><P>horizontal</P></LI><LI><P>vertical</P></LI><LI><P>grid</P></LI></UL><P>By nesting layouts, together with the spacer and the sizepolicies and sizehints of each individual widget, you can create almost any layout. A good rule of thumb is perhaps that if your intended layout confuses the layout managers of the Designer, then it will probably also confuse your users.</P><P>A good layout is one that can be easily taken in with one look, and that neatly groups the various bits of data in the form. A good layout will also be simple enough that the form won't take an eternity to appear. Bear in mind that Python has to load the form, lay it out, and, most importantly, fill the various fields with relevant the data. The last step can take a lot of time. I once had to create a form that brought together about sixty pieces of information from more than twenty database tables. My client was not pleased when this form wouldn't appear in the required three seconds.</P><P>I've already discussed the classes behind the horizontal, vertical and grid layout managers: <TTCLASS="CLASSNAME">QLayout</TT>, <TTCLASS="CLASSNAME">QBoxLayout</TT>, <TTCLASS="CLASSNAME">QVBoxLayout</TT>, <TTCLASS="CLASSNAME">QHBoxLayout</TT> and <TTCLASS="CLASSNAME">QGridLayout</TT>.</P><P>You can influence the layouts by selecting them in the object hierarchy window. Interesting properties include <SPAN><ICLASS="EMPHASIS">LayoutSpacing</I></SPAN> and <SPAN><ICLASS="EMPHASIS">LayoutMargin</I></SPAN>. The first determines how much room there is between widgets; the second determines how much space the layout wants between itself and the border of the window or other layouts.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>Layout manager properties.</P></DIV></P></DIV><DIVCLASS="SECT3"><H3CLASS="SECT3">The Horizontal Layout Manager</A></H3><P>The horizontal layout manager lays the widgets out in one row, like the individual menu's in a menu bar, or the buttons at the bottom of a form based on the <SPAN><ICLASS="EMPHASIS">Dialog With Buttons (Bottom)</I></SPAN> dialog. </P><P>There are few widgets that are customarily laid out horizontally, most often widgets are grouped in vertical columns. The columns themselves can be grouped in a horizontal layout manager. </P></DIV><DIVCLASS="SECT3"><H3CLASS="SECT3">The Vertical Layout Manager</A></H3><P>The vertical layout manager puts widgets in one column. This can be very useful when creating a groupbox that contains radio buttons or checkboxes. You will very seldom want to layout radio buttons in a horizontal row. Another use is the column of buttons in the <SPAN><ICLASS="EMPHASIS">Dialog with Buttons (right)</I></SPAN> template. </P></DIV><DIVCLASS="SECT3"><H3CLASS="SECT3">The Grid Layout Manager</A></H3><P>The Grid Layout managers lays out your widgets in a square or oblong grid. If you want everything in your form to be managed in a grid, then you can simply select this layout manager from the toolbar, and then click somewhere on the background of the form. The Designer module is <SPAN><ICLASS="EMPHASIS">very</I></SPAN> clever, and will try to retain your current, manually created layout as far as possible. It can even create the difficult multi-column widgets automatically. </P></DIV><DIVCLASS="SECT3"><H3CLASS="SECT3">The Spacer object</A></H3><P>Of course, for all its cleverness, there are situations when the Designer simply cannot determine your meaning without some help. There is no Intention Layout Manager! One useful tool to let the layout manager know your intention is the spacer object. This is an invisible (at runtime) widget that pushes other widgets away. You can use a spacer either horizontally or vertically. If you use a spacer at both sides of a widget, they will push the widget to the middle. If you use only one spacer, it will push the widget to the other side. </P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>Playing with spacers.</P></DIV></P></DIV></DIV><DIVCLASS="SECT3"><H3CLASS="SECT3">What widgets can do to get the space they want</A></H3><P>Not every widget wants to hog all the space in a dialog. A combobox, for instance, has no reason to grow vertically, while a vertical scrollbar doesn't need to get any wider. You can set the horizontal and vertical sizepolicies of your widgets in the Designer module.</P><P>However, this will not always produce the results you want — in such a case, you might be reduced to setting minimum and maximum pixel widths by hand. This may be necessary if you have a listbox or combobox that expands without limit because one of the entries is as long as a fantasy trilogy without linebreaks. To curb the tendency of the listbox to usurp all the space in the dialog, you should set its maximum width to something sensible. Note also that, alas, the layout management of the forms in the designer doesn't work exactly the same as the layout management of the running forms. You can see the difference in the preview mode. </P><P>The sizepolicy works in concord with the result of calls to the <TTCLASS="FUNCTION">sizeHint ()</TT> function — this function returns the size the widget wants to be, and the <TTCLASS="FUNCTION">minimumSizeHint()</TT> function, which returns the absolute minimum size the widget can be. The following hints can be used for setting the sizepolicy of widgets:</P><P></P><UL><LI><P>fixed — what <TTCLASS="FUNCTION">sizeHint()</TT> says is law — smaller nor larger is acceptable. </P></LI><LI><P>minimum — the result of <TTCLASS="FUNCTION">sizeHint()</TT> is sufficient. It cannot be smaller, might be larger, but there's no use in growing. </P></LI><LI><P>maximum — what <TTCLASS="FUNCTION">sizeHint()</TT> returns is the max — the widget should not be expanded, but might be shrunk without detriment. </P></LI><LI><P>preferred — the <TTCLASS="FUNCTION">sizeHint()</TT> size is best, but the widget can be smaller without problems. It might be larger, but there's no earthly reason why it should. </P></LI><LI><P>minimumExpanding — the widget wants as much space as it can get — the more it gets, the better. No way it should shrink. </P></LI><LI><P>Expanding — the widget wants as much space as it can get, but it's still useful if it get less than the result of <TTCLASS="FUNCTION">sizeHint()</TT>. </P></LI></UL></DIV><DIVCLASS="SECT3"><H3CLASS="SECT3">Creating a complex form</A></H3><P> Let's try to create a really complicated form, just to see what the automatic layout engine can do. </P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>A quite complex dialog.</P></DIV></P></DIV><P>This dialog was created in the following steps:</P><P></P><OLTYPE="1"><LI><P>Create a new form — based the simple Dialog Template. </P></LI><LI><P>Create two pushbuttons and place them at the right top. </P></LI><LI><P>Create a vertical spacer item, below the buttons. </P></LI><LI><P>Collect the buttons and the spacer in a rubber band and select the vertical layout manager. Resize the layout to the height of the dialog. </P></LI><LI><P>Create the three listboxes, and resize them to roughly about the right size; put the three line editors below. </P></LI><LI><P>Select the listboxes and the lineedits in a rubber band, and select the grid layout — resize the complete layout about three-quarters the height of the dialog. </P></LI><LI><P>Create a groupbox below the constellation of listboxes and edit controls, and put, roughly vertically, three radio buttons in it. </P></LI><LI><P>Select the groupbox and click on the vertical layout manager button. Note that if you have the object browser open, you won't see this layout manager: the groupbox takes that function. </P></LI><LI><P>Create two checkboxes, next to each other, below the groupbox. </P></LI><LI><P>Select the listboxes, and select the horizontal layout manager. </P></LI><LI><P>Now select the form and then the grid layout manager. </P></LI></OL><P>The result should be quite pleasing — take a look at how Designer created the final grid layout. Perhaps it would be better to encase the checkboxes in a groupbox, too, but this is not essential. Some GUI design guidelines urge you to envelop everything but the <SPANCLASS="GUIBUTTON">OK</SPAN> and <SPANCLASS="GUIBUTTON">Cancel</SPAN> buttons (and perhaps the <SPANCLASS="GUIBUTTON">Help</SPAN> button if its in the same row or column) in a frame with a title. Personally, I'm in favor of that recommendation, but in this
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?