problème avec QT

problème avec QT - C++ - Programmation

Marsh Posté le 15-06-2006 à 14:52:54    

Bonjour,
 
J'utilise QT pour créer une petite interface graphique. J'ai un thread lancé en parallèle du main. Quand je viens écrire dans une QListBox depuis le thread, ça ne s'affiche pas. Il faut que je bouge la fenêtre pour que ça s'affiche. Je pense qu'il s'agit d'un problème de rafraîchissement, mais je ne trouve pas de fonction qui rafraîchisse l'affichage.
Est-ce que quelqu'un connaît une solution ? Merci d'avance pour vos réponses.
 
Jérôme

Reply

Marsh Posté le 15-06-2006 à 14:52:54   

Reply

Marsh Posté le 15-06-2006 à 20:28:40    

Tu écris comment dans ta QListBox ?
 
Faut que tu envoies un signal à la QListbox avec le texte en paramètre.

Reply

Marsh Posté le 16-06-2006 à 09:14:05    

J'écris dans la QListBox avec insertItem : j'ai créé un Slot Affichage_texte avec comme paramètre le texte à afficher, et dans ce slot, j'utilise insertItem.  
Comment je fais pour envoyer un signal (j'utilise habituellement Qt Designer et je connecte les signaux en reliant les éléments, mais là, ce n'est pas possible) ?

Reply

Marsh Posté le 16-06-2006 à 16:03:11    

Il n'y a pas de slot dans QListBox permettant d'ajouter un item.
 
Dans Qt, il me semble bien que les thread ne doivent pas interagir avec le thread d'UI (je dis "semble" car je ne l'ai pas encore utilisé, mais je l'ai lu dans un bouquin sur Qt3 me semble-t-il :) ).
Il faut que tu définisses un slot dans ta fenêtre qui fasse elle même l'ajout de l'item, ça devrait passer.
 
Sinon, tu as la solution (boîteuse ;) ) d'appeler update() sur ta qlistbox pour demander son réaffichage.

Reply

Marsh Posté le 16-06-2006 à 16:17:31    

voui voui, pas d'interaction directe, les signaux/slots ne fonctionnent pas non plus.
 
La bonne méthode est d'utiliser un évènement customisé. Voir la fonction QObject::customEvent(), la class QCustomEvent, et QApplication:: postEvent().


Message édité par nargy le 16-06-2006 à 16:18:07
Reply

Marsh Posté le 16-06-2006 à 17:01:55    

Hu, effectivement, c'est plus élégant le custom event et je me coucherais moins con, mais les signaux slots ça fonctionne très bien

Reply

Marsh Posté le 16-06-2006 à 17:04:14    

Chez moi ça a buggé les signaux/slots.
Pourtant j'ai essayé, ça avait l'air de marcher, et puis finalement ça me faisait des SEGFAULTs un coup de temps en temps.

Reply

Marsh Posté le 16-06-2006 à 17:09:12    

Hu, je t'assure que les signaux slots sont synchronisés "comme il faut" en multithreadé. C'est spécifié par la doc.
 
Having an event loop in a thread makes it possible to connect signals from other threads to slots in this threads, using a mechanism called queued connections. It also makes it possible to use classes that require the event loop, such as QTimer and QTcpSocket, in the thread.

Reply

Marsh Posté le 16-06-2006 à 17:11:26    

Reply

Marsh Posté le 16-06-2006 à 17:44:31    

J'ai lu la doc, en ligne et en travers. Je réessayerai la prochaine fois. J'ai dû bugger dans les données partagées que j'utilisais.
 
Au final, c'était de toutes façons plus organisé pour ce que je faisait d'utiliser directement le mécanisme d'évènement. (enfin, bref)

Reply

Marsh Posté le 16-06-2006 à 17:44:31   

Reply

Marsh Posté le 16-06-2006 à 19:09:45    

Merci pour toutes vos réponses, je testerai ça lundi matin :)

Reply

Marsh Posté le 18-06-2006 à 18:06:32    

Salut,
 
Voilà où j'avais lu que les signaux/slots n'étaient pas utilisable: http://doc.trolltech.com/3.3/threads.html#8
Vu le nom de ta classe (QListBox), je suppose que tu utilises Qt3, et par conséquent que la restriction s'y applique.
Si tu utilises Qt4, change de widget ;)
 
Edit: balise URL


Message édité par IrmatDen le 18-06-2006 à 18:06:53
Reply

Marsh Posté le 19-06-2006 à 14:26:36    

Oui, j'utilise bien Qt3.2...
Je vais voir si j'y arrive quand même, en utilisant les signaux.

Reply

Marsh Posté le 19-06-2006 à 15:09:27    

Pourquoi persister sur les signaux qui ne sont pas un système sûr? Utilise un customEvent ça se fait sans douleur ;)

Reply

Marsh Posté le 19-06-2006 à 15:13:06    

Ouais, même conseil. C'est pas la mort, juste quelques classes très courtes dérivant de QCustomEvent à déclarer dans un fichier à part, puis une réimplémentation de QObject:: customEvent(), enfin QApplication:: postEvent() là où il faut.

Reply

Marsh Posté le 19-06-2006 à 15:36:07    

Ok, je passe sur CustomEvent (si j'y arrive ;) )

Reply

Marsh Posté le 19-06-2006 à 15:57:24    

Si tu as besoins de faire passer des chaîne de caractères dans un évènement, utilise la classe template QDeepCopy<QString>.
Exemple, un évènement qui envoie un texte vers un widget QTextEdit pour afficher du log:

Code :
  1. enum MyEventType // définir un nouveau type d'evènement
  2. {
  3.   MyEventLog=QEvent::User
  4. };
  5. // définir un nouvelle classe d'évènement
  6. class LogEvent: public QCustomEvent
  7. {
  8.   QDeepCopy<QString> s_; // une chaîne
  9.   public: // construire l'évènement à partir d'un texte
  10.   LogEvent(QString& string):
  11.     QCustomEvent((QEvent::Type)MyEventLog),
  12.     s_(string)
  13.   { }
  14.   QString string() // récupérer le texte // NOTE: pas de <<const>> sur la fonction
  15.   { return s_; }
  16. };


Dans la class Log:

Code :
  1. protected: // redéfinir customEvent
  2.   void customEvent(QCustomEvent* e)
  3.   { // vérifier le type d'évènement
  4.     if(e->type()==(QEvent::Type)MyEventLog)
  5.     { // récupérer le texte
  6.       QString s=((ExecuterLogEvent*)e)->string();
  7.       protected_log(s); // la vraie fonction qui affiche le texte dans un QTextEdit
  8.     }
  9.   }
  10.   public:
  11.   void log(const QString& s) // la fonction qui fonctionne pour toutes les threads
  12.   { // envoyer un évènement au gestionnaire
  13.     QApplication::postEvent(this, new LogEvent(s));
  14.   }


À utiliser de la manière suivante:

Code :
  1. Log log=new Log();
  2. log->log("Hello, world!" ); // ajoute du log quelquesoit la thread en cours


Message édité par nargy le 19-06-2006 à 16:04:26
Reply

Marsh Posté le 19-06-2006 à 16:23:44    

Merci beaucoup, ca marche !!!!! :p

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed