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 &#38;)"),                     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 &#38;)"),                     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&#8212;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 + -
显示快捷键?