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 :
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
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
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>
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
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()"); } }
Voilà voilà ! Merci d'avance à tous ceux qui se pencheront sur le problème.
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); } }
Partager