index.lxp@lxpwrap=c6351_252ehtm.htm
来自「GUI Programming with Python」· HTM 代码 · 共 1,439 行 · 第 1/3 页
HTM
1,439 行
used with Base.</P></LI><LI><P>Button - general button background color</P></LI><LI><P>ButtonText - for button texts</P></LI><LI><P>Light - lighter than Button color. </P></LI><LI><P>Midlight - between Button and Light. </P></LI><LI><P>Dark - darker than Button. </P></LI><LI><P>Mid - between Button and Dark. </P></LI><LI><P>Shadow - a very dark color. </P></LI><LI><P>Highlight - a color to indicate a selected or highlighted item. </P></LI><LI><P>HighlightedText - a text color that contrasts to Highlight.</P></LI></UL><P>All colors are normally calculated from the Background color. Setting the background color of the editor with the convenience function <TTCLASS="FUNCTION">setBackgroundColor()</TT> won't have an effect; we must use the Base color in the relevant <TTCLASS="CLASSNAME">QColorGroup</TT>.</P><P>This system is certainly quite complex, but it allows for tremendous flexibility. Using it isn't too arduous. First, we retrieve the palette from the editor widget:</P><PRECLASS="PROGRAMLISTING"> pl = self.txtEditorPreview.palette() pl.setColor(QColorGroup.Base, self.textBackgroundColor) pl.setColor(QColorGroup.Text, self.textForegroundColor) </PRE><P>Then we can use the function <TTCLASS="FUNCTION">setColor</TT>, which takes a colorgroup role and a <TTCLASS="CLASSNAME">QColor</TT> as arguments. Note that if we use these functions to change the colors of a widget after it has been shown for the first time, we must call <TTCLASS="FUNCTION">repaint(TRUE)</TT> to force the widget to redraw itself. Otherwise Qt's highly optimized drawing engine becomes confused. This will be done in the slot function that's connected to the <TTCLASS="FUNCTION">clicked()</TT> signal of the color choice buttons.</P><PRECLASS="PROGRAMLISTING"> def initInterfaceTab(self): self.initStylesCombo() self.initWindowViewCombo() self.lblBackgroundColor.setBackgroundColor(self.MDIBackgroundColor) self.connect(self.bnWorkspaceBackgroundColor, SIGNAL("clicked()"), self.slotWorkspaceBackgroundColor) </PRE><P>The preview for the interface style is initialized in <TTCLASS="FUNCTION">initWindowViewCombo</TT>. Note that <TTCLASS="CLASSNAME">QLabel</TT> is rather more simple in its needs than <TTCLASS="CLASSNAME">QMultiLineEdit</TT> as regards colors. Here, you can just use the convenience function <TTCLASS="FUNCTION">setBackgroundColor</TT> (<TTCLASS="FUNCTION">setEraseColor()</TT> in Qt 3) to show the preview color for the MDI workspace.</P><PRECLASS="PROGRAMLISTING"> def initDocumentTab(self): self.initEncodingCombo() self.chkAddNewLine.setChecked(kalamconfig.get("forcenewline")) </PRE><P>This must be the least complex tab, but no doubt we will be adding to it during the course of our development of <SPANCLASS="APPLICATION">Kalam</SPAN>.</P><PRECLASS="PROGRAMLISTING"> def initStylesCombo(self): self.cmbStyle.clear() styles = kalamconfig.stylesDictionary.keys() styles.sort() try: currentIndex = styles.index(kalamconfig.Config.style) except: currentIndex = 0 kalamconfig.setStyle(styles[0]) self.cmbStyle.insertStrList(styles) self.cmbStyle.setCurrentItem(currentIndex) self.connect(self.cmbStyle, SIGNAL("activated(const QString &)"), self.setStyle) </PRE><P>To make life a lot easer, we have defined a dictionary that maps user-understandable style names to <TTCLASS="CLASSNAME">QStyle</TT> classes in <TTCLASS="FILENAME">kalamconfig</TT>. Note that we need, in order to find out which one is the current style, not the result of <TTCLASS="FUNCTION">kalamconfig.get("style")</TT>, since that returns a <TTCLASS="CLASSNAME">QStyle</TT> object, but the actual string in the <TTCLASS="CLASSNAME">Config</TT><TTCLASS="VARNAME">.style</TT> variable.</P><PRECLASS="PROGRAMLISTING"># kalamconfig.py - styles dictionarystylesDictionary = { "Mac OS 8.5" : QPlatinumStyle, "Windows 98" : QWindowsStyle, "Motif" : QMotifStyle, "Motif+" : QMotifPlusStyle, "CDE" : QCDEStyle } </PRE><P>The keys of this dictionary are used to fill the style combo. Python dictionaries are unordered, and to ensure that the same style is alwas at the same place in the combobox, we have to sort the list of keys. Sorting a list is done <SPAN><ICLASS="EMPHASIS">in place</I></SPAN> in Python, and that means that calling <TTCLASS="FUNCTION">sort()</TT> on a list doesn't return a list. If we'd written:</P><PRECLASS="PROGRAMLISTING"> styles = kalamconfig.stylesDictionary.keys().sort() </PRE><P>instead, styles would have been set to <TTCLASS="VARNAME">None</TT>... Activating an entry in the styles combobox emits a signal that is routed to the <TTCLASS="FUNCTION">setStyle()</TT> function:</P><PRECLASS="PROGRAMLISTING"> def setStyle(self, style): kalamconfig.set("style", str(style)) qApp.setStyle(kalamconfig.get("style")()) </PRE><P>Changing a style is instantaneous in <SPANCLASS="APPLICATION">Kalam</SPAN>, if only because it is fun to run through all the styles and see the application changing under your fingers. Therefore, we immediately update the style setting, and call <TTCLASS="FUNCTION">qApp.setStyle()</TT> to propagate the changes to the application widgets.</P><PRECLASS="PROGRAMLISTING"> def initWindowViewCombo(self): self.cmbWindowView.clear() workspaces = kalamconfig.workspacesDictionary.keys() workspaces.sort() try: currentIndex = workspaces.index(kalamconfig.Config.workspace) except: currentIndex = 0 kalamconfig.setWorkspace(workspaces[0]) self.cmbWindowView.insertStrList(workspaces) self.cmbWindowView.setCurrentItem(currentIndex) self.connect(self.cmbWindowView, SIGNAL("activated(const QString &)"), self.setWorkspacePreview) </PRE><P>Setting up the workspace selection combobox is similar to setting up the styles combobox. The only interesting point is the connection to <TTCLASS="FUNCTION">setWorkspacePreview</TT>. This function updates the small image that shows what each option means. These images were made from snapshots, and scaled down with Pixie, a KDE graphics application (which is now obsolete).</P><PRECLASS="PROGRAMLISTING"> def setWorkspacePreview(self, workspace): workspace = str(workspace) + ".png" # XXX - when making installable, fix this path pixmap = QPixmap(os.path.join("./pixmaps", workspace)) self.pxViewSample.setPixmap(pixmap) </PRE><P>As you can see, application development is messy, and I don't want to hide all the mess from you. Later, when we make the application distributable in <A href="index.lxp@lxpwrap=c8349_252ehtm.htm">Chapter 26</A>, we will have to come back to this function and devise a way to make <SPANCLASS="APPLICATION">Kalam</SPAN> retrieve its pictures from the installation directory.</P><PRECLASS="PROGRAMLISTING"> def initEncodingCombo(self): self.cmbEncoding.clear() encodings = kalamconfig.codecsDictionary.keys() encodings.sort() try: currentIndex = encodings.index(kalamconfig.get("encoding")) except: currentIndex = 0 Config.encoding = encodings[0] self.cmbEncoding.insertStrList(encodings) self.cmbEncoding.setCurrentItem(currentIndex) </PRE><P>The list of encodings is defined in <TTCLASS="FILENAME">kalamconfig</TT>, just like the list of styles and interface types:</P><PRECLASS="PROGRAMLISTING"># kalamconfig.py - encodings dictionarycodecsDictionary = { "Unicode" : "utf8", "Ascii": "ascii", "West Europe (iso 8859-1)": "iso-8859-1", "East Europe (iso 8859-2)": "iso-8859-2", "South Europe (iso 8859-3)": "iso-8859-3", "North Europe (iso 8859-4)": "iso-8859-4", "Cyrilic (iso 8859-5)": "iso-8859-5", "Arabic (iso 8859-6)": "iso-8859-6", "Greek (iso 8859-7)": "iso-8859-7", "Hebrew (iso 8859-8)": "iso-8859-8", "Turkish (iso 8859-9)": "iso-8859-9", "Inuit (iso 8859-10)": "iso-8859-10", "Thai (iso 8859-11)": "iso-8859-11", "Baltic (iso 8859-13)": "iso-8859-13", "Gaeilic, Welsh (iso 8859-14)": "iso-8859-14", "iso 8859-15": "iso-8859-15", "Cyrillic (koi-8)": "koi8_r", "Korean (euc-kr)": "euc_kr"} </PRE><P>A <TTCLASS="CLASSNAME">QMultiLineEdit</TT> widget always used Unicode internally, but these codecs are used as a default setting for loading and saving files. Users load an ascii file, edit it in Unicode, and save it back to ascii. Theoretically, you can retrieve the users preferences from his locale. The operating system defines the preferred encoding, but people seldom work with one encoding, and <SPANCLASS="APPLICATION">Kalam</SPAN> is meant to provide users with a choice.</P><P>While the selection of codecs in Python is large, not all important encodings are available from Python. Japanese (jis, shift-jis, euc-jp), Chinese (gbk) and Tamil (tscii) are only available in Qt (QTextCodec classes), and not in Python. Codecs for the tiscii encoding used for Devagari are not available anywhere. You can download separate Japanese codecs for Python from http://pseudo.grad.sccs.chukyo-u.ac.jp/~kajiyama/python/. (euc-jp, shift_jis, iso-2022-jp)</P><P> Note also that iso-8859-8 is visually ordered, and you need Qt 3.0 with the QHebrewCodec to translate iso-8859-8 correctly to Unicode.</P><PRECLASS="PROGRAMLISTING"> def slotForegroundColor(self): color = QColorDialog.getColor(self.textForegroundColor) if color.isValid(): pl = self.txtEditorPreview.palette() pl.setColor(QColorGroup.Text, color) self.textForegroundColor = color self.txtEditorPreview.repaint(1) def slotBackgroundColor(self): color = QColorDialog.getColor(self.textBackgroundColor) if color.isValid(): pl = self.txtEditorPreview.palette() pl.setColor(QColorGroup.Base, color) self.textBackgroundColor = color self.txtEditorPreview.repaint(1) def slotWorkspaceBackgroundColor(self): color = QColorDialog.getColor(self.MDIBackgroundColor) if color.isValid(): self.MDIBackgroundColor = color self.lblBackgroundColor.setBackgroundColor(color) </PRE><P>Each of the color selection buttons is connected to one of these color slot functions. Note that <TTCLASS="CLASSNAME">QFontDialog</TT>, in contrast with <TTCLASS="CLASSNAME">QColorDialog</TT>, returns a tuple consisting of a <TTCLASS="CLASSNAME">QFont</TT> and a value that indicates whether the user pressed OK or Cancel. <TTCLASS="CLASSNAME">QColorDialog</TT> only returns a color; if the color is invalid, then the user pressed Cancel. This can be confusing, especially since an invalid <TTCLASS="CLASSNAME">QColor</TT> is just black. Note that we have to call <TTCLASS="FUNCTION">repaint(1)</TT>, here, to make sure the editor preview is updated.</P><PRECLASS="PROGRAMLISTING"> def slotFont(self): (font, ok) = QFontDialog.getFont(kalamconfig.getTextFont(), self) if ok: self.txtEditorPreview.setFont(font) self.textFont = font </PRE><P>The <TTCLASS="CLASSNAME">QFontDialog</TT> <SPAN><ICLASS="EMPHASIS">does</I></SPAN> return a tuple—and if <TTCLASS="VARNAME">ok</TT> is true, then we update the font of the preview and also set the <TTCLASS="VARNAME">textFont</TT> variable to reflect the users choice.</P><P>Finally, there's a bit of code appended to <TTCLASS="CLASSNAME">DlgSettings</TT>, to make it possible to run the dialog on its own (to test all functionality):</P><PRECLASS="PROGRAMLISTING">if __name__ == '__main__': a = QApplication(sys.argv) QObject.connect(a,SIGNAL('lastWindowClosed()'),a,SLOT('quit()')) w = DlgSettings() a.setMainWidget(w) w.show() a.exec_loop() </PRE></DIV
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?