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

📄 index.lxp@lxpwrap=x6734_252ehtm.htm

📁 GUI Programming with Python
💻 HTM
📖 第 1 页 / 共 3 页
字号:
>QRegExp</TT> here (though        it is a little underpowered in its Qt 2.3 incarnation compared        to <TTCLASS="FILENAME">re</TT> and Qt 3.0's        <TTCLASS="CLASSNAME">QRegExp</TT>).</P><P>A <TTCLASS="CLASSNAME">QRegExp</TT> is        constructed from a string that contains the patterns that        should be matched, and two options. The first option        determines whether the search should be case sensitive; the        second determines whether or not the search is a wildcard        search. Wildcard searches work like the filename expansion on        a Unix command line, and are not terribly useful for searching        in a text.</P><P><TTCLASS="CLASSNAME">QRegExp</TT> has two        tools for searching: <TTCLASS="FUNCTION">match()</TT> and        <TTCLASS="FUNCTION">find()</TT>. Both take as parameters the        <TTCLASS="CLASSNAME">QString</TT> to be searched and the position        from which searching should start. However,        <TTCLASS="FUNCTION">match()</TT> also returns the length of the        string that is found, and can take an optional parameter that        indicates whether the start position should match the regular        expression character "^" (start of input). You don't want this        for searching in editable text, so we make it FALSE by        default.</P><P>Literal searching is a simple matter of        applying the <TTCLASS="FUNCTION">find()</TT> method of        <TTCLASS="CLASSNAME">QString</TT> from the current        position.</P><P>Looking for an occurrence returns        either -1, if nothing was found, or the begin and end        positions of the string that was found. Note that        <TTCLASS="CLASSNAME">QString</TT>.<TTCLASS="FUNCTION">find()</TT>        doesn't return the length of the found string; we take the        <TTCLASS="FUNCTION">length()</TT> of the search string to        determine the end position.</P><PRECLASS="PROGRAMLISTING">    def previousOccurrence(self):        findText = self.cmbFind.currentText()        caseSensitive = self.chkCaseSensitive.isChecked()        pos = self.view.text().findRev(findText,                                       self.currentPosition,                                       caseSensitive)        return (pos, pos + findText.length())      </PRE><P>Qt 2.3 doesn't yet support backwards        searching with regular expressions, so the function        <TTCLASS="FUNCTION">previousOccurrence</TT> is quite a bit        simpler. Instead of        <TTCLASS="CLASSNAME">QString</TT>.<TTCLASS="FUNCTION">find()</TT>,        <TTCLASS="CLASSNAME">QString</TT>.<TTCLASS="FUNCTION">findRev()</TT>        is used - this searches backwards.</P><PRECLASS="PROGRAMLISTING">    def slotFindNext(self):        if self.radioForward.isChecked():            begin, end = self.nextOccurrence()            if begin &#62; -1:                self.view.setSelection(begin,                                       end)                self.currentPosition = end                return (begin, end)            else:                if (self.chkSelection.isChecked() == FALSE and                    self.chkWholeText.isChecked() == FALSE):                    self.wrapExtentForward()                return (self.currentPosition, self.currentPosition)        else:            begin, end = self.previousOccurrence()            if begin &#62; -1:                self.view.setSelection(begin,                                       end)                self.currentPosition = begin -1                return (begin, end)            else:                if (self.chkSelection.isChecked() == FALSE and                    self.chkWholeText.isChecked() == FALSE):                    self.wrapExtentBackward()                return (self.currentPosition, self.currentPosition)      </PRE><P>The <TTCLASS="FUNCTION">slotFindNext</TT>        slot is the central bit of intelligence in this class.        Depending upon the selected direction, the next or previous        occurrence of the search string is searched. If an occurrence        is found (when <TTCLASS="VARNAME">begin</TT> is greater        than -1), it is selected, and the current position is moved.        If there are no more matches, the user is asked whether he or        she wants to go on with the rest of the document. </P><PRECLASS="PROGRAMLISTING">    def slotReplaceNext(self):        begin, end = self.slotFindNext()        if self.view.hasSelection():            self.view.replaceSelection(self.cmbReplace.currentText())            return begin, end        else:            return -1, -1    def slotReplaceAll(self):        begin, end = self.slotReplaceNext()        while begin &#62; -1:            begin, end = self.slotReplaceNext()            print begin, end      </PRE><P>Replacing is one part finding, one part        replacing. The <TTCLASS="FUNCTION">slotFindNext()</TT> code is        reused, which is one good reason for creating a dialog that        has both a find and a find and replace mode.        <TTCLASS="FUNCTION">slotFindNext()</TT> already selects the match,        so replacing is a simple matter of deleting the match and        inserting the replacement string. This is done with a new        function in <TTCLASS="CLASSNAME">KalamView</TT>:</P><PRECLASS="PROGRAMLISTING">...class KalamView(QWidget):...    def replaceSelection(self, text):        self.editor.deleteChar()        self.editor.insert(text)        self.editor.emit(SIGNAL("textChanged()"),())      </PRE><P>Messing about with the text in a        <TTCLASS="CLASSNAME">QMultiLineEdit</TT> widget has a few tricky        points. You should avoid trying to directly change the        <TTCLASS="CLASSNAME">QString</TT> that you retrieve with        <TTCLASS="CLASSNAME">QMultiLineEdit</TT>.<TTCLASS="FUNCTION">text()</TT>&#8212;         changing this string behind the editor's back is a sure recipe        for a beautiful crash. <TTCLASS="CLASSNAME">QMultiLineEdit</TT>        has several functions, such as        <TTCLASS="FUNCTION">deleteChar()</TT> (which not only deletes        characters, but also the selection, if there is one), to alter        the contents. However, these functions don't emit the        <TTCLASS="FUNCTION">textChanged()</TT> signal&#8212; you will have        to do that yourself. If we do not emit        <TTCLASS="FUNCTION">textChanged()</TT>, other views on the same        document won't know of the changes, nor will the document        itself know it has been changed.</P><P>Another interesting complication occurs        because <TTCLASS="CLASSNAME">QMultiLineEdit</TT>, the editor        widget used in <TTCLASS="CLASSNAME">KalamView</TT>, works with        line and column positioning, not with a position within the        string that represents the text. This makes it necessary to        create conversion functions between string index and editor        line / column position in <TTCLASS="CLASSNAME">KalamView</TT>,        which is potentially very costly business for long        files:</P><PRECLASS="PROGRAMLISTING">...class KalamView(QWidget):...    def getLineCol(self, p):        i=p        for line in range(self.editor.numLines()):            if i &#60; self.editor.textLine(line).length():                return (line, i)            else:                # + 1 to compensate for \n                i-=(self.editor.textLine(line).length() + 1)         # fallback        return (0,0)    def setCursorPosition(self, p):        """Sets the cursor of the editor at position p in the text."""        l, c = self.getLineCol(p)        self.editor.setCursorPosition(l, c)    def getPosition(self, startline, startcol):        if startline = 0:            return startcol        if startline &#62; self.editor.numLines():            return self.editor.text().length()        i=0        for line in range(self.editor.numLines()):            if line &#60; startline:                i += self.editor.textLine(line).length()            else:                return i + startcol    def getCursorPosition(self):        """Get the position of the cursor in the text"""        if self.editor.atBeginning():            return 0        if self.editor.atEnd():            return self.editor.text().length()        l, c = self.editor.getCursorPosition()        return self.getPosition(l, c)      </PRE><P>The function        <TTCLASS="FUNCTION">getLineCol()</TT> takes a single index        position as argument. It then loops through the lines of the        editor, subtracting the length of each line from a temporary        variable, until the length of the current line is greater than        the remaining number of characters. Then we have linenumber        and column.</P><P>The same, but in reverse is necessary in        <TTCLASS="FUNCTION">getPosition</TT> to find out how far into a        string the a certain line number and column position        is. There are a few safeguards and optimizations, but not        quite enough.</P><P>Qt 3 offers the        <TTCLASS="CLASSNAME">QTextEdit</TT> class, which is vastly more        powerful than <TTCLASS="CLASSNAME">QMultiLineEdit</TT>. For        instance, <TTCLASS="CLASSNAME">QTextEdit</TT> sports a built-in        find function. Internally, <TTCLASS="CLASSNAME">QTextEdit</TT> is        associated with <TTCLASS="CLASSNAME">QTextDocument</TT>, which is        comparable to our <TTCLASS="FUNCTION">KalamDocument</TT>. But you        can't get at <TTCLASS="CLASSNAME">QTextDocument</TT> (it's not        even documented, you need to read the Qt source code to find        out about it), so it's not a complete replacement for our        document-view architecture. The external rich text        representation of <TTCLASS="CLASSNAME">QTextEdit</TT> is a subset        of html, which makes it less suitable for a programmer's        editor. You have to choose: either colorized, fontified        text, and filter the html codes out yourself, or a plain text        editor. Fortunately, Qt 3 still includes        <TTCLASS="CLASSNAME">QMultiLineEdit</TT> for compatibility        reasons.</P></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"><A accesskey="P" href="index.lxp@lxpwrap=c6351_252ehtm.htm">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="H" href="index.lxp@lxpwrap=book1_252ehtm">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><A accesskey="N" href="index.lxp@lxpwrap=x6992_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Using Dialog Windows</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=c6351_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Conclusion</TD></TR></TABLE></DIV></BODY></HTML>      </td>      </tr>      </table>      </td>    </tr>  </table>      

⌨️ 快捷键说明

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