Qt- Comment utiliser la connexion entre le signal incompatible et le slot

J’essaye de faire un jeu. En cela, je veux appeler une fonction, cette fonction recevra un point. Mais cette fonction doit être invoquée par le signal de temporisation de la timer. Quelqu’un peut-il dire comment y parvenir? Ci-dessous le code requirejs / d’erreur

Point p(a,b); connect(timer,SIGNAL(timedout()),this,startDestruction(p)); 

Quelqu’un peut-il dire comment y parvenir?

Créez une méthode à utiliser comme emplacement intermédiaire, comme ceci.

 Point p(a,b); connect(timer, SIGNAL(timedout()), this, q); q() { startDestruction(this->p) } 

Votre conception est défectueuse;

  • vous créez p sur la stack
  • vous voulez que Qt empêche cet object de mourir et le réutilise chaque fois qu’un signal est appelé

Votre problème est généralement résolu en utilisant QSignalMapper , mais cela ne prend en charge que QSsortingng , int , QWidget* et QObject* tant que types de parameters.

Si vous voulez utiliser d’autres types, vous devez implémenter votre propre mappeur de signal (ne détestez-vous pas que Qt ne vous laisse pas créer des modèles de classe dérivés de QObject s? 🙂 comme ceci:

 class PointSignalMapper : public QObject { Q_OBJECT public: explicit PointSignalMapper( QObject * parent=0 ) : QObject( parent ), m_map() {} void setMapping( QObject * sender, const Point & p ) { if ( sender ) m_map[sender] = p; } public Q_SLOTS: void map() { map( sender() ); } void map( QObject * sender ) { if ( !sender ) return; const QMap::const_iterator it = m_map.constFind( sender ); if ( it != m_map.constEnd() ) emit mapped( it.value() ); } Q_SIGNALS: void mapped( const Point & p ); private: QMap m_map; }; 

Usage:

 PointSignalMapper * mapper = new PointSignalMapper( this ); connect( mapper, SIGNAL(mapped(Point)), this, SLOT(pointDestroyed(Point)) ); mapper->setMapping( qObject1, point1 ); connect( qObject1, SIGNAL(timedout()), mapper, SLOT(map()) ); mapper->setMapping( qObject2, point2 ); connect( qObject2, SIGNAL(timedout()), mapper, SLOT(map()) ); // ... 

Dans votre cas particulier:

 Point p(a,b); PointSignalMapper * mapper = new PointSignalMapper( this ); // added mapper->setMapping( timer, p ); // added connect( timer, SIGNAL(timedout()), mapper, SLOT(map()) ); // added connect( mapper, SIGNAL(mapped(Point)), // modified this, startDestruction(Point)) ) 

Vous devez généralement créer un emplacement intermédiaire déclenché par le minuteur, puis appeler startDestruction avec le point.

Qu’en est-il de la refonte de votre classe, de sorte que startDestruction () est un emplacement de p. Lorsque p.startDestruction () est appelé, il émet un signal pour notifier la classe principale.

 connect(timer,SIGNAL(timedout()),p,startDestruction()); connect(p,SIGNAL(destroyed()),this,destroyHandle()); 

Voici un exemple qui fonctionne, mais pas si minimal.

Qt exige que la classe dérivée de QObject simulée ne soit pas dans le fichier principal, et c’est pourquoi Pipe est séparé. L’utilisation d’un object comme wrapper au lieu d’une fonction offre une plus grande flexibilité et ne vous oblige pas à encapsuler une variable dans un champ (aucun changement d’architecture).

Sortie

 Destroyed target at [40, 12] Destroyed target at [41, 11] Destroyed target at [42, 10] 

main.cpp

 #include "Game.h" #include "Pipe.h" #include  #include  int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); Game game; Point target(40, 12); Pipe pipe(&game, &target); pipe.pass(); QTimer::singleShot(500, &pipe, SLOT(pass())); QTimer::singleShot(1000, &pipe, SLOT(pass())); QTimer::singleShot(2000, &app, SLOT(quit())); return app.exec(); } 

Game.h

 #ifndef GAME_H #define GAME_H #include  struct Point { int x; int y; Point(int _x, int _y) : x(_x), y(_y) {} }; class GameInterface { public: virtual void startDesturction(Point * pt) = 0; }; class Game : public GameInterface { public: virtual void startDesturction(Point * pt) { std::cout<<"Destroyed target at ["<x<<", " <y<<"]"<x += 1; pt->y -= 1; } }; #endif // GAME_H 

Pipe.h

 #ifndef PIPE_H #define PIPE_H #include "Game.h" #include  class Pipe : public QObject { Q_OBJECT public: Pipe(GameInterface * game, Point * target) : QObject(), m_game(game), m_target(target) {} virtual ~Pipe() {} public slots: void pass() { m_game->startDesturction(m_target); } private: GameInterface * m_game; Point * m_target; }; #endif // PIPE_H