📄 index.lxp@lxpwrap=x3738_252ehtm.htm
字号:
work on streams, and asynchronous IO classes. We have already seen an example of working with <TTCLASS="CLASSNAME">QDir</TT>. <TTCLASS="CLASSNAME">QFile</TT> is Qt's equivalent of the Python file object; it is almost fully implemented in PyQt, with some changes due to naming conflicts. <TTCLASS="CLASSNAME">QFileInfo</TT> is a useful class that encapsulates and caches information including name, path, creation date and access rights. You could use the various function in Python's <TTCLASS="CLASSNAME">os.path</TT> module, but those don't cache information.</P><P>The base class for all these IO-oriented classes is <TTCLASS="CLASSNAME">QIODevice</TT>, which is completely implemented in PyQt. You can subclass it for your own IO classes. Qt divides its stream handling into text streams and binary streams. Only the text stream handling in implemented in PyQt, with the <TTCLASS="CLASSNAME">QTextStream</TT>, <TTCLASS="CLASSNAME">QTextIStream</TT> and <TTCLASS="CLASSNAME">QTextOStream</TT> classes. <TTCLASS="CLASSNAME">QTextStream</TT> is the base class, <TTCLASS="CLASSNAME">QTextIStream</TT> provides input stream functionality and <TTCLASS="CLASSNAME">QTextOStream</TT> output stream functionality. One problem remains with these stream classes — operator overloading. C++ relies on the >> and << operators to read from and write to a stream. PyQt doesn't support this yet, so you cannot actually make use of the streaming capabilities. Instead, you will have to limit yourself to using <TTCLASS="FUNCTION">read()</TT> to read the entire contents of the stream.</P><P>The asynchronous IO classes, the buffer class and the binary IO classes have <SPAN><ICLASS="EMPHASIS">not</I></SPAN> been implemented yet. You can easily substitute the various Python modules for file and IO handling. You can use <TTCLASS="CLASSNAME">asyncore</TT> in place <TTCLASS="CLASSNAME">QAsyncIO</TT>. The Python <TTCLASS="CLASSNAME">file</TT> object is buffered by nature, if you <TTCLASS="FUNCTION">open()</TT> your files with the <TTCLASS="PARAMETER"><I>bufsize</I></TT> parameter set.</P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">Date and time</A></H2><P></P><UL><LI><P>QDate — representation of a data</P></LI><LI><P>QTime — clock and time functions</P></LI><LI><P>QDateTime — combination of QDate and QTime</P></LI></UL><P>While Python has a <TTCLASS="CLASSNAME">time</TT> module, this only presents a low-level interface to the system date and time functions (and the <TTCLASS="FUNCTION">sleep()</TT> function, which halts processing for a while). It does not provide a high-level encapsulation of dates and times. PyQt, however, provides just that with <TTCLASS="CLASSNAME">QDate</TT> and <TTCLASS="CLASSNAME">QTime</TT>. <TTCLASS="CLASSNAME">QDate</TT> is especially suited to data arithmetic, and can hold dates from 1752 to 8000. The first limit is based on the date that our Gregorian calendar was introduced; if you need the Julian calendar (or perhaps Vikram Samvat or other exotic calendars), you must write your own <TTCLASS="CLASSNAME">Date</TT> class.</P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">Mime</A></H2><P></P><UL><LI><P>QMimeSource — a piece of formatted data</P></LI><LI><P>QMimeSourceFactory — a provider of formatted data</P></LI></UL><P>Python <TTCLASS="CLASSNAME">mimetools</TT> and the <TTCLASS="CLASSNAME">MimeWriter</TT> modules are not exactly equivalent to the PyQt <TTCLASS="CLASSNAME">QMimeSource</TT> and <TTCLASS="CLASSNAME">QMimeSourceFactory</TT> classes. The Python modules are optimized for the handling of mime-encoded e-mail messages. The PyQt classes are a more generalized abstraction of formatted data, where the format is identified by the IANA list of MIME media types. <TTCLASS="CLASSNAME">QMimeSource</TT> is used extensively in the drag'n'drop subsystem, in the clipboard handling, and in the production of images for rich text widgets.</P><P>An example is given in the <TTCLASS="FILENAME">application.py</TT> script that is included with PyQt. Below, I show a relevant fragment of that example, which takes a bit of html-formatted text with an <img> tag to a certain name, which is resolved using <TTCLASS="CLASSNAME">QMimeSourceFactory</TT>:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 10-20. Using QMimeSourceFactory (application.py)</B></P><PRECLASS="PROGRAMLISTING"> ...fileOpenText = \'''<img source="fileopen">Click this button to open a <em>new file</em>.<br><br>You can also select the <b>Open</b> command from the <b>File</b> menu.'''... QWhatsThis.add(self.fileOpen,fileOpenText) QMimeSourceFactory.defaultFactory().setPixmap('fileopen',openIcon)... </PRE></DIV></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">Text handling</A></H2><P></P><UL><LI><P>QString — string handling </P></LI><LI><P>QRegExp — regular expressions that work on a string.</P></LI><LI><P>QChar — one Unicode character</P></LI><LI><P>QValidator — validates input text according to certain rules</P></LI><LI><P>QTextCodec — conversions between text encodings</P></LI><LI><P>QTextDecoder — decode a text to Unicode</P></LI><LI><P>QTextEncoder — encode a text from Unicode</P></LI></UL><P>Qt's string handling really excels: it is thoroughly based upon Unicode, but provides easy functionality for other character encodings. However, plain Python also provides Unicode string functionality, and the interplay between Python strings and PyQt QStrings can be quite complex.</P><P>For most purposes, however, the conversions are transparent, and you can use Python strings as parameters in any function call where a <TTCLASS="CLASSNAME">QString</TT> is expected. If you run across more complex problems, you can consult <A href="index.lxp@lxpwrap=c2029_252ehtm.htm">Chapter 8</A>, on String Objects in Python and Qt.</P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">Threads</A></H2><P></P><UL><LI><P>QMutex</P></LI></UL><P>Python threads and Qt threads bite each other frequently. Qt thread support itself is still experimental, and with Unix/X11, most people still use the un-threaded Qt library. The C++ Qt thread class <TTCLASS="CLASSNAME">QMutex</TT> has not been ported to PyQt, so you cannot serialize access to gui features.</P><P>Python thread support is far more mature, but doesn't mix too well with PyQt — you don't want two threads accessing the same gui element. You're quite safe though, as long as your threads don't access the gui. The next example shows a simple pure-python script with two threads:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 10-21. thread1.py — Python threads without gui</B></P><PRECLASS="PROGRAMLISTING">## thread1.py#import sysimport timefrom threading import *class TextThread(Thread): def __init__(self, name, *args): self.counter=0 self.name=name apply(Thread.__init__, (self, ) + args) def run(self): while self.counter < 200: print self.name, self.counter self.counter = self.counter + 1 time.sleep(1)def main(args): thread1=TextThread("thread1") thread2=TextThread("thread2") thread1.start() thread2.start()if __name__=="__main__": main(sys.argv) </PRE></DIV><P>The next example has a Qt window. The threads run quite apart from the window, and yet everything operates fine— that is, until you try to close the application. The threads will continue to run until they are finished, but it would be better to kill the threads when the last window is closed. Killing or stopping threads from outside the threads is not supported in Python, but you can create a global variable, <TTCLASS="VARNAME">stop</TT>, to circumvent this. In the threads themselves, you then check whether <TTCLASS="VARNAME">stop</TT> is true.</P><DIVCLASS="EXAMPLE"></A><P><B>Example 10-22. Python threads and a PyQt gui window</B></P><PRECLASS="PROGRAMLISTING">## thread2.py - Python threads#import sys, timefrom threading import *from qt import *class TextThread(Thread): def __init__(self, name, *args): self.counter=0 self.name=name apply(Thread.__init__, (self, ) + args) def run(self): while self.counter < 200: print self.name, self.counter self.counter = self.counter + 1 time.sleep(1)class MainWindow(QMainWindow): def __init__(self, *args): apply(QMainWindow.__init__, (self,) + args) self.editor=QMultiLineEdit(self) self.setCentralWidget(self.editor) self.thread1=TextThread("thread1") self.thread2=TextThread("thread2") self.thread1.start() self.thread2.start()def main(args): app=QApplication(args) win=MainWindow() win.show() app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) app.exec_loop() if __name__=="__main__": main(sys.argv) </PRE></DIV><P>Another technique (though dangerous!) is to have the GUI use a timer to periodically check the variables produced by the threads. However, concurrent access of a variable can lead to nasty problems.</P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">URL's</A></H2><P>The Qt URL-handling classes are quite equivalent to Python's urllib module. It's up to you to choose which you prefer.</P><P></P><UL><LI><P>QUrl</P></LI><LI><P>QUrlInfo</P></LI><LI><P>QUrlOperator</P></LI></UL></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">Qt modules that overlap with Python modules</A></H2><P>In addition, there are two Qt modules that are also available completely as Python modules: the XML module (wrapped by Jim Bublitz) and the Network module. The Python equivalent of Qt's XML module, for simple tasks, xmllib, and for more complicated problems xml.sax. While xmllib is deprecated, it is still very useful and one the simplest ways of handling XML data. The xml.sax module depends on the presence of the expat parser, which is not available on every system.</P><P>The Qt network module has not been completely wrapped in PyQt yet. It is mainly useful if you want to program your own network clients and servers, and intend to move your code to C++ one day. Python offers equivalent modules for every service, and a lot more, too (such as http and gopher clients). You might find Qt's socket objects a bit more convenient than Python's offerings. Another possible reason to use the Qt socket classes is that they are better implemented on Windows than the Python socket classes.</P><DIVCLASS="TABLE"></A><P><B>Table 10-2. Qt and Python network classes</B></P><TABLEBORDER="1"CLASS="CALSTABLE"><THEAD><TR><THALIGN="LEFT"VALIGN="TOP">Qt Class</TH><THALIGN="LEFT"VALIGN="TOP">Python Class</TH><THALIGN="LEFT"VALIGN="TOP">Implemented</TH><THALIGN="LEFT"VALIGN="TOP">Description</TH></TR></THEAD><TBODY><TR><TDALIGN="LEFT"VALIGN="TOP">QSocket</TD><TDALIGN="LEFT"VALIGN="TOP">socket</TD><TDALIGN="LEFT"VALIGN="TOP">Partially implemented</TD><TDALIGN="LEFT"VALIGN="TOP">Low level network connection object. Note that Python's socket module is useful both for clients and servers, while Qt's QSocket is for clients only: servers use QServerSocket.</TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP">QSocketDevice</TD><TDALIGN="LEFT"VALIGN="TOP">socket</TD><TDALIGN="LEFT"VALIGN="TOP">No</TD><TDALIGN="LEFT"VALIGN="TOP">This class is mostly intended for use inside Qt - use QIODevice instead, which is completely implemented in PyQt.</TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP">QServerSocket</TD><TDALIGN="LEFT"VALIGN="TOP">socket, SocketServer</TD><TDALIGN="LEFT"VALIGN="TOP">Partially implemented</TD><TDALIGN="LEFT"VALIGN="TOP">The server-side complement of QSocket. Again, Python's socket module servers both for server and client applications. Python offers the server-specific SocketServer module.</TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP">QHostAddress</TD><TDALIGN="LEFT"VALIGN="TOP">No real equivalent</TD><TDALIGN="LEFT"VALIGN="TOP">Partially — not the functionality for IPv6.</TD><TDALIGN="LEFT"VALIGN="TOP">A platform and protocol independent representation of an IP address.</TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP">QDns</TD><TDALIGN="LEFT"VALIGN="TOP">No real equivalent</TD><TDALIGN="LEFT"VALIGN="TOP">Not implemented</TD><TDALIGN="LEFT"VALIGN="TOP">Asynchronous DNS lookups — it's not implemented, all Python libraries do automatic synchronous DNS lookups, as do the QSocket derived Qt classes.</TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP">QFtp</TD><TDALIGN="LEFT"VALIGN="TOP">ftplib</TD><TDALIGN="LEFT"VALIGN="TOP">Not implemented</TD><TDALIGN="LEFT"VALIGN="TOP">This class is seldom used: it's easier to just open an URL either with QUrlOperator or one of the Python Internet protocol handling libraries like urllib. </TD></TR></TBODY></TABLE></DIV></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=x3581_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=c4079_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Dialogs and Standard Dialogs</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=c2591_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Qt Designer, BlackAdder and uic</TD></TR></TABLE></DIV></BODY></HTML> </td> </tr> </table> </td> </tr> </table>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -