index.lxp@lxpwrap=x4274_252ehtm.htm

来自「GUI Programming with Python」· HTM 代码 · 共 1,446 行 · 第 1/3 页

HTM
1,446
字号
    <table border="0" cellspacing="0" cellpadding="3" width="100%"><tr><td>    <div align="center" id="bldcontent">      <a href="../default.htm"><img src="../images/opendocs.png" width="63" height="76" border="0"></a>      <br>      <div class="symbol">Your OpenSource Publisher&#153;</div>    </div>      </td></tr></table>    <div align="center" class="author">      	<a href="../products.lxp">Products</a>	&nbsp;|&nbsp;	<a href="../wheretobuy.lxp">Where to buy</a>	&nbsp;|&nbsp;	<a href="../bookstore.lxp">Retailers</a>	&nbsp;|&nbsp;	<a href="../faq.lxp">FAQ</a>	&nbsp;|&nbsp;        <a href="../writeforus.lxp">Write for Us.</a>        &nbsp;|&nbsp;        <a href="#contact">Contact Us.</a>  </div>    <table border="0" cellspacing="3" cellpadding="0" width="100%"><tr><td width="100%">      <div class="content">        <table border="0" cellspacing="2" cellpadding="0" width="100%"><tr><td width="100%">          <div align="center"><H4 CLASS="AUTHOR"><A NAME="AEN5">Boudewijn Rempt</A><br><a href="../../https@secure.linuxports.com/opendocs/default.htm"><img src=odpyqt125.png></a><br>ISBN: 0-97003300-4-4<br><a href="../../https@secure.linuxports.com/opendocs/default.htm">Available from bookstores everywhere or you can order it here.</a><p>You can download the source files for the book <a href="pyqtsrc.tgz">(code / eps) here.</a><hr></div>                    <HTML><HEAD><TITLE>Advanced Designer topics</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.72"><LINKREL="HOME"TITLE="GUI Programming with Python: QT Edition"HREF="book1.htm"><LINKREL="UP"TITLE="Qt Designer, BlackAdder and uic"HREF="c4079.htm"><LINKREL="PREVIOUS"TITLE="Qt Designer, BlackAdder and uic"HREF="c4079.htm"><LINKREL="NEXT"TITLE="Creating real applications with PyQt"HREF="p4627.htm"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">GUI Programming with Python: QT Edition</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><A accesskey="P" href="index.lxp@lxpwrap=c4079_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 11. Qt Designer, BlackAdder and uic</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=p4627_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1">Advanced Designer topics</A></H1><P>In this section, I will discuss more advanced topics in      working with BlackAdder Designer. These are: the connecting of      the individual widgets in your design using signals and slots,      the adding of custom widgets to the BlackAdder Designer palette,      and the actual generation and use of code with BlackAdder and      with the command-line utility pyuic. Finally, I will give some      attention to the generation of C++ code.</P><DIVCLASS="SECT2"><H2CLASS="SECT2">Defining signals and slots in Designer</A></H2><P>The widgets on a form often have a relationship to each        other. For instance, the <SPANCLASS="GUIBUTTON">OK</SPAN> button should ask        the form to close. Clicking on a button should move selected        items from one <TTCLASS="CLASSNAME">QListView</TT> to another. As        you have seen before, the standard way of linking widgets in        PyQt is by connecting signals with slots. You can create these        connections by simply drawing a line in BlackAdder designer.      </P><P>The first step is to create a design. Based on the        <SPAN><ICLASS="EMPHASIS">DIalog with Buttons (right)</I></SPAN> template, we        add two <TTCLASS="CLASSNAME">QListBox</TT>es and four buttons:</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>Initial design.</P></DIV></P></DIV><P> If you right-click on the form, and then choose      <SPANCLASS="GUIMENUITEM">Connections</SPAN>, you will see that there      are already two connections made, namely between the      <SPANCLASS="GUIBUTTON">OK</SPAN> button and the      <SPANCLASS="GUIBUTTON">Cancel</SPAN> button. It is our task to create      more connections.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>The two initial connections.</P></DIV></P></DIV><P>The goal of the buttons is to move items        from the left listbox to the right listbox, and back.        Double-arrowed buttons move everything, and single-arrowed        buttons move the selection. Select the connection button (        <IMGSRC="ch7/connection_button.eps">), and draw a line from the top button to any        place on the form. A dialog pops up that lets you select from        the signals of the button and the slots of the form. However,        there is no slot available that says something useful like        <TTCLASS="FUNCTION">slotAddAllFromLeftToRight()</TT>!</P><P>Does this mean that you are restricted to        the slots as defined in the PyQt library? Fortunately, no. You        can add your own slots &#8212; but only to the form, not to        the individual widgets. This is actually quite logical; later,        you will generate a Python class from the        <TTCLASS="FILENAME">.ui</TT> design. You then subclass the        generated Python code to add functionality.  Since you will        only subclass the form, the form is the only place you will be        able to add slots. If you want custom slots in your widgets,        you will have to add custom widgets to Designer.</P><P>Your subclass will be a descendant of the        entire form, so you can only add functionality to the form,        not to the widgets. Of course, you can also create custom        widgets with custom signals and slots, and use those instead        of the standard <TTCLASS="CLASSNAME">QListBox</TT>. I will        discuss the technique for adding custom widgets in the next        section.</P><P>Lets go ahead and add our custom slots to        the form. This is quite easy. Select the        <SPANCLASS="GUIMENUITEM">Slots</SPAN> menu item from the        <SPANCLASS="GUIMENU">Edit</SPAN> menu, and press the <SPANCLASS="GUIBUTTON">New          Slot</SPAN> button. Now you can edit the text in the        <SPANCLASS="GUIBUTTON">Slot Properties</SPAN> text field. Type the        name of the slot, and then enter the        <SPAN><ICLASS="EMPHASIS">types</I></SPAN> of the arguments the slot should be        called with, between brackets. This is not useful in our case,        since we will call the slots with the        <TTCLASS="FUNCTION">clicked()</TT> signal of the buttons, and        these don't pass on an argument.</P><P>Define the following four slots:</P><P></P><UL><LI><P>slotAddAll()</P></LI><LI><P>slotAddSelection()</P></LI><LI><P>slotRemoveAll()</P></LI><LI><P>slotRemoveSelection()</P></LI></UL><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>All slots are defined.</P></DIV></P></DIV><P>Now, you can connect the <TTCLASS="FUNCTION">clicked()</TT> signal of        each button to the right slot.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>All connections are made.</P></DIV></P></DIV><P>The Access specifier in the slot definition dialog is only        important if you want to migrate your designs to C++ at some        time. "Public" means that all classes in your C++ program have        access to those slots; protected means that only the generated        class itself and its subclasses can access the slot.        &#8216;Protected is as if the slotname were prefixed with a double        underscore in Python.</P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">Adding your own widgets</A></H2><P>Not only can you add your own slots to the forms you        design with BlackAdder, but you can also create custom widgets,        and use those widgets in other designs. The design shown in        the previous section &#8212; two listboxes and a few buttons to move        items from left to right, and vice-versa &#8212; is something that's        quite often needed, and is a prime candidate to turn into a        widget.</P><P>Open the <TTCLASS="FILENAME">connections.ui</TT> file, and        create a new <TTCLASS="FILENAME">.ui</TT> file based on the widget        template. Copy everything from the form to the widget, except,        of course, the <SPANCLASS="GUIBUTTON">OK</SPAN>,        <SPANCLASS="GUIBUTTON">Cancel</SPAN> and <SPANCLASS="GUIBUTTON">Help</SPAN>        buttons. Perhaps you will have to do the layout again; if so, use a        grid layout. Create the slots again, this time for the widget,        and connect them.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>The DoubleListBox widget design.</P></DIV></P></DIV><P>Choose <SPANCLASS="GUIMENUITEM">Compile Form</SPAN> from the        <SPANCLASS="GUIMENU">File</SPAN> menu. This will generate a Python file that        implements your design. For now, this is enough. As I will show later,        you should subclass the generated Python file and add some real        logic, and perhaps a few signals.</P><P>For now, we have a custom component, designed with BlackAdder and        implemented in Python. This component we will add to the BlackAdder        components palette, and use it in a dialog.</P><P>Choose <SPANCLASS="GUIMENUITEM">Edit Custom Widgets</SPAN> from the        <SPANCLASS="GUISUBMENU">Custom</SPAN> submenu in the <SPANCLASS="GUIMENU">Tools</SPAN>        menu. This will open a rather complicated dialog that lets you add new        widgets.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>Adding a custom widget.</P></DIV></P></DIV><P>You must type the name of the Python class &#8212; in this case        <TTCLASS="CLASSNAME">DoubleListBox</TT> &#8212; in the Class text field. The        headerfile text field refers ostensibly to a C++ header file; but        BlackAdder assumes that it refers to a Python file. Enter        <TTCLASS="FILENAME">wdglistbox</TT>, if that is the name you saved your        custom widget under. Do not add the extension. The choice between local        and global only has a meaning for C++ and defines the type of        include.</P><P>The rest of the fields are less vital. You can create a        pixmap that represents your widget; if you don't, the green        Trolltech logo will take be used a placeholder.  You can give        a default size hint and size policy. For example, if you want the double        listbox to take as much space as it can get, set both        policies to <SPAN><ICLASS="EMPHASIS">expanding</I></SPAN>. Our double listbox        cannot contain other widgets (it is not like a groupbox), and        therefore we don't check the <SPANCLASS="GUIBUTTON">Container          Widget</SPAN> checkbox.</P><P>In the other tabs, we can enter the slots and signals that our        widget knows; this is only useful for slots and widgets that        have a meaning to the outside world. The four special slots defined in        the previous section are for internal use. In a subclass of        DoubleListBox, we might define a few extra signals, like:</P><P></P><UL><LI><P>sigItemAdded(ListViewItem)</P></LI><LI><P>sigItemDeleted(ListViewItem)</P></LI></UL><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>Adding signals to a custom widget.</P></DIV></P></DIV><P>Note that we give a listviewitem as an argument to these signals;        Python signals do have arguments, but they are untyped. Slots are not        relevant for this widget, and neither are properties.</P><P>If you press <SPANCLASS="GUIBUTTON">OK</SPAN> a new item        will be added to the toolbars, which you can select and put on        a form. If you do so, you will see that the icon is also used

⌨️ 快捷键说明

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