title: Why does QDialog::exec() blocks QTcpSocket work
body: <p>I make a Bomberman (or DynaBlast) game clone with multiplayer. Server game and client game communicate through messages using QTcpSocket. Typical workflow for playing network game is following:</p>
  <ul>
  <li>Server player execs NetworkGame dialog, among other things this dialog creates NetworkGame object</li>
  <li>Client player execs ClientGame dialog, among other things this dialog creates ClientGame object</li>
  <li>Client chooses IP of server and clicks &quot;Connect&quot;</li>
  <li>Server accepts connections, server and clients are now able to send messages each other</li>
  <li>Client sends &quot;ready&quot;-message, server start game</li>
  <li>When game over, the game object emits <code>GameStatusChanged(GameStatus newStatus)</code> signal. This signal connected to MainWindow, which execs <code>GameOverDialog</code>. If player chooses &quot;Play again&quot; at <code>GameOverDialog</code>, MainWindow execs NetworkGame or ClientGame dialogs again and we are at the first points.</li>
  </ul>
  <p>So, after first game is over, second <code>exec</code> of <code>ClientGameDialog</code> blocks <code>QTcpSocket</code> work in the way it cann't read data or emit <code>QTcpSocket::readyRead</code> signal (I don't know which one point exactly). <code>ClientGameDialog</code>'s GUI is responsive, it can send messages to server, but it cann't read messages. At the same time <code>NetworkGame</code> and <code>NetworkGameDialog</code> work properly - they are able to send and receive messages. I checked all my classes several times and don't see any significant difference.</p>
  <p>I think full code is to huge to post it here, so I gave UML a try. This is a chart for most important classes. Green arrow designates Qt's child-parent relations, starting at a child QObject it points to a parent.
  <a href="https://i.stack.imgur.com/RdCoZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RdCoZ.png" alt="enter image description here" /></a></p>
  <p>When <code>Socket</code> class receives new message through <code>QTcpSocket</code> interface, it emits <code>messageReceived(const Message&amp; message)</code> signal; other classes can connect to this signal via slots and handle messages. I don't see what <code>Client</code>, <code>ServerWorker</code>, <code>Server</code> classes can do with event loop, the just help to process raw data from <code>QTcpSocket</code> and deliver messages to other classes, particulary to <code>Game</code> and <code>Dialog</code> classes.</p>
  <p>Here is some code (I have some code duplications, I leave them until better times). Creating game:</p>
  <pre><code>// Server game
  void MainWindow::startNetworkGame() // User clicked &quot;Start network game&quot; button
  {
      const auto&amp; player = mainMenuWidget_-&gt;selectedPlayer();
      gameDialogs_ = createGameDialogs(this, GameType::Server, player);
      auto answer  = gameDialogs_.creationDialog-&gt;exec();
      if (answer == QDialog::Accepted) {
          auto initializationData = gameDialogs_.creationDialog-&gt;initializationData();
          initializeGame(initializationData);
          startGame(initializationData);
      }
  }
  
  // Client game
  void MainWindow::connectToServer() // User clicked &quot;Connect to server&quot; button
  {
      const auto&amp; player = mainMenuWidget_-&gt;selectedPlayer();
      gameDialogs_       = createGameDialogs(this, GameType::Client, player);
      auto answer        = gameDialogs_.creationDialog-&gt;exec(); // At first time it works fine
      if (answer == QDialog::Accepted) {
          auto initializationData = gameDialogs_.creationDialog-&gt;initializationData();
          initializeGame(initializationData);
          startGame(initializationData);
      }
  }
  </code></pre>
  <p>Next snippet is code for processing <code>GameStatusChanged</code> signal when game was over:</p>
  <pre><code>void MainWindow::gameStatusChanged(GameStatus newStatus)
  {
      if (newStatus == GameStatus::GameOver) {
          auto* gameOverDialog = gameDialogs_.gameOverDialog;
          gameOverDialog-&gt;setGameResult(gameData_.game-&gt;gameResult());
          auto gameOverDialogAnswer = gameOverDialog-&gt;exec();
          if (gameOverDialogAnswer == QDialog::Accepted) {
              gameDialogs_.creationDialog-&gt;reset();
              auto answer = gameDialogs_.creationDialog-&gt;exec(); // At this point client cann't receive messages, but server can.
              if (answer == QDialog::Accepted) {
                  auto initializationData = gameDialogs_.creationDialog-&gt;initializationData();
                  initializeGame(initializationData);
                  startGame(initializationData);
              } else {
                  showMainMenu();
              }
          } else {
              showMainMenu();
          }
      }
  }
  </code></pre>
  <p>I suspect that <code>ClientGameDialog</code>'s event loop (is it indeed has it's own event loop) doesn't processes <code>QTcpSocket</code>'s events. I tried to replace <code>exec()</code> with <code>open</code> methods for client dialog:</p>
  <pre><code>void MainWindow::gameStatusChanged(GameStatus newStatus)
  {
      if (newStatus == GameStatus::GameOver) {
          auto* gameOverDialog = gameDialogs_.gameOverDialog;
          gameOverDialog-&gt;setGameResult(gameData_.game-&gt;gameResult());
          auto gameOverDialogAnswer = gameOverDialog-&gt;exec();
          if (gameOverDialogAnswer == QDialog::Accepted) {
              gameDialogs_.creationDialog-&gt;reset();
              auto d = qobject_cast&lt;ClientGameDialog*&gt;(gameDialogs_.creationDialog);
              if (d) {
                  gameDialogs_.creationDialog-&gt;open();
              } else {
                  auto answer = gameDialogs_.creationDialog-&gt;exec();
                  if (answer == QDialog::Accepted) {
                      auto initializationData = gameDialogs_.creationDialog-&gt;initializationData();
                      initializeGame(initializationData);
                      startGame(initializationData);
                  } else {
                      showMainMenu();
                  }
              }
          } else {
              showMainMenu();
          }
      }
  }
  </code></pre>
  <p>It works, but I want to find where was the problem. Maybe someone can prompt, where to search a solution. Main questions are: where the difference between Server and Client code flows and why Client code works fine at the first time and breaks at the second.</p>