Bonjour bonjour !

Je viens vers vous car j'ai un soucis de code avec Qt qui me fait de la résistance depuis plusieurs semaines.

Voici ce que je souhaite faire.
L'idée c'est de charger une interface web codée dans un fichier html (ça, ça marche), de la faire interagir avec le code Java (ça aussi ça marche), d'afficher cette interface web avec un background transparent devant un autre widget dans lequel je dessine des formes, colle des images... pour afficher la scène d'un jeu en 2D par exemple, et ça, ça marche aussi... tant que ça reste statique !

Les problèmes viennent quand l'interface web change avec les manipulations du DOM et du css. A chaque changement, l'ancien affichage n'est pas effacé et le nouveau s'affiche par dessus.
Ce qui nous donne des joyeusetés de ce genre :

Nom : QT-Webkit-bug-005.png
Affichages : 640
Taille : 733,7 Ko

Je vois venir le truc. A chaque mise à jour du widget, celui-ci trace un rectangle avec la couleur de fond pour masquer l'ancien affichage et retracer le nouvel affichage par dessus (classique). Sauf que, pas de pot, la couleur de fond est transparente.

J'ai bien essayé des solutions qui ont été proposées sur le net en utilisant différents modes de composition au moment de masquer l'ancien affichage mais rien n'y fait : soit ça m'affiche la même blague soit ça m'affiche un écran noir. J'ai même essayé de forcé le rafraichissement du widget de derrière avec un repaint() mais ça n'a pas d'effet. Soit ça ne fait rien du tout, soit ça fait le repaint derrière le widget de l'interface web.

Je vous présente tout de même mon code pour vous faciliter la tâche.

La page HTML

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
 
<html>
    <head>
       <meta charset="utf-8" />
 
       <style>
           #body
           {
               position: absolute;
               left: 0px;
               right: 0px;
                top: 0px;
               bottom: 0px;
               overflow: hidden;
           }
 
 
            #button
            {
                position: absolute;
                left: 20px;
                top: 20px;
                background-color: rgba(255, 100, 100, 0.1);
                padding: 10px;
                box-shadow: 0px 2px 5px rgb(0, 0, 0);
                border-radius: 5px;
            }
 
           #token
            {
                position: absolute;
                left: 200px;
                top: 20px;
                background-color: rgba(100, 255, 100, 0.1);
                padding: 10px;
                box-shadow: 0px 2px 5px rgb(0, 0, 0);
                border-radius: 5px;
            }
 
           #console
           {
               background-color: rgba(100, 100, 255, 0.1);
               position: absolute;
               left: 20px;
               right: 20px;
               top: 100px;
               bottom: 20px;
               padding: 10px;
               overflow: auto;
           }
       </style>
 
    </head>
 
    <body>
 
        <div id="button" >Appeler Java</div> <!-- Le bouton rouge qui appelle Java -->
        <div id="console" >Console. <br /></div> <!-- Le bloc bleu où on affiche les messages -->
        <div id="token" >Je bouge.</div> <!-- Le petit bloc vert qui bouge tout seul -->
 
        <script type="text/javascript" >
 
            // Fonction javascript appelée par Java au chargement de la page
            var fromJavaToJavascript = function()
            {
                document.getElementById("console").appendChild(document.createTextNode("J'ai été appelé par le Java. "));
                document.getElementById("console").appendChild(document.createElement("br"));
            };
 
            window.onload = function()
            {
                var count = 0;
 
                // Fonction qui appelle Java et déclenchée par le bouton rouge
               document.getElementById("button").onclick = function()
               {
                   count++;
 
                   // On affiche l'incrément dans le bouton rouge
                   while (document.getElementById("button").firstChild)
                       document.getElementById("button").removeChild(document.getElementById("button").firstChild);
 
                   document.getElementById("button").appendChild(document.createTextNode("Appeler Java " + count));
 
                   // On affiche un message dans le bloc bleu
                   document.getElementById("console").appendChild(document.createTextNode("Je dois appeler le Java. " + javaObject));
                   document.getElementById("console").appendChild(document.createElement("br"));
 
                   // On appelle Java
                   javaObject.submit();
               };
 
                var initPos = 20;
 
                // Le bloc vert bouge tout seul.
                var timer = setInterval(function()
                {
                    initPos = initPos + 5;
 
                    document.getElementById("token").style.top = initPos + "px";
 
                }, 500);
            };
 
        </script>
 
    </body>
</html>
La fenêtre principale

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
 
public class WebBrowserTestFrame extends QMainWindow
{
    protected QGraphicsView view;
    protected QGraphicsScene scene;
    protected WebBrowserTestQWebView browser;
    protected QGridLayout gridLayout;
 
    public WebBrowserTestFrame()
    {
        // Le widget où on affiche une image
        this.scene = new QGraphicsScene();
        QPixmap image = new QPixmap("resources/tests/Coin-coin.jpg");
        this.scene.addPixmap(image);
        this.view = new QGraphicsView(scene);
 
        // Le widget qui charge le fichier HTML
        this.browser = new WebBrowserTestQWebView();
        QPalette palette = this.browser.palette();
        palette.setBrush(QPalette.ColorRole.Base, new QBrush(new QColor(Qt.GlobalColor.transparent)));
        this.browser.setPalette(palette);
        this.browser.setAttribute(Qt.WidgetAttribute.WA_OpaquePaintEvent, false);
 
        // On superpose les 2 widget
        this.gridLayout = new QGridLayout();
        this.gridLayout.addWidget(this.view, 0, 0);
        this.gridLayout.addWidget(this.browser, 0, 0);
 
        // On attache le tout à la fenêtre principale
        QWidget widget = new QWidget();
        widget.setLayout(this.gridLayout);
        this.setCentralWidget(widget);
        this.setWindowTitle("Hello WebKit");
 
        // Evénements de la Web view
        this.browser.loadFinished.connect(this, "loadDone()");
 
        // On charge la page
        QApplication.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                File htmlFile = new File("resources/interfaces/javascript/test.html");
 
                if (htmlFile.exists())
                    browser.load(new QUrl("file://" + htmlFile.getAbsolutePath()));
                else
                    System.out.println("Le fichier n'existe pas");
            }
        });
    }
 
    public void loadDone()
    {
        WebBrowserTestJavascript javascript = new WebBrowserTestJavascript();
        this.browser.page().mainFrame().addToJavaScriptWindowObject("javaObject", javascript);
        this.browser.page().mainFrame().evaluateJavaScript("fromJavaToJavascript()");
    }
}
Ma surcouche de QWebView

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
 
public class WebBrowserTestQWebView extends QWebView
{
    @Override
    public void paintEvent(QPaintEvent event)
    {
        // On tente d'effacer l'ancien affichage de la web view et c'est là que ça coince.
        QPainter painter = new QPainter(this);
        painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_Source);
        painter.fillRect(event.rect(), Qt.GlobalColor.transparent);
        painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceOver);
 
        super.paintEvent(event);
    }
}
Voilà voilà ! Merci d'avance à tous ceux qui se pencheront sur le problème.