1 votes

Comment déboguer les événements perdus publiés à partir d'un thread non-GUI dans Qt?

Comme le sujet le dit, je poste des événements à partir d'un thread non-GUI (dans un thread GStreamer, pour être précis). Le code ressemble à cela :

GstBusSyncReply on_bus_message(GstBus* bus, GstMessage* message, gpointer data)
{
    bool ret = QMetaObject::invokeMethod(static_cast(data), "stateChanged", Qt::QueuedConnection);
    Q_ASSERT(ret);

    return GST_BUS_PASS;
}

Le problème est que stateChanged (peu importe s'il s'agit d'un slot ou d'un signal) n'est pas appelé. J'ai suivi QMetaObject::invokeMethod avec un débogueur, je l'ai suivi jusqu'à ce qu'il appelle PostMessage (c'est Qt 4.6.2 sur Windows, au fait) - tout semblait être correct.

L'objet pointé par data vit dans le thread GUI, j'ai double-vérifié cela.

Comment puis-je déboguer ce problème ? Ou, mieux encore, peut-être le contourner complètement ?

0voto

rubo77 Points 2294

Oh mon dieu.

Je suis tellement stupide.

J'ai littéralement passé des journées à déboguer ceci.

Et le problème ressemblait à ceci:

bool VideoWidget::even(QEvent* e)
{
    if (!impl_)
        return false;

    // ...
}

Oui, j'ai réimplémenté QObject::event() (pour ajouter un traitement spécial pour les événements de affichage/masquage et redimensionnement), et je n'ai pas appelé la méthode de base. Et, devinez quoi, Qt::QueuedConnection utilise des événements QEvent pour effectuer les appels différés.

Ne faites jamais les choses comme je l'ai fait. Vraiment.

Ou, cher Qt, pouvez-vous s'il vous plaît utiliser NVI pour nous protéger contre ce genre d'erreurs?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X