Bonjour,

Je code une application qui demande un traitement réguliers (jouer un son) et pour cela j'utilise un QThread (normal non ?). J'ai lu la documentation et quelques posts sur des forums us et fr et je suis là car même après tout ça je ne trouve pas mon erreur.

J'ai une classe battement qui dérive de QThread, elle est chargée de jouer un son toute les n-secondes, j'ai donc d'un coté cette classe qui s'occupe de faire le traitement "jouer le son" dans la méthode run() et d'un autre coté j'ai une classe qui dérive de QWidget qui me permet de lancer le Thread et l'arrêter (of course), sur le papier c'est pas mal mais quand je lance le Thread j'ai cette erreur :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QApplication(0x22fe68), parent's thread is QThread(0x317480), current thread is QThread(0x1495f90)
QThread: Destroyed while thread is still running
Pas de code graphique dans le Thread ? c'est ce que j'ai lu partout et il ne me semble pas en avoir, je ne fait que des traitements..

J'ai essayer de lancer mon Thread via l'événement d'un bouton (clicked) avec un slot perso mais pas moyen, et j'ai tenté de lancer le thread avec le signal du bouton sur le slot start() du thread, mais là toujours la même erreur..

Je sèche mais j'aimerais vraiment comprendre ce qui cloche voici donc mon code (qui n'est pas trop long heureusement)

battement.h : La thread en action

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
#ifndef BATTEMENT_H
#define BATTEMENT_H
 
#include <QThread>
#include <QString>
#include <QSound>
#include <QObject>
 
class Battement : public QThread
{
public:
    Battement(QObject *parent = 0);
    virtual ~Battement();
 
protected:
    void run();
 
    // Mutateur inline
    int currentBpm() { return m_bpm; }
    int currentSample() { return m_sampleName; }
    // Accesseur
    void setBpm(const int&);
    void setSample(const int&);
 
private:
    QString determineStringSample();
    // Determine le temps de pause entre chaque battement
    // 1 seconde / nombre de battements par secondes
    float determineTempo() { return (60000 / m_bpm); }
 
private:
    int m_bpm;
    int m_sampleName;
    float m_tempo;
};
 
#endif // BATTEMENT_H
battement.cpp

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 
#include "battement.h"
 
Battement::Battement(QObject *parent) : QThread(parent)
{
    m_bpm = 96;
    m_sampleName = 2;
}
Battement::~Battement()
{
 
}
 
void Battement::run()
{
    msleep(long(determineTempo()));
    QSound::play(determineStringSample());
    exec();
}
 
void Battement::setBpm(const int &bpm)
{
    if (bpm <= 30)          // Bpm Min
        m_bpm = 30;
    else if (bpm >= 250)    // Bpm Max
        m_bpm = 250;
    else
        m_bpm = bpm;        // Bpm Perso
}
 
void Battement::setSample(const int &sampleName)
{
    m_sampleName = sampleName;
}
 
QString Battement::determineStringSample()
{
    QString sampleName;
 
    switch (m_sampleName)
    {
    case 0: sampleName = "/res/samples/bass1.wav";   break;
    case 1: sampleName = "/res/samples/bass2.wav";   break;
    case 2: sampleName = "/res/samples/noise.wav";   break;
    case 3: sampleName = "/res/samples/snare1.wav";  break;
    case 4: sampleName = "/res/samples/snare2.wav";  break;
    case 5: sampleName = "/res/samples/snare3.wav";  break;
    case 6: sampleName = "/res/samples/snare4.wav";  break;
    default: sampleName = "/res/samples/noise.wav";  break;
    }
    return sampleName;
}
YMetronome.cpp : Voilà où ça coince (je vous épargne le code qui n'a rien à voir)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "YMetronome.h"
 
YMetronome::YMetronome() : QWidget()
{
    initializeWindow();
    initializeComponents();
    initializePresentation();
    initializeConnections();
}
 
YMetronome::~YMetronome()
{
    delete e_battement;
}
 
// Méthodes d'intialisation
void YMetronome::initializeWindow()
{
    setFixedSize(500, 150);
    e_battement = new Battement;      // 1. Déclaration :D
}
 
// Des méthodes qui n'ont rien à voir avec notre (mon) problème
 
void YMetronome::initializeConnections()
{
    QObject::connect(m_btLancer, SIGNAL(clicked()), this, SLOT(playSample()));
    QObject::connect(m_btStopper, SIGNAL(clicked()), this, SLOT(stopSample()));
    QObject::connect(m_sbBpmPerso, SIGNAL(valueChanged(int)), this, SLOT(bpmChanged(int)));
    QObject::connect(m_cbChoixBpm, SIGNAL(currentIndexChanged(int)), this, SLOT(bpmChanged(int)));
    QObject::connect(m_cbChoixSample, SIGNAL(currentIndexChanged(int)), this, SLOT(sampleChanged(int)));
    QObject::connect(m_btLancer, SIGNAL(clicked()), e_battement, SLOT(start())); // 2.Derniers trucs essayés
}
 
 
// Slots personnalisés
void YMetronome::playSample()
{
    // e_battement->start(); 
    emit playingSample(true);
}
 
void YMetronome::stopSample()
{
    // e_battement->quit();
    emit playingSample(false);
}

Je n'est pourtant pas de code graphique dans mon Thread donc je ne comprend pas trop ce qui se passe. Je ne suis pas contre une petite explication Bon je retourne sur la FAQ Qt en attendant (j'ai trouvé des posts qui la pointait mais je n'y ai pas trouvé réponse à mon problème)

Merci.