Bonjour,

je m'essaye au GUI et j'ai choisit FLTK. J'aimais assez le fonctionnement de QT mais je le trouve assez lourd et je souhaite pouvoir développer avec peu d'espace disque. Je me suis essayé à GTK mais je suis rapidement tombé sur un souci, mon incapacité à lancer l'interface dans un thread.

J'ai fais des tests avec fltk et tout semble fonctionner.

Mon problème est le suivant.

Je souhaite réaliser un lecteur de son mp3. J'utilise STK pour la lecture et pour l'affichage FLTK.

j'ai un thread de lecture du son, un main et un thread gtk.

Pour simuler la lecture du son en boucle, j'incrémente un float dans la boucle principale main() et j'affiche cette valeur sur ma fenêtre fltk.

Voici le code que j'obtiens :

Définition de la class :
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
class SampleWindow : public Window {
 
    private:
        IntInput intinput;
        Button copy_button;
        Button down_button;
        Button up_button;
        Button exit_button;
 
    public:  
        Slider slider;
        float* m_val;
 
    inline void copy_callback_i();
    static void copy_callback(Widget*, void* v);
    inline void down_callback_i();
    static void down_callback(Widget*, void* v);
    inline void up_callback_i();
    static void SampleWindow::up_callback(Widget*, void* v);
    inline void slider_callback_i(Slider* slider);
    static void slider_callback(Widget* w, void* v);
 
 
  SampleWindow(const char* label, float* val);
  ~SampleWindow();
 
};
Implémentation

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
SampleWindow::SampleWindow(const char* label=0, float* val=0):
    Window(USEDEFAULT,USEDEFAULT,320,90,label,true),
    intinput(10,10,100,20),
    copy_button(110,10,100,20,"copy to slider"),
    slider(10,35,300,20),
    down_button(50,60,50,20,"down"),
    up_button(150,60,50,20,"up"),
    exit_button(250,60,50,20,"exit")
{
 
    copy_button.callback(copy_callback,this);
    down_button.callback(down_callback,this);
    up_button.callback(up_callback,this);
    slider.callback(slider_callback,this);
    slider.set_horizontal(); slider.type(Slider::TICK_ABOVE);
    slider.range(-100,100);
    slider.step(0.1);
    slider.value(-100);
    exit_button.callback(exit_callback);
    m_val = val;
    add_idle(IdleCallback, this);
    end();
 
}
 
SampleWindow::~SampleWindow()
{
}
 
 
inline void SampleWindow::copy_callback_i()
{
    slider.value(intinput.ivalue());
    *m_val = intinput.ivalue();
}
 
void SampleWindow::copy_callback(Widget*, void* v)
{
    ((SampleWindow*)v)->copy_callback_i();
}
 
inline void SampleWindow::down_callback_i()
{
    slider.value(slider.value()-0.1);
    intinput.value(slider.value());
    *m_val = slider.value()-0.1;
}
 
void SampleWindow::down_callback(Widget*, void* v)
{
    ((SampleWindow*)v)->down_callback_i();
}
 
inline void SampleWindow::up_callback_i()
{
    slider.value(slider.value()+0.1);
    intinput.value(slider.value());
    *m_val = slider.value()-0.1;
}
 
void SampleWindow::up_callback(Widget*, void* v)
{
    ((SampleWindow*)v)->up_callback_i();
}
 
inline void SampleWindow::slider_callback_i(Slider* slider)
{
    intinput.value(slider->value());
    *m_val = slider->value();
 
}
 
void SampleWindow::slider_callback(Widget* w, void* v)
{
    ((SampleWindow*)v)->slider_callback_i((Slider*)w);
}

Le main :

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
int main(int argc, char ** argv) {
 
pthread_t idInterface;       //keyboard thread id
 
float val = 0;
 
  int interfaceError  = pthread_create(&idInterface, NULL, interface, &val);
 
  while(running)
  {
    for (float i = -100; i<=100 ; i=i+0.1)
    {
      usleep(800);
      val = i;
    } 
  }
 
  return 0;
}

La fonction pour le thread:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
void* interface(void *var)
{
  float *valeur = (float*) var;
  SampleWindow window1("Window 1", valeur);
  window1.show();
  run();
}

Les fonctions globales utilisées pour les callback :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
void IdleCallback(void* pData)
{
 if (pData != NULL)
 {
	 SampleWindow* pWindow = reinterpret_cast<SampleWindow*>(pData);
	 pWindow->slider.value(*(pWindow->m_val));
	 pWindow->redraw();
 }
 
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
static void exit_callback(Widget *, void *)
{
  running = 0;
  exit(0);
}
l'entête :

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
#include <fltk/run.h>
#include <fltk/Window.h>
#include <fltk/Slider.h>
#include <fltk/Button.h>
#include <fltk/IntInput.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>   // For the multi-threading
#include <iostream>
 
using namespace fltk;
using namespace std;
 
void* interface(void *var); //Keyboard input
 
void IdleCallback(void* pData);
static void exit_callback(Widget *, void *) ;
 
int running = 1;

Mon problème est le suivant, je n'arrive pas à utiliser le slider pour fixer la valeur du slide lorsque j'utilise le rafraichissement et l'appel à la fonction IdleCallback(). Des fois ça passe et d'autre non.... j'ai comme l'impression qu'il faudrait que j'utilise des mutex ??

Par ailleurs sous OSX dès que la fenêtre n'est pas en focus, elle se met à bouffer les ressources proc....(je peux ouvrir un thread spécific pour cela).

Merci d'avance !

Gabriel