#1 Le 09/11/2013, à 02:10
- temps
[résolu] <QThread> choix run et start
Bonjour,
De manière à pouvoir manipuler les curseurs (slider) créant les sons pendant que je joue la musique avec une de mes pages sous qt5, j'ai créé une class QThread
Cette classe, je l'ai nommé FaitDehors, elle possède un .cpp et un .h
Quand j'appelle (je fais jouer la musique)
FaitDehors enavant;
enavant.run();
en plaçant le code dans le main,
j'obtient du séquentiel, en d'autre mots, je joue bien de la musique et ensuite se produit l'action suivante "ouvrir ma fenêtyre(inutile d'avoir un Thread pour ça)
si je place dans main
FaitDehors enavant;
enavant.start();
C'est parfait, j'ouvre ma fenêtre (action suivante en même temps que je joue de la musique.
Jusque là tout va bien.
Le problème c'est que mon synthétiseur ne se trouve pas dans le main, mais dans une fenêtre derrière une autre fenêtre.
Quand j'appelle
FaitDehors enavant;
enavant.run();
dans la fenêtre, je joue bien le son, mais je ne peux toucher les curseurs pour jouer le son suivant, comme dans main, c'est du séquentiel. C'est normal.
mais le problème est que quand je mets
FaitDehors enavant;
enavant.start();
dans la fenêtre, tout compile bien, l'application se lance bien, mais à la première demande de lecture d'un son, tout plante avec ce message d'erreur
Démarrage de /home/pit/build-lm9jo-Desktop-Debug/lm9jo...QThread: Destroyed while thread is still running
Le programme s'est terminé subitement.
/home/pit/build-lm9jo-Desktop-Debug/lm9jo a quitté avec le code 0
Est-ce que quelqu'un a un début de solution ?
Cordialement
Dernière modification par temps (Le 09/11/2013, à 19:09)
Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net
Hors ligne
#2 Le 09/11/2013, à 12:03
- jacobus77
Re : [résolu] <QThread> choix run et start
QThread: Destroyed while thread is still running
Si par hasard tu fais ton allocation sur le stack ton QThread sera vraisemblablement détruit avant d'avoir fait quoi que ce soit d'utile.
Hors ligne
#3 Le 09/11/2013, à 13:59
- temps
Re : [résolu] <QThread> choix run et start
Merci pour la réponse.
En reprenant les termes sur le moteur de recherche, j'ai cru comprendre qu'il faut ajouter quelque chose de manière à ce que le Thread "FaitDehors" ne se ferme pas avant qu'il ai fini son exécution. Du genre lier une fin d'exécution.
Je donne mon Qthread .h et .cpp car je ne sais si c'est possible à moin de changer mon lecteur audio.
Voici le FaitDehors.h
#ifndef FAITDEHORS_H
#define FAITDEHORS_H
#include <QThread>
#include <QtCore>
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <iostream>
#include <iostream>
#include <QObject>
#include <QMessageBox>
#include <QKeyEvent>
#include <ctype.h>
#include <qwidget.h>
class FaitDehors : public QThread
{
Q_OBJECT
public:
/* FaitDehors(QObject *parent = 0);*/
void run();
protected:
public slots:
private:
};
#endif // FAITDEHORS_H
et voici le FaitDehors.cpp
#include <QApplication>
#include "MaFenetre.h"
#include "Acapela.h"
#include "MaBasse.h"
#include "MaFlute.h"
#include "MaGuiElec.h"
#include "MaGuitare.h"
#include "MonDrum.h"
#include "MonOrgue.h"
#include "MonPiano.h"
#include "MonSaxo.h"
#include "Nature.h"
#include "MonViolon.h"
#include "FaitDehors.h"
#include <QThread>
#include <QtCore>
void FaitDehors::run()
{
system("play joris1.wav");
}
Cordialement
Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net
Hors ligne
#4 Le 09/11/2013, à 19:07
- temps
Re : [résolu] <QThread> choix run et start
Bonjour,
Je poste en résolu, car en manipulant qt je m’aperçois que cet outil n'est pas le meilleur pour travailler sur plusieurs thread. (plusieurs taches "fonctions" en même temps). C'est très lourd et consommateur de ressources sous qt . Quand j'ai créé la possibilité de jouer plusieurs notes du clavier en même temps sur les instruments de musique, j'ai utilisé d'une manière naturelle les fonctions du noyau linux qui sait faire ça très bien.
Il me semble que vouloir utiliser qt pour lui faire faire quelque chose qu'il fait très mal, n'est pas cohérent aussi je reprends pour le synthétiseur la première méthode en ne laissant que la gestion graphique à qt pour garder toutes les gestions intelligentes au bash (ou peut-être plus tard par fun je ferai une version en C).
N.B. j'ai trouvé une solution aussi sous qt en déplaçant la class dans le main, mais préfère ne rien laisser de ça quant un simple
#/bin/bash
play joris1.wav
exit 0
suffit
Cordialement
Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net
Hors ligne
#5 Le 09/11/2013, à 21:15
- jacobus77
Re : [résolu] <QThread> choix run et start
FaitDehors dérive directement de QThread, tu alloues sur le stack, FaitDehors et le thread qu'il gère sont détruits dés qu'ils sortent du scope.
FaitDehors *enavant = new FaitDehors();
Hors ligne
#6 Le 09/11/2013, à 21:39
- temps
Re : [résolu] <QThread> choix run et start
Bonjour,
Merci pour ces précieux renseignements.
Sur la version actuelle (gestion multi-taches en bash), je peux bouger les curseurs, jouer les sons synthétisés en fonction de la position des curseurs, mais je ne sais pas pourquoi le bouton qui change la valeur qui permet à la boucle de lecture de tourner, ne fonctionne pas.
En d'autres mots, le bouton d'arrêt du synthé ne fonctionne pas alors que tout le reste marche très bien. j'ai essayé de while à do while mais le problème reste
Peut-être une erreur dans le code ou c'est qt , dans son fonctionnement il ne regarde la valeur d'une variable que quand il lance le void et après il ne réajuste pas les valeurs de variables. Il faut que je gratte un peu plus
Cordialement
Dernière modification par temps (Le 09/11/2013, à 21:42)
Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net
Hors ligne
#7 Le 11/11/2013, à 10:52
- temps
Re : [résolu] <QThread> choix run et start
Bonjour,
Le concept de la bascule me semble simple mais je galère pour le réaliser sous qt5. (j'y arrive pas).
Le problème :
De manière à avoir un synthé qui joue en continue, j'ai besoin d'avoir deux taches séparées lancées par la même fonction et comme c'est qt (le gestionnaire graphique qui possède les valeurs créant les sons), je suis obligé d'avoir ces deux taches sous qt.
Le bilan, c'est que sans mettre la deuxième tache (QThread nommé FaitDehors) ) dans le main, je n'y arrive pas, je retombe toujours sur le même message d'erreur. ça compile bien sans erreur, ça ouvre bien les fenêtres sans erreur mais quand je demande la lecture, soit elle ne se fait pas, en disant que qwidget ne peut traversé les class, soit l'appli se ferme.
Je vais essayer une nouvelle technique en passant par le main, le principe je garde ma fenêtre du synthé, je crée un QThread dans le main, quand la lecture est demandée, je fait un connect vers le QThread qui vient lancer la lecture audio dans la fenêtre.
A la fin de la fonction lecture audio dans la fenêtre, j'envoie un signal de fin qui se connecte au QThread qui relance la lecture audio.
Je mets au début de la fonction lecture audio une condition sur une variable qui autorise ou stop la lecture audio. Je pilote cette variable à l'aide du bouton d'arrêt.
J'ai intégré mon QThread dans le main
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FaitDehors* newThread = new FaitDehors();
MaFenetre fenetre;
fenetre.show();
return app.exec();
}
FaitDehors.cpp
#include <QApplication>
#include "MaFenetre.h"
#include "Acapela.h"
#include "MaBasse.h"
#include "MaFlute.h"
#include "MaGuiElec.h"
#include "MaGuitare.h"
#include "MonDrum.h"
#include "MonOrgue.h"
#include "MonPiano.h"
#include "MonSaxo.h"
#include "Nature.h"
#include "MonViolon.h"
#include "FaitDehors.h"
#include "LM.h"
#include <QThread>
#include <QtCore>
FaitDehors::FaitDehors(QObject* parent):
QThread(parent)
{
// instanciation objets de travail...
// long traitement
start();
tamporise = new QTimer();
}
FaitDehors::~FaitDehors()
{
exit();
wait();
// nettoyage
}
void FaitDehors::run()
{
/* tamporise =200;*/
void ouvrirLecteur();
// emit signal();
// long traitement effectué dans le thread crée
}
void lance()
{
void signal();
}
void signal()
{
}
FaitDehors.h
#ifndef FAITDEHORS_H
#define FAITDEHORS_H
#include <QThread>
#include <QtCore>
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <iostream>
#include <iostream>
#include <QObject>
#include <QMessageBox>
#include <QKeyEvent>
#include <ctype.h>
#include <qwidget.h>
class FaitDehors : public QThread
{
Q_OBJECT
public:
void signal();
void lance();
FaitDehors(QObject* parent = NULL);
virtual ~FaitDehors();
protected:
virtual void run();
private:
QTimer *tamporise;
};
#endif // FAITDEHORS_H
appel dans ma fenêtre LM
FaitDehors *externe = new FaitDehors();
QObject::connect(externe, SIGNAL(signal()), this, SLOT(ouvrirLecteur()));
/* FaitDehors *externe1 = new FaitDehors();
QObject::connect(ba_bouton, SIGNAL(clicked()), externe1, SLOT(start()), Qt::DirectConnection);*/
externe->start();
QObject::connect(ba_bouton, SIGNAL(clicked()), this, SLOT(FaitDehors::run()));
Tout se compile et les fenêtres s'ouvrent bien, mais pas de mélodie car j'ai en réponse au clique
Démarrage de /home/pit/build-lm9jo-Desktop-Debug/lm9jo...QObject::connect: No such signal QThread::signal() in ../lm9jo/LM.cpp:2842/home/pit/build-lm9jo-Desktop-Debug/lm9jo a quitté avec le code 0
Démarrage de /home/pit/build-lm9jo-Desktop-Debug/lm9jo...QObject::connect: No such signal QThread::signal() in ../lm9jo/LM.cpp:2842
QObject::connect: No such slot LM::FaitDehors::start() in ../lm9jo/LM.cpp:2848
/home/pit/build-lm9jo-Desktop-Debug/lm9jo a quitté avec le code 0
Démarrage de /home/pit/build-lm9jo-Desktop-Debug/lm9jo...QObject::connect: No such signal FaitDehors::signal() in ../lm9jo/LM.cpp:2842
QObject::connect: No such slot LM::FaitDehors::start() in ../lm9jo/LM.cpp:2848
/home/pit/build-lm9jo-Desktop-Debug/lm9jo a quitté avec le code 0
Démarrage de /home/pit/build-lm9jo-Desktop-Debug/lm9jo...QObject::connect: No such signal FaitDehors::signal() in ../lm9jo/LM.cpp:2842
QObject::connect: No such slot LM::FaitDehors::run() in ../lm9jo/LM.cpp:2848
Visiblement, c'est un problème de slot dans QThread, je vais essayé de gratter pour trouver la solution
Cordialement
Dernière modification par temps (Le 11/11/2013, à 15:56)
Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net
Hors ligne
#8 Le 11/11/2013, à 23:33
- jacobus77
Re : [résolu] <QThread> choix run et start
Je te conseilles de lire cette page en entier, les choses seront surement pus claire aprés.
http://qt-project.org/doc/qt-5.0/qtcore … slots.html
QObject::connect: No such signal QThread::signal() in
Regardes le code à la fin de la page... sinon tu as plein d'exempes fournis avec QtCreator.
Tu as aussi QtConcurrentRun ça sera peut-être plus adapté à ton besoin (c'est bcp plus simple à mettre en pace que les QThread).
Hors ligne
#9 Le 12/11/2013, à 00:28
- temps
Re : [résolu] <QThread> choix run et start
Merci pour les liens,
Je m'étais orienté vers une autre technique, à savoir essayer d'inclure dans la fonction à l'aide d'un connect la valeur qui permet de stopper la boucle de lecture des sons créés, en suite il faudra que je construise un timer en fonction des temps positionnés sur les slider, mais mais toujours en galère, je me demande même si QThread ne déforme pas mes signaux audio, il faut que je regarde si c'est une erreur de code de ma part ou si c'est vraiment le cas. Je comprends pas parfois mes signaux se construisent bien, et parfois j'ai comme des plateaux qui n'ont rien à voir avec la position des slider.
Cordialement
Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net
Hors ligne
#10 Le 12/11/2013, à 20:51
- temps
Re : [résolu] <QThread> choix run et start
Bonjour,
Avant de me lancer plus dans les connect, j'ai repris encore une fois l'analyse du problème.
Depuis le début l'origine vient du fait que je lance la lecture sous qt qui une fois que le bouton a lancé une fonction, temps que celle-ci n'est pas fini tout est bloqué.
La première solution a été de donner l'action longue (lecture audio) au bash, ainsi il était à nouveau possible d'utiliser les sliders et les sélections des formes pendant la lecture.
Ensuite, j'ai essayé sans succès l'option QThread, mais bien que je n'ai pas réussit à utiliser cette fonction, j'ai pu observer qu'il est probable qu'elle ait posé un problème en interférant sur d'autres fonctions.
J'ai ensuite pensé à essayer de faire des connect dans la fonction lancée par le bouton, ce qui a l'avantage d'éviter QThread.
Tout ce raisonnement tient sur le fait que j'ai décidé que c'est en cliquant sur un bouton de la fenêtre que devait commencer la lecture.
Et si je lançais la lecture à l'ouverture de la fenêtre ? Il me suffirait de mettre des durées longues de faible amplitude pour que le son ne soit pas audible.
Une tampo qui arrete la lecture automatiquement. Le bouton pour relancer la lecture ne serait qu'un bouton qui change une valeur, et pour l'arrêt pareille.
Avant d'essayer la solution avec les connect, je vais essayer plutot la gestion des événements en c++
Cordialement
Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net
Hors ligne
#11 Le 20/11/2013, à 00:05
- temps
Re : [résolu] <QThread> choix run et start
Bonjour,
Après de multiples test je suis revenue à une utilisation de QThread.
Le système fonctionne comme je veux à l'aide d'un mélange de bash, de qthread, de usleep
Il me reste encore à régler le destructeur car si j'arrive à bien tout faire fonctionner en démarrant deux thread dans le main, par contre quand je demande la fermeture, je ne ferme qu'un thread
voici mon main
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
LM* icioula = new LM();
MaFenetre fenetre;
QThread* thread = new QThread;
QObject::connect(thread, SIGNAL(started()), icioula, SLOT(enDemanDeSon()));
QObject::connect(icioula, SIGNAL(finished()), thread, SLOT(quit()));
QObject::connect(icioula, SIGNAL(finished()), icioula, SLOT(deleteLater()));
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
fenetre.show();
return app.exec();
}
Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net
Hors ligne
#12 Le 28/06/2014, à 05:15
- temps
Re : [résolu] <QThread> choix run et start
Bonjour,
Toujours sur Qt et les thread
j'ai jusqu'à présent utilisé soit des bash soit des fork afin d'ouvrir plusieurs thread en même temps (utilisation de plusieurs touches en même temps du piano virtuel que j'ai créé)
Mon outil fonctionne avec le fork qui appel une fonction placée en bas du fichier cpp,
est-ce quelqu'un sait comment remplacer d'une manière simple le fork par une fonction qthread qui ferai la même chose ?
Et qui bien sure s’exécuterait à une vitesse proche de celle du fork.
L’application actuelle est composée de 3 fichiers, le main, lafenetre.cpp et lafenetre.h
Dans lafenetre.cpp je dessine un clavier, je piste les cliques et les touches du clavier azerty, au premier appel d'une note je la synthétise en utilisant la technique que j'ai crée pour le projet BAUL (avec 3octets) et enfin je lance la lecture du fichier audio synthétisé (le tout est très léger avant d'avoir finit d'appuyer sur la touche on a déja entendue le son)
Cordialement
Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net
Hors ligne