Sophie

Sophie

distrib > Mageia > 7 > i586 > by-pkgid > 1dd17e0d683ef79b4bb6872bbf359d7f > files > 4069

qt4-doc-4.8.7-26.2.mga7.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- blockingfortuneclient.qdoc -->
  <title>Qt 4.8: Blocking Fortune Client Example</title>
  <link rel="stylesheet" type="text/css" href="style/style.css" />
  <script src="scripts/jquery.js" type="text/javascript"></script>
  <script src="scripts/functions.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/superfish.css" />
  <link rel="stylesheet" type="text/css" href="style/narrow.css" />
  <!--[if IE]>
<meta name="MSSmartTagsPreventParsing" content="true">
<meta http-equiv="imagetoolbar" content="no">
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie6.css">
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie7.css">
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="style/style_ie8.css">
<![endif]-->

<script src="scripts/superfish.js" type="text/javascript"></script>
<script src="scripts/narrow.js" type="text/javascript"></script>

</head>
<body class="" onload="CheckEmptyAndLoadList();">
 <div class="header" id="qtdocheader">
    <div class="content"> 
    <div id="nav-logo">
      <a href="index.html">Home</a></div>
    <a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a>
    <div id="narrowsearch"></div>
    <div id="nav-topright">
      <ul>
        <li class="nav-topright-home"><a href="http://qt.digia.com/">Qt HOME</a></li>
        <li class="nav-topright-dev"><a href="http://qt-project.org/">DEV</a></li>
        <li class="nav-topright-doc nav-topright-doc-active"><a href="http://qt-project.org/doc/">
          DOC</a></li>
        <li class="nav-topright-blog"><a href="http://blog.qt.digia.com/">BLOG</a></li>
      </ul>
    </div>
    <div id="shortCut">
      <ul>
        <li class="shortCut-topleft-inactive"><span><a href="index.html">Qt 4.8</a></span></li>
        <li class="shortCut-topleft-active"><a href="http://qt-project.org/doc/">ALL VERSIONS        </a></li>
      </ul>
     </div>
 <ul class="sf-menu" id="narrowmenu"> 
             <li><a href="#">API Lookup</a> 
                 <ul> 
                     <li><a href="classes.html">Class index</a></li> 
           <li><a href="functions.html">Function index</a></li> 
           <li><a href="modules.html">Modules</a></li> 
           <li><a href="namespaces.html">Namespaces</a></li> 
           <li><a href="qtglobal.html">Global Declarations</a></li> 
           <li><a href="qdeclarativeelements.html">QML elements</a></li> 
             </ul> 
             </li> 
             <li><a href="#">Qt Topics</a> 
                 <ul> 
                        <li><a href="qt-basic-concepts.html">Programming with Qt</a></li>  
                        <li><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li>  
                        <li><a href="qt-gui-concepts.html">UI Design with Qt</a></li>  
                        <li><a href="supported-platforms.html">Supported Platforms</a></li>  
                        <li><a href="technology-apis.html">Qt and Key Technologies</a></li>  
                        <li><a href="best-practices.html">How-To's and Best Practices</a></li>  
              </ul> 
                 </li> 
                 <li><a href="#">Examples</a> 
                     <ul> 
                       <li><a href="all-examples.html">Examples</a></li> 
                       <li><a href="tutorials.html">Tutorials</a></li> 
                       <li><a href="demos.html">Demos</a></li> 
                       <li><a href="qdeclarativeexamples.html">QML Examples</a></li> 
                </ul> 
                     </li> 
                 </ul> 
    </div>
  </div>
  <div class="wrapper">
    <div class="hd">
      <span></span>
    </div>
    <div class="bd group">
      <div class="sidebar">
        <div class="searchlabel">
          Search index:</div>
        <div class="search" id="sidebarsearch">
          <form id="qtdocsearch" action="" onsubmit="return false;">
            <fieldset>
              <input type="text" name="searchstring" id="pageType" value="" />
 <div id="resultdialog"> 
 <a href="#" id="resultclose">Close</a> 
 <p id="resultlinks" class="all"><a href="#" id="showallresults">All</a> | <a href="#" id="showapiresults">API</a> | <a href="#" id="showarticleresults">Articles</a> | <a href="#" id="showexampleresults">Examples</a></p> 
 <p id="searchcount" class="all"><span id="resultcount"></span><span id="apicount"></span><span id="articlecount"></span><span id="examplecount"></span>&nbsp;results:</p> 
 <ul id="resultlist" class="all"> 
 </ul> 
 </div> 
            </fieldset>
          </form>
        </div>
        <div class="box first bottombar" id="lookup">
          <h2 title="API Lookup"><span></span>
            API Lookup</h2>
          <div  id="list001" class="list">
          <ul id="ul001" >
              <li class="defaultLink"><a href="classes.html">Class index</a></li>
              <li class="defaultLink"><a href="functions.html">Function index</a></li>
              <li class="defaultLink"><a href="modules.html">Modules</a></li>
              <li class="defaultLink"><a href="namespaces.html">Namespaces</a></li>
              <li class="defaultLink"><a href="qtglobal.html">Global Declarations</a></li>
              <li class="defaultLink"><a href="qdeclarativeelements.html">QML elements</a></li>
            </ul> 
          </div>
        </div>
        <div class="box bottombar" id="topics">
          <h2 title="Qt Topics"><span></span>
            Qt Topics</h2>
          <div id="list002" class="list">
            <ul id="ul002" >
               <li class="defaultLink"><a href="qt-basic-concepts.html">Programming with Qt</a></li> 
               <li class="defaultLink"><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li> 
               <li class="defaultLink"><a href="qt-gui-concepts.html">UI Design with Qt</a></li> 
               <li class="defaultLink"><a href="supported-platforms.html">Supported Platforms</a></li>  
               <li class="defaultLink"><a href="technology-apis.html">Qt and Key Technologies</a></li> 
               <li class="defaultLink"><a href="best-practices.html">How-To's and Best Practices</a></li> 
            </ul>  
          </div>
        </div>
        <div class="box" id="examples">
          <h2 title="Examples"><span></span>
            Examples</h2>
          <div id="list003" class="list">
        <ul id="ul003">
              <li class="defaultLink"><a href="all-examples.html">Examples</a></li>
              <li class="defaultLink"><a href="tutorials.html">Tutorials</a></li>
              <li class="defaultLink"><a href="demos.html">Demos</a></li>
              <li class="defaultLink"><a href="qdeclarativeexamples.html">QML Examples</a></li>
            </ul> 
          </div>
        </div>
      </div>
      <div class="wrap">
        <div class="toolbar">
          <div class="breadcrumb toolblock">
            <ul>
              <li class="first"><a href="index.html">Home</a></li>
              <!--  Breadcrumbs go here -->
