📄 c4807.htm
字号:
<HTML><HEAD><TITLE>Actions: menus, toolbars and accelerators</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="Creating real applications with PyQt"HREF="p4627.htm"><LINKREL="PREVIOUS"TITLE="Project layout"HREF="x4782.htm"><LINKREL="NEXT"TITLE="Menus"HREF="x4954.htm"></HEAD><BODYCLASS="CHAPTER"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"><AHREF="x4782.htm"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="x4954.htm"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="CH25">Chapter 13. Actions: menus, toolbars and accelerators</A></H1><DIVCLASS="TOC"><DL><DT><B>Table of Contents</B></DT><DT><AHREF="c4807.htm#AEN4824">Actions</A></DT><DT><AHREF="x4954.htm">Menus</A></DT><DT><AHREF="x4974.htm">Toolbars</A></DT><DT><AHREF="x5021.htm">Keyboard accelerators</A></DT><DT><AHREF="x5049.htm">Setting an application icon</A></DT></DL></DIV><P>In this chapter we investigate adding the command structure to the application framework we developed in <AHREF="c4631.htm">Chapter 12</A>. This consists of <TTCLASS="CLASSNAME">QAction</TT> objects that are added to toolbars and menu bars, and that can provide keyboard accelerators.</P><P>Creating <TTCLASS="CLASSNAME">QActions</TT> and populating your toolbars and menus with them is not an exciting task, but it is necessary for any GUI application. Let's take a deeper look at the possibilities of actions, toolbars and menus.</P><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="AEN4824">Actions</A></H1><P>We first encountered the <TTCLASS="CLASSNAME">QAction</TT> class in <AHREF="c2591.htm">Chapter 10</A>. To recap briefly, <TTCLASS="CLASSNAME">QAction</TT> is a model of a well-defined action that a user can perpetrate against your application, or the data of your application models. This a very powerful concept. Previously, you would have to create menu items and connect them to slots, create toolbar items and connect them to slots, and create keyboard shortcuts and connect them to slots, <SPAN><ICLASS="EMPHASIS">too</I></SPAN>.</P><P>Keeping everything synchronized is difficult, and the whole process often leads to a horrible mess. Combine this with the possibility that you might want to disable some action—such as redo, when there's nothing to redo—and you're suddenly writing lots of duplicated code. And then, of course, you get to the point where your users want to modify the contents of the toolbar...</P><P>By bringing all the user-interface characteristics of actions together in the <TTCLASS="CLASSNAME">QAction</TT> class, most of the mess can be avoided. The <TTCLASS="CLASSNAME">QAction</TT> class tracks the following interface elements:</P><P></P><UL><LI><P>Pull-down menus text</P></LI><LI><P>Tooltip text</P></LI><LI><P>What's This text</P></LI><LI><P>Statusbar tips</P></LI><LI><P>Keyboard accelerators</P></LI><LI><P>Associated icons</P></LI><LI><P>Enabled/disabled</P></LI><LI><P>Toggled on or off</P></LI></UL><P>For each of these properties, there is a set function; although you can also set some properties in the constructor of <TTCLASS="CLASSNAME">QAction</TT>. Here is an annotated example of a complete <TTCLASS="CLASSNAME">QAction</TT> definition:</P><DIVCLASS="EXAMPLE"><ANAME="AEN4870"></A><P><B>Example 13-1. Defining a complex toggle action</B></P><PRECLASS="PROGRAMLISTING"> planAction=QAction(self) <ANAME="ACTION.CONSTRUCTOR"><IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A> planAction.setIconSet(QIconSet(QPixmap(plan))) <ANAME="ICONSET"><IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A> planAction.setText("Plan") <ANAME="SETTEXT"><IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A> planAction.setMenuText("&Plan ...") <ANAME="MENUTEXT"><IMGSRC="images/callouts/4.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(4)"></A> planAction.setOn(0) planAction.setStatusTip("Enable the cunning plan") <ANAME="STATUSTIP"><IMGSRC="images/callouts/6.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(6)"></A> planAction.setToolTip("Enables the cunning plan") <ANAME="TOOLTIP"><IMGSRC="images/callouts/7.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(7)"></A> planAction.setWhatsThis( <ANAME="WHATSTHIS"><IMGSRC="images/callouts/8.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(8)"></A>"""PlanSelecting plan enables the cunning plan for this window.""") planAction.setAccel(QAccel.stringToKey("CTRL+C"),) <ANAME="ACCEL"><IMGSRC="images/callouts/9.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(9)"></A> planAction.setToggleAction(1) <ANAME="ON"><IMGSRC="images/callouts/10.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(10)"></A> </PRE><DIVCLASS="CALLOUTLIST"><DLCOMPACT="COMPACT"><DT><AHREF="c4807.htm#ACTION.CONSTRUCTOR"><IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A></DT><DD>There are three constructors that create a <TTCLASS="CLASSNAME">QAction</TT> with some of the properties already set. However, I find it nicer to create an empty <TTCLASS="CLASSNAME">QAction</TT> and set everything by hand. Besides, the next thing we would like to do is to read in the definition of a <TTCLASS="CLASSNAME">QAction</TT> from an XML file or a Python dictionary, and automatically generate the actions. If you want to do this, it is just as easy to set every property separately.</DD><DD><P>One important parameter is the <TTCLASS="VARNAME">parent</TT> to the <TTCLASS="CLASSNAME">QAction</TT>. You can create groups of <TTCLASS="CLASSNAME">QAction</TT>s — <TTCLASS="CLASSNAME">QActionGroup</TT>s. A <TTCLASS="CLASSNAME">QActionGroup</TT> is a type of <TTCLASS="CLASSNAME">QAction</TT> that functions like a type of <TTCLASS="CLASSNAME">QGroupBox</TT>: it can group actions into mutually exclusive choices. The whole group of actions can be added to a menu.</P></DD><DT><AHREF="c4807.htm#ICONSET"><IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A></DT><DD>The set of icons you associate with an action is used to paint the toolbar buttons. They are also used to decorate the pull-down menus. <TTCLASS="CLASSNAME">QIconSet</TT> can generate icons in different sizes and with an active, normal or disabled look all by itself, based on one icon—or you can explicitly set icons of different sizes. You can provide a user option to toggle <TTCLASS="CLASSNAME">QMainWindow</TT>.<TTCLASS="FUNCTION">setUsesBigPixmaps</TT> on or off. This decides whether the toolbars will be drawn with big icons, or small ones.</DD><DT><AHREF="c4807.htm#SETTEXT"><IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A></DT><DD>This is a generic text that can be used where a more specific text hasn't been set. For instance, if you enable captions in toolbars with <TTCLASS="CLASSNAME">QMainWindow</TT>.<TTCLASS="FUNCTION">setUsesTextLabel()</TT>, then this text will be used. It will also be used for pulldown menu texts, unless you set those explicitly with <TTCLASS="FUNCTION">setMenuText()</TT>. </DD><DT><AHREF="c4807.htm#MENUTEXT"><IMGSRC="images/callouts/4.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(4)"></A></DT><DD>By setting the menutext explicitly, you can add keyboard shortcuts (like alt-p in this case), or the three dots that indicate that a dialog window will open. You wouldn't want the shortcut to show up on toolbar captions—they don't work there, so you can set them in the menu text, by prefixing an ampersand (&) to the shortcut letter.</DD><DT><AHREF="c4807.htm#TOGGLEACTION"><IMGSRC="images/callouts/5.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(5)"></A></DT><DD>Sometimes, a certain action toggles an application state on or off. Examples include setting toolbar captions of toolbar icon sizes, or bold or normal fonts. By grouping actions in action groups, you can create mutually exclusive groups (such as centered, justified or ragged text in a text editor).</DD><DT><AHREF="c4807.htm#STATUSTIP"><IMGSRC="images/callouts/6.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(6)"></A></DT><DD>This text appears in the statusbar of the mainwindow when the user presses but doesn't release the menu option or toolbar button associated with the action.</DD><DT><AHREF="c4807.htm#WHATSTHIS"><IMGSRC="images/callouts/8.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(8)"></A></DT><DD>This is a longer text that appears in the form of a yellow note when the user presses the optional ‘what's this' button, which appears on the toolbar.</DD><DT><AHREF="c4807.htm#ACCEL"><IMGSRC="images/callouts/9.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(9)"></A></DT><DD>The keyboard accelerator that activates this action—for instance, pressing the control and the s key together—will trigger the <TTCLASS="FUNCTION">activated()</TT> signal, which might be connected to the <TTCLASS="FUNCTION">save()</TT> slot function. It is easiest to construct this using <TTCLASS="CLASSNAME">QAccel</TT>'s <TTCLASS="FUNCTION">stringToKey()</TT> function. Not only is this very convenient, it can also be translated to languages where a different shortcut key is preferred, by using either pygettext or PyQt's <TTCLASS="FUNCTION">tr()</TT>. See <AHREF="c8212.htm">Chapter 25</A> for more information on internationalizing an application.</DD><DT><AHREF="c4807.htm#ON"><IMGSRC="images/callouts/10.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(10)"></A></DT><DD>Of course, if you create a toggle action, it is nice to be able to set the initial state—which is what this does.</DD></DL></DIV></DIV><P>The <TTCLASS="CLASSNAME">QAction</TT> class can emit two signals:</P><P></P><UL><LI><P>activated()</P></LI><LI><P>toggled(boolean)</P></LI></UL><P>By connecting these signals to the correct slots (either directly in the document, or proxy slots defined in the application interface), you have encapsulated the entire behavior of your interface.</P><PRECLASS="PROGRAMLISTING"> self.connect(planaction, SIGNAL("activated()"), self.slotExecuteCunningPlan) </PRE><P>or, for a toggle action:</P><PRECLASS="PROGRAMLISTING"> self.connect(planaction, SIGNAL("toggled(bool)"), self.slotActivateCunningPlan) </PRE><P>All that remains, is to add the actions to pulldown menus or toolbars:</P><PRECLASS="PROGRAMLISTING"> self.planaction.addTo(self.planMenu) self.planaction.addTo(self.toolBar) </PRE></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="x4782.htm"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="book1.htm"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="x4954.htm"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Project layout</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="p4627.htm"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Menus</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -