Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2022-04-28T11:49:19+02:00Les derniers messages parus sur le forum de Zeste de Savoir.Qt C++ - Chat multicast, message #2424642022-04-28T11:49:19+02:00tsuruba/@tsurubahttps://zestedesavoir.com/forums/sujet/16226/qt-c-chat-multicast/?page=1#p242464<blockquote>
<p>Tu as déjà vu des cours de C qui montre correctement faire les choses ?</p>
</blockquote>
<p>Je ne pense pas… En tout cas je suis sûr et certain de ne pas avoir vu la manière de faire indiquée dans le poste d’Alexandre Laurent avec les exceptions. Même sans aller jusqu’aux exceptions, le fait de mettre des if toutes les 2 lignes et de goto vers un bloc de nettoyage, je ne le fait que quand je vois que mon code fonctionne pas : Je met des if et des print dedans pour localiser l’erreur, je corrige, et ensuite j’enlève tout.
Le cours d’Harvard (merci pour la référence) je vais m’y pencher, vu que c’est le C que j’utilise le plus souvent. Même si j’ai peur que ça va être compliqué de désapprendre. <img src="/static/smileys/svg/triste.svg" alt=":(" class="smiley"></p>Qt C++ - Chat multicast, message #2424582022-04-27T22:14:29+02:00gbdivers/@gbdivershttps://zestedesavoir.com/forums/sujet/16226/qt-c-chat-multicast/?page=1#p242458<figure><blockquote>
<blockquote>
<p>Ca sent le problème de génération de qmake. Relance qmake (dans Qt Creator, dans le menu Build > Run qmake) puis fait un rebuild (dans le menu Build > Rebuild).</p>
</blockquote>
<p>Ca a suffit, pas besoin de destructeur virtuel en fin de compte. J’étais persuadé d’avoir bien lancé qmake… J’ai pas dû faire attention à ses messages en sortie, j’ai manqué d’attention, my bad ! <img src="/static/smileys/svg/hihi.svg" alt="^^" class="smiley"></p>
</blockquote><figcaption><a href="https://zestedesavoir.com/forums/sujet/16226/qt-c-chat-multicast/?page=1#p242457">tsuruba</a></figcaption></figure>
<p>Non, ce n’est pas une erreur de ta part. QtCreator lance automatiquement qmake normalement. Mais il arrive juste que de temps en temps, qmake n’est pas lancé.</p>
<p>Quand tu vois cette erreur de "vtable" avec un objet Qt, pense a lancer manuellement qmake. C’est juste un truc a savoir.</p>
<figure><blockquote>
<p>Oui dans ma formation on m’apprend qu’il est courant de travailler avec des anciennes versions des outils et langages pour des questions de compatibilité,</p>
</blockquote><figcaption><a href="https://zestedesavoir.com/forums/sujet/16226/qt-c-chat-multicast/?page=1#p242457">tsuruba</a></figcaption></figure>
<p>Ce qui est totalement vrai, on travaille souvent sur du code ancien à maintenir.</p>
<p>Mais ce n’est en réalité pas un argument pour ne pas apprendre les approches modernes. Parce que l’une des choses importantes que l’on apprend quand on apprend les approches modernes, c’est pourquoi on ne fait plus comme avant. Quels sont les problèmes posés par les anciennes approches. Et donc comment écrire du code ancien qui est correct.</p>
<p>Le problème de beaucoup de formation "ancienne", c’est qu’elles n’enseignent pas à écrire du code correct. C’est des bugs partout.</p>
<p>Un exemple qui montre le problèmes : <a href="https://alexandre-laurent.developpez.com/cpp/retour-fonctions-ou-exceptions">https://alexandre-laurent.developpez.com/cpp/retour-fonctions-ou-exceptions</a>. Regarde le code final correct en C. Tu as déjà vu des cours de C qui montre correctement faire les choses ? Beaucoup de cours se content de monter les syntaxes de base, sans montrer la complexité d’écrire du code correct. Un exemple d’exception : le cours CS50 de Harvard (gratuit et en anglais), qui montre par exemple que les pointeurs peuvent créer des bugs et comment utiliser valgrind pour détecter les problèmes.</p>Qt C++ - Chat multicast, message #2424572022-04-27T21:59:41+02:00tsuruba/@tsurubahttps://zestedesavoir.com/forums/sujet/16226/qt-c-chat-multicast/?page=1#p242457<blockquote>
<p>Ca sent le problème de génération de qmake. Relance qmake (dans Qt Creator, dans le menu Build > Run qmake) puis fait un rebuild (dans le menu Build > Rebuild).</p>
</blockquote>
<p>Ca a suffit, pas besoin de destructeur virtuel en fin de compte. J’étais persuadé d’avoir bien lancé qmake… J’ai pas dû faire attention à ses messages en sortie, j’ai manqué d’attention, my bad ! <img src="/static/smileys/svg/hihi.svg" alt="^^" class="smiley"></p>
<blockquote>
<p>C’est pas pour embêter les gens ou par snobisme qu’on déconseille les cours pas à jour. </p>
</blockquote>
<p>Je m’en doute t’inquiète, et c’est pas ce que je voulais dire, je me suis mal exprimé. En fait ce que je voulais dire, c’est que étant donné la source de mon cours, étant donné que dès les premières pages du cours j’avais des choses qui fonctionnaient pas, et étant donné ce que j’ai compris d’un article d’un certain "développeurzéro" (je suis plus du tout sûr du pseudo de cette personne), je pouvais prévoir que j’allais me confronter à des problèmes à un moment ou à un autre, en mélangeant des info récentes et anciennes, et en m’entêtant à utiliser la dernière version de Qt. (Oui dans ma formation on m’apprend qu’il est courant de travailler avec des anciennes versions des outils et langages pour des questions de compatibilité, mais là j’en suis à apprendre, pas à maintenir des trucs qui ont 30 ans donc go dernières versions selon moi <img src="/static/smileys/svg/triste.svg" alt=":(" class="smiley"> )</p>
<p>Enfin bref, ça fonctionne comme il faut. Je serai plus attentif pour la partie client de mon programme pour ne pas avoir les même problèmes. Merci ! <img src="/static/smileys/svg/heureux.svg" alt=":D" class="smiley"></p>Qt C++ - Chat multicast, message #2424562022-04-27T20:15:18+02:00gbdivers/@gbdivershttps://zestedesavoir.com/forums/sujet/16226/qt-c-chat-multicast/?page=1#p242456<p>J’ai fait une erreur de frappe pour le dernier argument, c’est <code>&fenetre_serveur::nouvelleConnexion</code>.</p>
<blockquote>
<p>c’était pas la peine d’aller chercher les best practice</p>
</blockquote>
<p>C’est pas en réalité une question de bonnes pratiques, mais simplement que la "nouvelle" syntaxe donne un message d’erreur explicite à la compilation. Donc c’est plus simple de trouver les problèmes.</p>
<blockquote>
<p>`vtable for fenetre_serveur'</p>
</blockquote>
<p>Ca sent le problème de génération de qmake. Relance qmake (dans Qt Creator, dans le menu Build > Run qmake) puis fait un rebuild (dans le menu Build > Rebuild).</p>
<blockquote>
<p>Certains disaient d’ajouter un destructeur virtuel</p>
</blockquote>
<p>Quand tu as une classe de base qui a un destructeur virtuel (dans ton cas QWidget), alors ta classe aura aussi un destructeur virtuel ajouté automatiquement par le compilateur.</p>
<p>Perso, je le mets, mais pas sur que ce soit nécessaire et que ca soit la cause du problème. Tu peux tester en ajoutant :</p>
<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="1"></span></div><pre><code class="hljs language-cpp">~<span class="hljs-built_in">fenetre_serveur</span>() <span class="hljs-keyword">override</span> = <span class="hljs-keyword">default</span>;
</code></pre></div>
<blockquote>
<p> D’autre disait plutôt de supprimer la macro. </p>
</blockquote>
<p>La macro sert a Qt pour déclarer des fonctionnalités internes, comme les signaux ou les meta objets (pour faire du QML). En fonction de ce que tu fais dans ta classe, la macro Q_OBJECT peut être obligatoire ou pas.</p>
<blockquote>
<p>je le sentais gros comme une maison</p>
</blockquote>
<p>C’est pas pour embêter les gens ou par snobisme qu’on déconseille les cours pas à jour. C’est que souvent, c’est un problème dans l’apprentissage : les langages ont évolués pour devenir plus simple et plus safe et utiliser une approche historique, cela veut dire se taper à la main toutes les merdes qui passent (et qui souvent n’ont aucun intérêt en termes d’apprentissage).</p>Qt C++ - Chat multicast, message #2424552022-04-27T19:56:21+02:00tsuruba/@tsurubahttps://zestedesavoir.com/forums/sujet/16226/qt-c-chat-multicast/?page=1#p242455<p>Salut, merci de la réponse !</p>
<blockquote>
<p>Ca doit compiler. Si ca ne compile pas, la solution n’est pas de le supprimer, mais de corriger le problème de compilation. Donne les messages d’erreur.</p>
</blockquote>
<p>Il y a 3 messages d’erreur :</p>
<blockquote>
<p>:-1: erreur : debug/fenetre_serveur.o:fenetre_serveur.cpp:(.rdata$.refptr._ZTV15fenetre_serveur[.refptr._ZTV15fenetre_serveur]+0x0): undefined reference to `vtable for fenetre_serveur'</p>
</blockquote>
<blockquote>
<p>:-1: erreur : collect2.exe: error: ld returned 1 exit status</p>
</blockquote>
<blockquote>
<p>:-1: erreur : [Makefile.Debug:81: debug/Chat_multicast—Partie_serveur.exe] Error 1</p>
</blockquote>
<p>J’avais un peu cherché, et j’ai trouvé un forum anglophone où ils discutaient de ce problème. Certains disaient d’ajouter un destructeur virtuel, que c’était nécessaire à cause de l’éhritage je crois. D’autre disait plutôt de supprimer la macro. Dans mon cas c’est la seconde option qui a "fonctionné".</p>
<blockquote>
<p>La syntaxe avec SIGNAL et SLOT n’est pas recommandé depuis Qt5 (10 ans). […] Tu suis quel cours ?</p>
</blockquote>
<p>Je m’y attendais à cette question et au problème lié, je le sentais gros comme une maison, quand au début du cours j’ai vu #include <QPushButton> ça ne fonctionnait pas !</p>
<p>Je suis le cours d’Open Classroom… Pas taper ! :’D Je sais les problèmes du cours C++ d’OC. Je sais aussi qu’il a subi très peu de mises à jour, si ce n’est la suppression de la section sur Qt.
J’ai suivi ce cours pour une raison simple. Je suis en école d’ingénieur, et j’ai un devoir sur ce fameux chat multicast. On me demande d’utiliser Qt, et les enseignants nous ont fourni le PDF du cours Qt d’OC. (à l’époque, c’était le site du zéro, je me souviens qu’on pouvait récupérer les PDF des cours du site, très mal formaté d’ailleurs !)
Comme je sais que certains de mes camarades ont déjà fini ce devoir, je me suis dit que, au moins sur cette section Qt, j’aurai pas de problème, et donc que c’était pas la peine d’aller chercher les best practice et que je pouvais me contenter de ce cours.
Voilà mon erreur… </p>
<p>BON ! Du coup je suis retourné à la doc (je vais finir par laisser tomber tous les cours de programmation et me contenter de la doc à chaque fois que je veux apprendre un nouveau langage je crois <img src="/static/smileys/svg/1f623.svg" alt="X(" class="smiley"> ) à la page <em><a href="https://doc.qt.io/qt-6/signalsandslots.html">Signals & Slots 6.3.0</a></em>. Je vois que dans la fonction connect, tout passe par pointeur. Donc la ligne que je doit écrire c’est : </p>
<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span></div><pre><code class="hljs language-cpp">QObject::<span class="hljs-built_in">connect</span>(serveur <span class="hljs-comment">/*déjà un pointeur*/</span>, &QTcpServer::newConnection, <span class="hljs-keyword">this</span>, fenetre_serveur::nouvelleConnexion);
</code></pre></div>
<p>(je me permet de corriger le dernier argument pour aussi le passer par pointeur au cas où d’autres passent par là).
Ca fonctionne, je n’ai plus le problème qui m’a amené ici initialement. Merci !</p>
<p>Pour le problème de la macro… J’ai une intuition (fondée sur rien !), c’est que mes différents connect posent problème. Je vais tous les réécrire pour qu’ils soient en accord avec la façon de faire que tu as indiquée (la "bonne façon" ? la "façon moderne" ?) pour voir si ça change quelque chose… Au pire si ça change rien j’aurai pas perdu mon temps j’aurai un code moins faux je suppose.</p>
<p>Je ferai ça dans la nuit et j’éditerai mon message je pense.</p>
<p>Bonne soirée !</p>Qt C++ - Chat multicast, message #2424532022-04-27T18:31:34+02:00gbdivers/@gbdivershttps://zestedesavoir.com/forums/sujet/16226/qt-c-chat-multicast/?page=1#p242453<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="1"></span></div><pre><code class="hljs language-cpp"><span class="hljs-comment">//Q_OBJECT J'arrive pas à voir pourquoi mais ça compile pas si je laisse ça...</span>
</code></pre></div>
<p>Ca doit compiler. Si ca ne compile pas, la solution n’est pas de le supprimer, mais de corriger le problème de compilation. Donne les messages d’erreur.</p>
<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="1"></span></div><pre><code class="hljs language-cpp">QObject::<span class="hljs-built_in">connect</span>(serveur, <span class="hljs-built_in">SIGNAL</span>(<span class="hljs-built_in">newConnection</span>()), <span class="hljs-keyword">this</span>, <span class="hljs-built_in">SLOT</span>(<span class="hljs-built_in">nouvelleConnexion</span>()));
</code></pre></div>
<p>La syntaxe avec SIGNAL et SLOT n’est pas recommandé depuis Qt5 (10 ans). Utilise la syntaxe avec les pointeurs de fonctions, pour avoir une erreur a la compilation.</p>
<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="1"></span></div><pre><code class="hljs language-cpp">QObject::<span class="hljs-built_in">connect</span>(serveur, &QTcpServer::newConnection, <span class="hljs-keyword">this</span>, &fenetre_serveur::nouvelleConnexion);
</code></pre></div>
<p>Tu suis quel cours ?</p>Qt C++ - Chat multicast, message #2424502022-04-27T15:26:36+02:00tsuruba/@tsurubahttps://zestedesavoir.com/forums/sujet/16226/qt-c-chat-multicast/?page=1#p242450<p>Bonjour tout le monde,</p>
<p>J’essaie de réaliser un chat multicast en C++ à l’aide du framework Qt. J’ai commencé par la partie serveur. Je me suis basé sur un cours trouvé sur internet, que j’ai réadapté pour qu’il soit adapté à Qt 6.
Je ne sais pas de quelle version il s’agit, mais le programme trouvé sur internet utilise directement :</p>
<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><QApplication></span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><QPushButton></span></span>
<span class="hljs-comment">// ou encore</span>
<span class="hljs-built_in">connect</span>(client, ... <span class="hljs-comment">// Sans le Qobject</span>
</code></pre></div>
<p>Je sais que ça ne marche plus en tout cas avec Qt 6, ce qui m’a obligé à faire des modifications après le copier-coller. Je pense que mon problème vient de mes modifs, mais je ne vois pas où.</p>
<p>Mes fichiers sont en fin du post pour la lisibilté. Tout ça compile et s’éxécute. Cependant, dans la "sortie de l’application" de Qt Creator, j’ai le message "qt.core.qobject.connect: QObject::connect: No such slot QWidget::nouvelleConnexion()" (aucun problème dans la "sortie du compilateur"). Le problème semble venir du fichier "fenetre_serveur.cpp" à la ligne 28.</p>
<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="27"></span><span data-count="28"></span><span data-count="29"></span></div><pre><code class="hljs language-cpp"><span class="hljs-comment">//...</span>
QObject::<span class="hljs-built_in">connect</span>(serveur, <span class="hljs-built_in">SIGNAL</span>(<span class="hljs-built_in">newConnection</span>()), <span class="hljs-keyword">this</span>, <span class="hljs-built_in">SLOT</span>(<span class="hljs-built_in">nouvelleConnexion</span>()));
<span class="hljs-comment">//...</span>
</code></pre></div>
<p>Je ne vois pas pourquoi il me dit que ce slot n’existe pas alors que je l’ai bien écrit dans le <em>.cpp et le </em>.h. Pour éviter les erreurs de nom, je les ai copier-coller là où il faut à partir de cette ligne justement.</p>
<p>Pourtant il me semble bien avoir compris les paramètres de connect :</p>
<ul>
<li>serveur : car j’atend un signal du widget serveur;</li>
<li>SIGNAL(newConnection()) : le signal du widget serveur qui m’intéresse;</li>
<li>this : Parceque je veux activer un slot de la fenêtre où je suis (parent de serveur);</li>
<li>SLOT(nouvelleConnexion()) : C’est le slot que je veux activer, qui est un slot ajouté.</li>
</ul>
<p>Je me serai trompé sur l’argument this ? je devrais mettre quoi alors ? :/ Je me dit que c’est this le problème car apparemment il cherche le slot "QWidget::nouvelleConnexion" et pas "fenetre_serveur::nouvelleConnexion". j’ai essayé de l’écrire directement dans la ligne 28, mais alors l’erreur est la même mais avec "QWidget::fenetre_serveur::nouvelleConnexion".</p>
<p>Je vois une autre possibilité, c’est la ligne 12 de mon *.h :</p>
<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span></div><pre><code class="hljs language-cpp"><span class="hljs-comment">//...</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">fenetre_serveur</span> :</span> <span class="hljs-keyword">public</span> QWidget {
<span class="hljs-comment">//Q_OBJECT J'arrive pas à voir pourquoi mais ça compile pas si je laisse ça...</span>
<span class="hljs-comment">//...</span>
</code></pre></div>
<p>Je ne comprend pas pourquoi, mais si je laisse la macro <code>cpp Q_OBJECT </code>, je ne peux pas compiler, et je ne comprend pas pourquoi car dans le cours que j’ai on me demande de la mettre, dans le programme trouvé sur internet elle est également présente.</p>
<p>De mon côté, je vais temporairement ignorer le problème, faire le client, puis voir ce qu’il se passe…
Avez-vous des pistes pour m’aider ?</p>
<p>Merci par avance</p>
<hr>
<p>FICHIERS COMPLETS</p>
<p>Les commentaires entre /**/ Sont des modifications que je veux apporter plus tard, elles ne sont pas importantes pour l’instant.</p>
<p>fenetre_serveur.cpp :</p>
<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span><span data-count="14"></span><span data-count="15"></span><span data-count="16"></span><span data-count="17"></span><span data-count="18"></span><span data-count="19"></span><span data-count="20"></span><span data-count="21"></span><span data-count="22"></span><span data-count="23"></span><span data-count="24"></span><span data-count="25"></span><span data-count="26"></span><span data-count="27"></span><span data-count="28"></span><span data-count="29"></span><span data-count="30"></span><span data-count="31"></span><span data-count="32"></span><span data-count="33"></span><span data-count="34"></span><span data-count="35"></span><span data-count="36"></span><span data-count="37"></span><span data-count="38"></span><span data-count="39"></span><span data-count="40"></span><span data-count="41"></span><span data-count="42"></span><span data-count="43"></span><span data-count="44"></span><span data-count="45"></span><span data-count="46"></span><span data-count="47"></span><span data-count="48"></span><span data-count="49"></span><span data-count="50"></span><span data-count="51"></span><span data-count="52"></span><span data-count="53"></span><span data-count="54"></span><span data-count="55"></span><span data-count="56"></span><span data-count="57"></span><span data-count="58"></span><span data-count="59"></span><span data-count="60"></span><span data-count="61"></span><span data-count="62"></span><span data-count="63"></span><span data-count="64"></span><span data-count="65"></span><span data-count="66"></span><span data-count="67"></span><span data-count="68"></span><span data-count="69"></span><span data-count="70"></span><span data-count="71"></span><span data-count="72"></span><span data-count="73"></span><span data-count="74"></span><span data-count="75"></span><span data-count="76"></span><span data-count="77"></span><span data-count="78"></span><span data-count="79"></span><span data-count="80"></span><span data-count="81"></span><span data-count="82"></span><span data-count="83"></span><span data-count="84"></span><span data-count="85"></span><span data-count="86"></span><span data-count="87"></span><span data-count="88"></span><span data-count="89"></span><span data-count="90"></span><span data-count="91"></span><span data-count="92"></span><span data-count="93"></span><span data-count="94"></span><span data-count="95"></span><span data-count="96"></span><span data-count="97"></span><span data-count="98"></span><span data-count="99"></span><span data-count="100"></span><span data-count="101"></span></div><pre><code class="hljs language-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"fenetre_serveur.h"</span></span>
<span class="hljs-comment">// Constructeur par défaut</span>
fenetre_serveur::<span class="hljs-built_in">fenetre_serveur</span>() : <span class="hljs-built_in">QWidget</span>()
{
<span class="hljs-comment">// Texte d'information du serveur</span>
etatServeur = <span class="hljs-keyword">new</span> <span class="hljs-built_in">QLabel</span>(<span class="hljs-keyword">this</span>);
<span class="hljs-comment">// Parametres du bouton</span>
boutonQuitter = <span class="hljs-keyword">new</span> <span class="hljs-built_in">QPushButton</span>(<span class="hljs-string">"Quitter"</span>, <span class="hljs-keyword">this</span>);
QObject::<span class="hljs-built_in">connect</span>(boutonQuitter, <span class="hljs-built_in">SIGNAL</span>(<span class="hljs-built_in">clicked</span>()), qApp, <span class="hljs-built_in">SLOT</span>(<span class="hljs-built_in">quit</span>()));
<span class="hljs-comment">// Disposition</span>
layout = <span class="hljs-keyword">new</span> <span class="hljs-built_in">QVBoxLayout</span>(<span class="hljs-keyword">this</span>); <span class="hljs-comment">//Pour ne pas s'embêter avec les ->setGeometry</span>
layout-><span class="hljs-built_in">addWidget</span>(etatServeur);
layout-><span class="hljs-built_in">addWidget</span>(boutonQuitter);
<span class="hljs-built_in">setWindowTitle</span>(<span class="hljs-string">"Fenetre du serveur"</span>);
<span class="hljs-comment">// Demarrage du serveur</span>
<span class="hljs-comment">/* Songer a mettre ceci hors du constructeur plus tard : J'aimerai pouvoir faire plusieurs serveurs en simultanné */</span>
serveur = <span class="hljs-keyword">new</span> <span class="hljs-built_in">QTcpServer</span>(<span class="hljs-keyword">this</span>);
<span class="hljs-comment">// Attente de la connexion de n'importe qui sur le port 50885.</span>
<span class="hljs-keyword">if</span>( !serveur-><span class="hljs-built_in">listen</span>(QHostAddress::Any, <span class="hljs-number">50885</span>)){ <span class="hljs-comment">/* Si possible laisser l'utilisateur choisir son port ou un port automatique*/</span>
etatServeur-><span class="hljs-built_in">setText</span>(<span class="hljs-string">"Le serveur n'a pas pu demarrer : <br />"</span> + serveur-><span class="hljs-built_in">errorString</span>());
}
<span class="hljs-keyword">else</span>{
etatServeur-><span class="hljs-built_in">setText</span>(<span class="hljs-string">"Le serveur a démarré sur le port <strong>"</span> + QString::<span class="hljs-built_in">number</span>(serveur-><span class="hljs-built_in">serverPort</span>()) + <span class="hljs-string">"</strong>.<br /> Des clients peuvent maintenant se connecter"</span>);
QObject::<span class="hljs-built_in">connect</span>(serveur, <span class="hljs-built_in">SIGNAL</span>(<span class="hljs-built_in">newConnection</span>()), <span class="hljs-keyword">this</span>, <span class="hljs-built_in">SLOT</span>(<span class="hljs-built_in">nouvelleConnexion</span>()));
}
}
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">fenetre_serveur::nouvelleConnexion</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-built_in">envoyerATous</span>(<span class="hljs-string">"Un nouveau client vient de se connecter"</span>); <span class="hljs-comment">// Annonce</span>
<span class="hljs-comment">// Nouveau client</span>
QTcpSocket *nouveauClient = serveur-><span class="hljs-built_in">nextPendingConnection</span>();
clients << nouveauClient;
<span class="hljs-comment">// Signaux</span>
QObject::<span class="hljs-built_in">connect</span>(nouveauClient, <span class="hljs-built_in">SIGNAL</span>(<span class="hljs-built_in">readyRead</span>()), <span class="hljs-keyword">this</span>, <span class="hljs-built_in">SLOT</span>(<span class="hljs-built_in">donneesRecues</span>())); <span class="hljs-comment">// signal readyRead introuvable dans la doc de QTcpSocket</span>
QObject::<span class="hljs-built_in">connect</span>(nouveauClient, <span class="hljs-built_in">SIGNAL</span>(<span class="hljs-built_in">disconnected</span>()), <span class="hljs-keyword">this</span>, <span class="hljs-built_in">SLOT</span>(<span class="hljs-built_in">deconnexionClient</span>())); <span class="hljs-comment">//idem</span>
}
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">fenetre_serveur::donneesRecues</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-comment">// Recherche du QTcpSoccket du client qui envoi</span>
QTcpSocket *socket = qobject_cast< QTcpSocket *>(<span class="hljs-built_in">sender</span>());
<span class="hljs-keyword">if</span>(socket == <span class="hljs-number">0</span>){ <span class="hljs-keyword">return</span>; }
<span class="hljs-comment">// Recuperation du message</span>
<span class="hljs-function">QDataStream <span class="hljs-title">in</span><span class="hljs-params">(socket)</span></span>; <span class="hljs-comment">/*rendre les if plus propres */</span>
<span class="hljs-keyword">if</span>(tailleMessage == <span class="hljs-number">0</span>){ <span class="hljs-comment">// Si on a pas déjà la taille du message</span>
<span class="hljs-keyword">if</span>(socket-><span class="hljs-built_in">bytesAvailable</span>() < (<span class="hljs-keyword">int</span>)<span class="hljs-built_in"><span class="hljs-keyword">sizeof</span></span>(quint16)){ <span class="hljs-comment">// Si on a pas au moins un int, alors on a pas encore reçu le message en entier</span>
<span class="hljs-keyword">return</span>;
}
in >> tailleMessage; <span class="hljs-comment">// Si on au moins un entier, alors on a la taille du message</span>
}
<span class="hljs-keyword">if</span>(socket-><span class="hljs-built_in">bytesAvailable</span>() < tailleMessage) {<span class="hljs-keyword">return</span>;} <span class="hljs-comment">// Si on a pas encore le message entier, on attend</span>
QString message;
in >> message; <span class="hljs-comment">// On vide entièrement in dans message;</span>
<span class="hljs-built_in">envoyerATous</span>(message); <span class="hljs-comment">// On l'envoi à tout le monde;</span>
tailleMessage = <span class="hljs-number">0</span>; <span class="hljs-comment">// On se rend prêt à recevoir un nouveau message;</span>
}
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">fenetre_serveur::envoyerATous</span><span class="hljs-params">(<span class="hljs-keyword">const</span> QString& message)</span>
</span>{
QByteArray paquet; <span class="hljs-comment">// Le paquet a envoyer est un vecteur d'octets</span>
<span class="hljs-function">QDataStream <span class="hljs-title">out</span><span class="hljs-params">(&paquet, QIODevice::WriteOnly)</span></span>; <span class="hljs-comment">// Simplement pour pouvoir ecrire dans le paquet avec <<. C'est du sucre syntaxique</span>
out << (quint16) <span class="hljs-number">0</span>; <span class="hljs-comment">// Réservation de l'emplacement pour la taille du message</span>
out << message; <span class="hljs-comment">// On place le message a proprement parler</span>
<span class="hljs-comment">/* Ajouter un traitement du message, pour mettre le pseudo de qui envoi, l'heure... */</span>
out.<span class="hljs-built_in">device</span>()-><span class="hljs-built_in">seek</span>(<span class="hljs-number">0</span>); <span class="hljs-comment">// On se repalce au début du paquet</span>
out << (quint16) (paquet.<span class="hljs-built_in">size</span>() - <span class="hljs-built_in"><span class="hljs-keyword">sizeof</span></span>(quint16)); <span class="hljs-comment">// La taille du message compte pas dans la taille du message...</span>
<span class="hljs-comment">// Envoi</span>
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < clients.<span class="hljs-built_in">size</span>(); i++)
{
clients[i]-><span class="hljs-built_in">write</span>(paquet);
}
}
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">fenetre_serveur::deconnexionClient</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-built_in">envoyerATous</span>(<span class="hljs-string">"Un client vient de se déconnecter"</span>);
<span class="hljs-comment">// Qui ?</span>
QTcpSocket *socket = qobject_cast<QTcpSocket *>(<span class="hljs-built_in">sender</span>());
<span class="hljs-keyword">if</span>( socket == <span class="hljs-number">0</span>) { <span class="hljs-keyword">return</span>; }
clients.<span class="hljs-built_in">removeOne</span>(socket); <span class="hljs-comment">// On retire le client</span>
socket-><span class="hljs-built_in">deleteLater</span>();
<span class="hljs-comment">/* Mettre des else !!! */</span>
}
</code></pre></div>
<p>fenetre_serveur.h</p>
<div class="hljs-code-div hljs-code-cpp"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span><span data-count="14"></span><span data-count="15"></span><span data-count="16"></span><span data-count="17"></span><span data-count="18"></span><span data-count="19"></span><span data-count="20"></span><span data-count="21"></span><span data-count="22"></span><span data-count="23"></span><span data-count="24"></span><span data-count="25"></span><span data-count="26"></span><span data-count="27"></span><span data-count="28"></span><span data-count="29"></span><span data-count="30"></span><span data-count="31"></span><span data-count="32"></span><span data-count="33"></span><span data-count="34"></span><span data-count="35"></span><span data-count="36"></span><span data-count="37"></span></div><pre><code class="hljs language-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> FENETRE_SERVEUR_H</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> FENETRE_SERVEUR_H</span>
<span class="hljs-comment">// fichiers par défaut</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><QWidget></span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><QtNetwork></span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><QtWidgets/QLabel></span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><QtWidgets/QPushButton></span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><QtWidgets/QVBoxLayout></span></span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">fenetre_serveur</span> :</span> <span class="hljs-keyword">public</span> QWidget {
<span class="hljs-comment">//Q_OBJECT J'arrive pas à voir pourquoi mais ça compile pas si je laisse ça...</span>
<span class="hljs-keyword">public</span>:
<span class="hljs-built_in">fenetre_serveur</span>();
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">envoyerATous</span><span class="hljs-params">(<span class="hljs-keyword">const</span> QString& message)</span></span>; <span class="hljs-comment">/*renommer en envoyer*/</span>
<span class="hljs-keyword">private</span> slots:
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">nouvelleConnexion</span><span class="hljs-params">()</span></span>; <span class="hljs-comment">/*renommer en client_connexion*/</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">donneesRecues</span><span class="hljs-params">()</span></span>; <span class="hljs-comment">/*renommer en recevoir*/</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">deconnexionClient</span><span class="hljs-params">()</span></span>; <span class="hljs-comment">/*renommer en client_deconnexion*/</span>
<span class="hljs-keyword">private</span>:
<span class="hljs-comment">// Elements de l'interface</span>
QLabel *etatServeur;
QPushButton *boutonQuitter;
QVBoxLayout *layout;
<span class="hljs-comment">// Elements de réseau</span>
QTcpServer *serveur;
QList<QTcpSocket *> clients;
quint16 tailleMessage = <span class="hljs-number">0</span>;
};
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span> <span class="hljs-comment">// FENETRE_SERVEUR_H</span></span>
</code></pre></div>
<p>(Je ne crois pas que mon main soit utile donc je le met pas pour des raisons de place)</p>incapacité de compiler un programme, message #435702015-02-13T00:10:33+01:00lewoudar/@lewoudarhttps://zestedesavoir.com/forums/sujet/2429/incapacite-de-compiler-un-programme/?page=1#p43570<p>D'accord Kje, prochainement je ne l'oublierais pas.
Merci RomHa, c'est exactement ce qu'il fallait faire.</p>incapacité de compiler un programme, message #434172015-02-12T10:00:22+01:00anonyme/@anonymehttps://zestedesavoir.com/forums/sujet/2429/incapacite-de-compiler-un-programme/?page=1#p43417<p>Quand tu ajoutes la macro Q_OBJECT, il faut relancer <em>qmake</em> pour générer le .moc associé.</p>incapacité de compiler un programme, message #434052015-02-12T08:00:14+01:00Kje/@Kjehttps://zestedesavoir.com/forums/sujet/2429/incapacite-de-compiler-un-programme/?page=1#p43405<p>Quand tu as des problèmes, plutôt que nous dire "QtCreator râle", tu devrais plutôt nous recopier l'erreur de compilation. Même si tu ne la comprends pas, nous ça peut beaucoup nous aider pour trouver le problème.</p>incapacité de compiler un programme, message #433942015-02-11T22:05:19+01:00lewoudar/@lewoudarhttps://zestedesavoir.com/forums/sujet/2429/incapacite-de-compiler-un-programme/?page=1#p43394<p>Bonjour,
j'ai suivi un tutoriel sur qt pour apprendre à créer un slot personnalisé. c'est un slot qui permet de redimensionner une fenêtre à partir de la valeur récupérée d'un QSLide
Voici l'entête </p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre></div></td><td class="code"><div class="codehilite"><pre><span class="cp">#ifndef DEF_MAFENETRE</span>
<span class="cp">#define DEF_MAFENETRE</span>
<span class="cp">#include <QApplication></span>
<span class="cp">#include <QWidget></span>
<span class="cp">#include <QSlider></span>
<span class="cp">#include <QProgressBar></span>
<span class="k">class</span> <span class="nc">MaFenetre</span> <span class="o">:</span> <span class="k">public</span> <span class="n">QWidget</span>
<span class="p">{</span>
<span class="n">Q_OBJECT</span>
<span class="k">public</span><span class="o">:</span>
<span class="n">MaFenetre</span><span class="p">();</span>
<span class="k">public</span> <span class="nl">slots</span><span class="p">:</span>
<span class="kt">void</span> <span class="n">changerLargeur</span><span class="p">(</span><span class="kt">int</span> <span class="n">largeur</span><span class="p">);</span>
<span class="k">private</span><span class="o">:</span>
<span class="n">QSlider</span> <span class="o">*</span><span class="n">m_slider</span><span class="p">;</span>
<span class="p">};</span>
<span class="cp">#endif</span>
</pre></div>
</td></tr></table>
<p>voici le .cpp</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17</pre></div></td><td class="code"><div class="codehilite"><pre><span class="cp">#include "MaFenetre.h"</span>
<span class="kt">void</span> <span class="n">MaFenetre</span><span class="o">::</span><span class="n">changerLargeur</span><span class="p">(</span><span class="kt">int</span> <span class="n">largeur</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">setFixedSize</span><span class="p">(</span><span class="n">largeur</span><span class="p">,</span> <span class="mi">100</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">MaFenetre</span><span class="o">::</span><span class="n">MaFenetre</span><span class="p">()</span> <span class="o">:</span> <span class="n">QWidget</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">setFixedSize</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">);</span>
<span class="n">m_slider</span> <span class="o">=</span> <span class="k">new</span> <span class="n">QSlider</span><span class="p">(</span><span class="n">Qt</span><span class="o">::</span><span class="n">Horizontal</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span>
<span class="n">m_slider</span><span class="o">-></span><span class="n">setRange</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span> <span class="mi">600</span><span class="p">);</span>
<span class="n">m_slider</span><span class="o">-></span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">150</span><span class="p">,</span> <span class="mi">20</span><span class="p">);</span>
<span class="n">QObject</span><span class="o">::</span><span class="n">connect</span><span class="p">(</span><span class="n">m_slider</span><span class="p">,</span> <span class="n">SIGNAL</span><span class="p">(</span><span class="n">valueChanged</span><span class="p">(</span><span class="kt">int</span><span class="p">)),</span> <span class="k">this</span><span class="p">,</span> <span class="n">SLOT</span><span class="p">(</span><span class="n">changerLargeur</span><span class="p">(</span><span class="kt">int</span><span class="p">)));</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>
<p>Cependant le compilateur de Qtcreator ralle lorsqu'il tombe sur cette ligne de l'entête</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="codehilite"><pre><span class="k">class</span> <span class="nc">MaFenetre</span> <span class="o">:</span> <span class="k">public</span> <span class="n">QWidget</span>
</pre></div>
</td></tr></table>
<p>et cela depuis que j'ai ajouté la macro Q_OBJECT
Je ne sais pas si quelqu'un pourrait m'expliquer ce qui ne va pas.
Merci d'avance.</p>