<li><a href="all-examples.html">Examples</a></li>
<li>Blocking Fortune Client Example</li>
            </ul>
          </div>
          <div class="toolbuttons toolblock">
            <ul>
              <li id="smallA" class="t_button">A</li>
              <li id="medA" class="t_button active">A</li>
              <li id="bigA" class="t_button">A</li>
              <li id="print" class="t_button"><a href="javascript:this.print();">
                <span>Print</span></a></li>
            </ul>
        </div>
        </div>
        <div class="content mainContent">
<h1 class="title">Blocking Fortune Client Example</h1>
<span class="subtitle"></span>
<!-- $$$network/blockingfortuneclient-description -->
<div class="descr"> <a name="details"></a>
<p>Files:</p>
<ul>
<li><a href="network-blockingfortuneclient-blockingclient-cpp.html">network/blockingfortuneclient/blockingclient.cpp</a></li>
<li><a href="network-blockingfortuneclient-blockingclient-h.html">network/blockingfortuneclient/blockingclient.h</a></li>
<li><a href="network-blockingfortuneclient-fortunethread-cpp.html">network/blockingfortuneclient/fortunethread.cpp</a></li>
<li><a href="network-blockingfortuneclient-fortunethread-h.html">network/blockingfortuneclient/fortunethread.h</a></li>
<li><a href="network-blockingfortuneclient-main-cpp.html">network/blockingfortuneclient/main.cpp</a></li>
<li><a href="network-blockingfortuneclient-blockingfortuneclient-pro.html">network/blockingfortuneclient/blockingfortuneclient.pro</a></li>
</ul>
<p>The Blocking Fortune Client example shows how to create a client for a network service using <a href="qtcpsocket.html">QTcpSocket</a>'s synchronous API in a non-GUI thread.<p class="centerAlign"><img src="images/blockingfortuneclient-example.png" alt="" /></p><p><a href="qtcpsocket.html">QTcpSocket</a> supports two general approaches to network programming:</p>
<ul>
<li><i>The asynchronous (non-blocking) approach.</i> Operations are scheduled and performed when control returns to Qt's event loop. When the operation is finished, <a href="qtcpsocket.html">QTcpSocket</a> emits a signal. For example, <a href="qabstractsocket.html#connectToHost">QTcpSocket::connectToHost</a>() returns immediately, and when the connection has been established, <a href="qtcpsocket.html">QTcpSocket</a> emits <a href="qabstractsocket.html#connected">connected()</a>.</li>
<li><i>The synchronous (blocking) approach.</i> In non-GUI and multithreaded applications, you can call the <tt>waitFor..&#x2e;()</tt> functions (e.g&#x2e;, <a href="qabstractsocket.html#waitForConnected">QTcpSocket::waitForConnected</a>()) to suspend the calling thread until the operation has completed, instead of connecting to signals.</li>
</ul>
<p>The implementation is very similar to the <a href="network-fortuneclient.html">Fortune Client</a> example, but instead of having <a href="qtcpsocket.html">QTcpSocket</a> as a member of the main class, doing asynchronous networking in the main thread, we will do all network operations in a separate thread and use <a href="qtcpsocket.html">QTcpSocket</a>'s blocking API.</p>
<p>The purpose of this example is to demonstrate a pattern that you can use to simplify your networking code, without losing responsiveness in your user interface. Use of Qt's blocking network API often leads to simpler code, but because of its blocking behavior, it should only be used in non-GUI threads to prevent the user interface from freezing. But contrary to what many think, using threads with <a href="qthread.html">QThread</a> does not necessarily add unmanagable complexity to your application.</p>
<p>We will start with the FortuneThread class, which handles the network code.</p>
<pre class="cpp"> <span class="keyword">class</span> FortuneThread : <span class="keyword">public</span> <span class="type"><a href="qthread.html">QThread</a></span>
 {
     Q_OBJECT

 <span class="keyword">public</span>:
     FortuneThread(<span class="type"><a href="qobject.html">QObject</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);
     <span class="operator">~</span>FortuneThread();

     <span class="type">void</span> requestNewFortune(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>hostName<span class="operator">,</span> <span class="type"><a href="qtglobal.html#quint16-typedef">quint16</a></span> port);
     <span class="type">void</span> run();

 <span class="keyword">signals</span>:
     <span class="type">void</span> newFortune(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>fortune);
     <span class="type">void</span> error(<span class="type">int</span> socketError<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>message);

 <span class="keyword">private</span>:
     <span class="type"><a href="qstring.html">QString</a></span> hostName;
     <span class="type"><a href="qtglobal.html#quint16-typedef">quint16</a></span> port;
     <span class="type"><a href="qmutex.html">QMutex</a></span> mutex;
     <span class="type"><a href="qwaitcondition.html">QWaitCondition</a></span> <span class="type">cond</span>;
     <span class="type">bool</span> quit;
 };</pre>
<p>FortuneThread is a <a href="qthread.html">QThread</a> subclass that provides an API for scheduling requests for fortunes, and it has signals for delivering fortunes and reporting errors. You can call requestNewFortune() to request a new fortune, and the result is delivered by the newFortune() signal. If any error occurs, the error() signal is emitted.</p>
<p>It's important to notice that requestNewFortune() is called from the main, GUI thread, but the host name and port values it stores will be accessed from FortuneThread's thread. Because we will be reading and writing FortuneThread's data members from different threads concurrently, we use <a href="qmutex.html">QMutex</a> to synchronize access.</p>
<pre class="cpp"> <span class="type">void</span> FortuneThread<span class="operator">::</span>requestNewFortune(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>hostName<span class="operator">,</span> <span class="type"><a href="qtglobal.html#quint16-typedef">quint16</a></span> port)
 {
     <span class="type"><a href="qmutexlocker.html">QMutexLocker</a></span> locker(<span class="operator">&amp;</span>mutex);
     <span class="keyword">this</span><span class="operator">-</span><span class="operator">&gt;</span>hostName <span class="operator">=</span> hostName;
     <span class="keyword">this</span><span class="operator">-</span><span class="operator">&gt;</span>port <span class="operator">=</span> port;
     <span class="keyword">if</span> (<span class="operator">!</span>isRunning())
         start();
     <span class="keyword">else</span>
         <span class="type">cond</span><span class="operator">.</span>wakeOne();
 }</pre>
<p>The requestNewFortune() function stores the host name and port of the fortune server as member data, and we lock the mutex with <a href="qmutexlocker.html">QMutexLocker</a> to protect this data. We then start the thread, unless it is already running. We will come back to the <a href="qwaitcondition.html#wakeOne">QWaitCondition::wakeOne</a>() call later.</p>
<pre class="cpp"> <span class="type">void</span> FortuneThread<span class="operator">::</span>run()
 {
     mutex<span class="operator">.</span>lock();
     <span class="type"><a href="qstring.html">QString</a></span> serverName <span class="operator">=</span> hostName;
     <span class="type"><a href="qtglobal.html#quint16-typedef">quint16</a></span> serverPort <span class="operator">=</span> port;
     mutex<span class="operator">.</span>unlock();</pre>
<p>In the run() function, we start by acquiring the mutex lock, fetching the host name and port from the member data, and then releasing the lock again. The case that we are protecting ourselves against is that <tt>requestNewFortune()</tt> could be called at the same time as we are fetching this data. <a href="qstring.html">QString</a> is <a href="threads-reentrancy.html#reentrant">reentrant</a> but <i>not</i> <a href="threads-reentrancy.html#thread-safe">thread-safe</a>, and we must also avoid the unlikely risk of reading the host name from one request, and port of another. And as you might have guessed, FortuneThread can only handle one request at a time.</p>
<p>The run() function now enters a loop:</p>
<pre class="cpp">     <span class="keyword">while</span> (<span class="operator">!</span>quit) {
         <span class="keyword">const</span> <span class="type">int</span> Timeout <span class="operator">=</span> <span class="number">5</span> <span class="operator">*</span> <span class="number">1000</span>;

         <span class="type"><a href="qtcpsocket.html">QTcpSocket</a></span> socket;
         socket<span class="operator">.</span>connectToHost(serverName<span class="operator">,</span> serverPort);</pre>
<p>The loop will continue requesting fortunes for as long as <i>quit</i> is false. We start our first request by creating a <a href="qtcpsocket.html">QTcpSocket</a> on the stack, and then we call <a href="qabstractsocket.html#connectToHost">connectToHost()</a>. This starts an asynchronous operation which, after control returns to Qt's event loop, will cause <a href="qtcpsocket.html">QTcpSocket</a> to emit <a href="qabstractsocket.html#connected">connected()</a> or <a href="qabstractsocket.html#error">error()</a>.</p>
<pre class="cpp">         <span class="keyword">if</span> (<span class="operator">!</span>socket<span class="operator">.</span>waitForConnected(Timeout)) {
             <span class="keyword">emit</span> error(socket<span class="operator">.</span>error()<span class="operator">,</span> socket<span class="operator">.</span>errorString());
             <span class="keyword">return</span>;
         }</pre>
<p>But since we are running in a non-GUI thread, we do not have to worry about blocking the user interface. So instead of entering an event loop, we simply call <a href="qabstractsocket.html#waitForConnected">QTcpSocket::waitForConnected</a>(). This function will wait, blocking the calling thread, until <a href="qtcpsocket.html">QTcpSocket</a> emits connected() or an error occurs. If connected() is emitted, the function returns true; if the connection failed or timed out (which in this example happens after 5 seconds), false is returned. <a href="qabstractsocket.html#waitForConnected">QTcpSocket::waitForConnected</a>(), like the other <tt>waitFor..&#x2e;()</tt> functions, is part of <a href="qtcpsocket.html">QTcpSocket</a>'s <i>blocking API</i>.</p>
<p>After this statement, we have a connected socket to work with. Now it's time to see what the fortune server has sent us.</p>
<pre class="cpp">         <span class="keyword">while</span> (socket<span class="operator">.</span>bytesAvailable() <span class="operator">&lt;</span> (<span class="type">int</span>)<span class="keyword">sizeof</span>(<span class="type"><a href="qtglobal.html#quint16-typedef">quint16</a></span>)) {
             <span class="keyword">if</span> (<span class="operator">!</span>socket<span class="operator">.</span>waitForReadyRead(Timeout)) {
                 <span class="keyword">emit</span> error(socket<span class="operator">.</span>error()<span class="operator">,</span> socket<span class="operator">.</span>errorString());
                 <span class="keyword">return</span>;
             }
         }</pre>
<p>This step is to read the size of the packet. Although we are only reading two bytes here, and the <tt>while</tt> loop may seem to overdo it, we present this code to demonstrate a good pattern for waiting for data using <a href="qabstractsocket.html#waitForReadyRead">QTcpSocket::waitForReadyRead</a>(). It goes like this: For as long as we still need more data, we call waitForReadyRead(). If it returns false, we abort the operation. After this statement, we know that we have received enough data.</p>
<pre class="cpp">         <span class="type"><a href="qtglobal.html#quint16-typedef">quint16</a></span> blockSize;
         <span class="type"><a href="qdatastream.html">QDataStream</a></span> in(<span class="operator">&amp;</span>socket);
         in<span class="operator">.</span>setVersion(<span class="type"><a href="qdatastream.html">QDataStream</a></span><span class="operator">::</span>Qt_4_0);
         in <span class="operator">&gt;</span><span class="operator">&gt;</span> blockSize;</pre>
<p>Now we can create a <a href="qdatastream.html">QDataStream</a> object, passing the socket to <a href="qdatastream.html">QDataStream</a>'s constructor, and as in the other client examples we set the stream protocol version to <a href="qdatastream.html#Version-enum">QDataStream::Qt_4_0</a>, and read the size of the packet.</p>
<pre class="cpp">         <span class="keyword">while</span> (socket<span class="operator">.</span>bytesAvailable() <span class="operator">&lt;</span> blockSize) {
             <span class="keyword">if</span> (<span class="operator">!</span>socket<span class="operator">.</span>waitForReadyRead(Timeout)) {
                 <span class="keyword">emit</span> error(socket<span class="operator">.</span>error()<span class="operator">,</span> socket<span class="operator">.</span>errorString());
                 <span class="keyword">return</span>;
             }
         }</pre>
<p>Again, we'll use a loop that waits for more data by calling <a href="qabstractsocket.html#waitForReadyRead">QTcpSocket::waitForReadyRead</a>(). In this loop, we're waiting until <a href="qabstractsocket.html#bytesAvailable">QTcpSocket::bytesAvailable</a>() returns the full packet size.</p>
<pre class="cpp">         mutex<span class="operator">.</span>lock();
         <span class="type"><a href="qstring.html">QString</a></span> fortune;
         in <span class="operator">&gt;</span><span class="operator">&gt;</span> fortune;
         <span class="keyword">emit</span> newFortune(fortune);</pre>
<p>Now that we have all the data that we need, we can use <a href="qdatastream.html">QDataStream</a> to read the fortune string from the packet. The resulting fortune is delivered by emitting newFortune().</p>
<pre class="cpp">         <span class="type">cond</span><span class="operator">.</span>wait(<span class="operator">&amp;</span>mutex);
         serverName <span class="operator">=</span> hostName;
         serverPort <span class="operator">=</span> port;
         mutex<span class="operator">.</span>unlock();
     }</pre>
<p>The final part of our loop is that we acquire the mutex so that we can safely read from our member data. We then let the thread go to sleep by calling <a href="qwaitcondition.html#wait">QWaitCondition::wait</a>(). At this point, we can go back to requestNewFortune() and look closed at the call to wakeOne():</p>
<pre class="cpp"> <span class="type">void</span> FortuneThread<span class="operator">::</span>requestNewFortune(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>hostName<span class="operator">,</span> <span class="type"><a href="qtglobal.html#quint16-typedef">quint16</a></span> port)
 {
     ...
     <span class="keyword">if</span> (<span class="operator">!</span>isRunning())
         start();
     <span class="keyword">else</span>
         <span class="type">cond</span><span class="operator">.</span>wakeOne();
 }</pre>
<p>What happened here was that because the thread falls asleep waiting for a new request, we needed to wake it up again when a new request arrives. <a href="qwaitcondition.html">QWaitCondition</a> is often used in threads to signal a wakeup call like this.</p>
<pre class="cpp"> FortuneThread<span class="operator">::</span><span class="operator">~</span>FortuneThread()
 {
     mutex<span class="operator">.</span>lock();
     quit <span class="operator">=</span> <span class="keyword">true</span>;
     <span class="type">cond</span><span class="operator">.</span>wakeOne();
     mutex<span class="operator">.</span>unlock();
     wait();
 }</pre>
<p>Finishing off the FortuneThread walkthrough, this is the destructor that sets <i>quit</i> to true, wakes up the thread and waits for the thread to exit before returning. This lets the <tt>while</tt> loop in run() will finish its current iteration. When run() returns, the thread will terminate and be destroyed.</p>
<p>Now for the BlockingClient class:</p>
<pre class="cpp"> <span class="keyword">class</span> BlockingClient : <span class="keyword">public</span> <span class="type"><a href="qwidget.html">QWidget</a></span>
 {
     Q_OBJECT

 <span class="keyword">public</span>:
     BlockingClient(<span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);

 <span class="keyword">private</span> <span class="keyword">slots</span>:
     <span class="type">void</span> requestNewFortune();
     <span class="type">void</span> showFortune(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>fortune);
     <span class="type">void</span> displayError(<span class="type">int</span> socketError<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>message);
     <span class="type">void</span> enableGetFortuneButton();

 <span class="keyword">private</span>:
     <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>hostLabel;
     <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>portLabel;
     <span class="type"><a href="qlineedit.html">QLineEdit</a></span> <span class="operator">*</span>hostLineEdit;
     <span class="type"><a href="qlineedit.html">QLineEdit</a></span> <span class="operator">*</span>portLineEdit;
     <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>statusLabel;
 <span class="preprocessor">#ifdef Q_OS_SYMBIAN</span>
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>fortuneAction;
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>exitAction;
 <span class="preprocessor">#else</span>
     <span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>getFortuneButton;
     <span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>quitButton;
     <span class="type"><a href="qdialogbuttonbox.html">QDialogButtonBox</a></span> <span class="operator">*</span>buttonBox;
 <span class="preprocessor">#endif</span>

     FortuneThread thread;
     <span class="type"><a href="qstring.html">QString</a></span> currentFortune;
 };</pre>
<p>BlockingClient is very similar to the Client class in the <a href="network-fortuneclient.html">Fortune Client</a> example, but in this class we store a FortuneThread member instead of a pointer to a <a href="qtcpsocket.html">QTcpSocket</a>. When the user clicks the &quot;Get Fortune&quot; button, the same slot is called, but its implementation is slightly different:</p>
<pre class="cpp">     connect(<span class="operator">&amp;</span>thread<span class="operator">,</span> SIGNAL(newFortune(<span class="type"><a href="qstring.html">QString</a></span>))<span class="operator">,</span>
             <span class="keyword">this</span><span class="operator">,</span> SLOT(showFortune(<span class="type"><a href="qstring.html">QString</a></span>)));
     connect(<span class="operator">&amp;</span>thread<span class="operator">,</span> SIGNAL(error(<span class="type">int</span><span class="operator">,</span><span class="type"><a href="qstring.html">QString</a></span>))<span class="operator">,</span>
             <span class="keyword">this</span><span class="operator">,</span> SLOT(displayError(<span class="type">int</span><span class="operator">,</span><span class="type"><a href="qstring.html">QString</a></span>)));</pre>
<p>We connect our FortuneThread's two signals newFortune() and error() (which are somewhat similar to <a href="qiodevice.html#readyRead">QTcpSocket::readyRead</a>() and <a href="qabstractsocket.html#error">QTcpSocket::error</a>() in the previous example) to requestNewFortune() and displayError().</p>
<pre class="cpp"> <span class="type">void</span> BlockingClient<span class="operator">::</span>requestNewFortune()
 {
 <span class="preprocessor">#ifdef Q_OS_SYMBIAN</span>
     fortuneAction<span class="operator">-</span><span class="operator">&gt;</span>setVisible(<span class="keyword">false</span>);
 <span class="preprocessor">#else</span>
     getFortuneButton<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">false</span>);
 <span class="preprocessor">#endif</span>
     thread<span class="operator">.</span>requestNewFortune(hostLineEdit<span class="operator">-</span><span class="operator">&gt;</span>text()<span class="operator">,</span>
                              portLineEdit<span class="operator">-</span><span class="operator">&gt;</span>text()<span class="operator">.</span>toInt());
 }</pre>
<p>The requestNewFortune() slot calls FortuneThread::requestNewFortune(), which <i>shedules</i> the request. When the thread has received a new fortune and emits newFortune(), our showFortune() slot is called:</p>
<pre class="cpp"> <span class="type">void</span> BlockingClient<span class="operator">::</span>showFortune(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>nextFortune)
 {
     <span class="keyword">if</span> (nextFortune <span class="operator">=</span><span class="operator">=</span> currentFortune) {
         requestNewFortune();
         <span class="keyword">return</span>;
     }

     currentFortune <span class="operator">=</span> nextFortune;
     statusLabel<span class="operator">-</span><span class="operator">&gt;</span>setText(currentFortune);
 <span class="preprocessor">#ifdef Q_OS_SYMBIAN</span>
     fortuneAction<span class="operator">-</span><span class="operator">&gt;</span>setVisible(<span class="keyword">true</span>);
 <span class="preprocessor">#else</span>
     getFortuneButton<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">true</span>);
 <span class="preprocessor">#endif</span>
 }</pre>
<p>Here, we simply display the fortune we received as the argument.</p>
</div>
<p><b>See also </b><a href="network-fortuneclient.html">Fortune Client Example</a> and <a href="network-fortuneserver.html">Fortune Server Example</a>.</p>
<!-- @@@network/blockingfortuneclient -->
      </div>
    </div>
    </div> 
    <div class="ft">
      <span></span>
    </div>
  </div> 
  <div class="footer">
    <p>
      <acronym title="Copyright">&copy;</acronym> 2015 The Qt Company Ltd.
      Documentation contributions included herein are the copyrights of
      their respective owners.</p>
    <br />
    <p>
      The documentation provided herein is licensed under the terms of the
      <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation
      License version 1.3</a> as published by the Free Software Foundation.</p>
    <p>
      Documentation sources may be obtained from <a href="http://www.qt-project.org">
      www.qt-project.org</a>.</p>
    <br />
    <p>
      Qt and respective logos are trademarks of The Qt Company Ltd 
      in Finland and/or other countries worldwide. All other trademarks are property
      of their respective owners. <a title="Privacy Policy"
      href="http://en.gitorious.org/privacy_policy/">Privacy Policy</a></p>
  </div>

  <script src="scripts/functions.js" type="text/javascript"></script>
</body>
</html>