⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 index.lxp@lxpwrap=x6734_252ehtm.htm

📁 GUI Programming with Python
💻 HTM
📖 第 1 页 / 共 3 页
字号:
      function. The same instance of the dialog can be used for      different documents.</P><PRECLASS="PROGRAMLISTING">    def showFind(self, document, view):        FrmFindReplace.show(self)        self.bnFind.setDefault(TRUE)        self.setCaption("Find in " + document.title())        self.bnReplaceNext.hide()        self.bnReplaceAll.hide()        self.grpReplace.hide()        self.cmbFind.setFocus()        self.init(document, view)    def showReplace(self, document, view):        FrmFindReplace.show(self)        self.setCaption("Find and replace in " + document.title())        self.bnReplaceNext.show()        self.bnReplaceNext.setDefault(TRUE)        self.bnReplaceAll.show()        self.grpReplace.show()        self.cmbFind.setFocus()        self.init(document, view)      </PRE><P>As we discussed above, there are two show functions        (<TTCLASS="FUNCTION">showFind()</TT> and        <TTCLASS="FUNCTION">showReplace</TT>), each hides or shows the        widgets that are relevant. The show functions also call the        initialization function <TTCLASS="FUNCTION">init()</TT>.</P><PRECLASS="PROGRAMLISTING">    def init(self, document, view):        self.document = document        self.view = view        if view.hasSelection():            self.chkSelection.setChecked(TRUE)        self.setFindExtent()      </PRE><P>The <TTCLASS="FUNCTION">init()</TT>        function sets the document and view variables. Most of the        work is done directly on the view, making use of its        functionality for inserting, deleting and selecting text. This        is because whenever a string is found, it will be selected.        Asking the document to select a string will cause it to select        the string in all views of that document, which would be quite        confusing for the user.</P><P>If there is already a selection present        in the view, the "find in selection" checkbox is checked. This        is convenient, because when a user presses find after having        selected a section of text, he most likely wants the search to        be performed in that selection only.</P><P>The function        <TTCLASS="FUNCTION">setFindExtent()</TT> (which we will examine in        detail later in this section) determines which part of the        text should be searched: from the cursor position to the end,        to the beginning, or between the beginning and end of a        selection. The find routine keeps track of where it is within        a search extent, using the variable        <TTCLASS="VARNAME">self.currentPosition</TT>, which is initially        the same as the start position of the extent.</P><PRECLASS="PROGRAMLISTING">    #    # Slot implementations    #    def slotRegExp(self):        if self.radioRegexp.isChecked():            self.radioForward.setChecked(TRUE)            self.grpDirection.setEnabled(FALSE)        else:            self.grpDirection.setEnabled(TRUE)      </PRE><P>If you are using Qt 2.3, you cannot use        regular expressions to search backwards. In Qt 3.0 the regular        expression object <TTCLASS="CLASSNAME">QRegExp</TT> has been        greatly extended, and can be used to search both forwards and        backwards. When <SPANCLASS="APPLICATION">Kalam</SPAN> was written,        Qt 3.0 was still in beta. Therefore, it was necessary to include        code to disable the forward/backward checkboxes whenever the        user selects the regular expressions search mode, and code to        make forward searching the default.</P><DIVCLASS="NOTE"><BLOCKQUOTECLASS="NOTE"><P><B>On regular expressions: </B>It is quite probable that you know          more about regular expressions than I do. I can't write them          for toffee, and I find reading regular expressions to be          even harder (despite the fact that I used to be a dab hand          at Snobol). Nonetheless, regular expressions are          indispensable when searching a text. Even I know how to use          $ to specify the end of input or \n to specify a new line.          Regular expressions are everywhere on a Unix system, and all          decent editors (as well as Python, Perl and most other          languages) support them. On Windows, you can enter regular          expressions in the search function of Word (or so I am          told).</P><P>A regular expression is nothing more          than an algebraic notation for characterizing a set of          strings. An expression represents a pattern that the regular          expression engine can use to match text. Python comes with          its own highly capable, high performance regular expression          engine, compared with which the regular expression engine in          Qt 2.3 is a bit puny. The regular expression engine of Qt          3.0 has been improved a lot, and is nearly as good as the          Python one.</P><P>According to the Qt online documentation, the Qt 2.3          <TTCLASS="CLASSNAME">QRegExp</TT> class recognized the          following primitives:</P><P></P><UL><LI><P>c - the character 'c'            </P></LI><LI><P>. - any character (but only one)            </P></LI><LI><P>^ - matches start of input            </P></LI><LI><P>$ - matches end of input            </P></LI><LI><P>[] - matches a defined set of characters. For            instance, [a-z] matches all lowercase ASCII            characters. Note that you can give a range with a dash            (-) and negate a set with a caron (^ - [^ab] match            anything that does contain neither a nor b)/            </P></LI><LI><P>c* -  matches a sequence of zero or more character c's            </P></LI><LI><P>c+ -  matches a sequence of one or more character c's            </P></LI><LI><P>c? - matches an optional character c            </P></LI><LI><P>\c - escape code for special characters such              as \, [, *, +, . etc.            </P></LI><LI><P>\t - matches the TAB character (9)            </P></LI><LI><P>\n - matches newline (10). For instance "else\n"            will find all occurrence of else that are followed with a            new line, and that are thus missing the obligatory closing            colon (:).            </P></LI><LI><P>\r - matches return (13)            </P></LI><LI><P>\s - matches a white space (defined as any character              for which QChar::isSpace() returns TRUE. This includes              at least ASCII characters 9 (TAB), 10 (LF), 11 (VT),              12(FF), 13 (CR) and 32 (Space)).            </P></LI><LI><P>\d - matches a digit (defined as any character for              which QChar::isDigit() returns TRUE. This includes at              least ASCII characters '0'-'9').            </P></LI><LI><P>\x1f6b - matches the character with unicode point              U1f6b (hexadecimal 1f6b). \x0012 will match the              ASCII/Latin1 character 0x12 (18 decimal, 12              hexadecimal).            </P></LI><LI><P>\022 - matches the ASCII/Latin1 character 022 (18              decimal, 22 octal).            </P></LI></UL><P>Being constitutionally unable to explain exactly          <SPAN><ICLASS="EMPHASIS">how</I></SPAN> you go about creating regular          expressions that work, I can only refer you to the online          documentation of Python and Qt, and to the many tutorials          available on the web. Qt 3.0 comes with an excellent page on          regular expressions, too. Whenever I read Part I of Jurafsky          and Martin's book &#8216;Speech and Language Processing', I have          the feeling that I understand regular expressions, and I          have never found that to be the case with any other text on the          subject.</P><P>As a last note: both Python and Qt regular expressions          work just fine with Unicode. Back to our code...</P></BLOCKQUOTE></DIV><PRECLASS="PROGRAMLISTING">    def slotCaseSensitive(self):        pass    def slotBeginning(self):        self.setFindExtent()    def slotSelection(self):        self.setFindExtent()    def slotForward(self):        self.setFindExtent()    def slotBackward(self):        self.setFindExtent()      </PRE><P>Whenever the user alters one of the options that influence      the direction or area of search, the extent must be adapted.</P><PRECLASS="PROGRAMLISTING">    #    # Extent calculations    #    def setSelectionExtent(self):        self.startSelection = self.view.selectionStart()        self.endSelection = self.view.selectionEnd()        self.startPosition = self.startSelection        self.endPosition = self.endSelection    def setBackwardExtent(self):        # Determine extent to be searched        if (self.chkWholeText.isChecked()):            self.endPosition = self.view.length()        else:            self.endPosition = self.view.getCursorPosition()        self.startPosition = 0        if self.chkSelection.isChecked():            if self.view.hasSelection():                setSelectionExtent()        self.currentPosition = self.endPosition    def setForwardExtent(self):        # Determine extent to be searched        if (self.chkWholeText.isChecked()):            self.startPosition = 0        else:            self.startPosition = self.view.getCursorPosition()        self.endPosition = self.view.length()        if self.chkSelection.isChecked():            if self.view.hasSelection():                setSelectionExtent()        self.currentPosition = self.startPosition    def setFindExtent(self):        if self.radioForward.isChecked():            self.setForwardExtent()        else:            self.setBackwardExtent()      </PRE><P>Correctly determining which part of the        text should be searched is a fairly complex task. First, there        is an important difference between searching forwards and        backwards, if only because of the place where searching should        start. A further complication is caused by the option to        search either the whole text, or from the cursor position.        Note that begin and end mean the same thing with both        backwards and forwards searches; it is        <TTCLASS="VARNAME">currentPosition</TT>, where searching should        start, that is different between forward and backward        searches.</P><PRECLASS="PROGRAMLISTING">    def wrapExtentForward(self):        if QMessageBox.information(self.parent(),                                   "Kalam",                                   "End reached. Start from beginning?",                                   "yes",                                   "no",                                   None,                                   0,                                   1) == 0:            self.endPosition = self.startPosition            self.startPosition = 0            self.currentPosition = 0            self.slotFindNext()    def wrapExtentBackward(self):        if QMessageBox.information(self.parent(),                                   "Kalam",                                   "Begin reached. Start from end?",                                   "yes",                                   "no",                                   None,                                   0,                                   1) == 0:            self.startPosition = self.endPosition            self.endPosition = self.view.length()            self.currentPosition = self.startPosition            self.previousOccurrence()            self.slotFindNext()      </PRE><P>Whenever the current extent has been searched, the user        should be asked whether he or she wants to search the rest of        the text. The functions above are different for        forwards and backwards searching, too.</P><PRECLASS="PROGRAMLISTING">    #    # Find functions    #    def nextOccurrence(self):        findText = self.cmbFind.currentText()        caseSensitive = self.chkCaseSensitive.isChecked()        if self.radioRegexp.isChecked():            # Note differences with Qt 3.0            regExp = QRegExp(findText,                             caseSensitive)            pos, len = regExp.match(self.view.text(),                                    self.currentPosition,                                    FALSE)            return pos, pos+len        else:            pos = self.view.text().find(findText,                                        self.currentPosition,                                        caseSensitive)            return (pos, pos + findText.length())      </PRE><P>Searching forwards can be done by plain text matching, or      with regular expressions.</P><P>Regular expressions are available from        both Python and PyQt. Python regular expressions (in the        <TTCLASS="FILENAME">re</TT> module) work on Python strings, while        PyQt regular expressions work on        <TTCLASS="CLASSNAME">QString</TT>s. It is relatively inefficient        to convert a <TTCLASS="CLASSNAME">QString</TT> to a Python        string, so we use <TTCLASS="CLASSNAME"

⌨️ 快捷键说明

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