1 pièce(s) jointe(s)
QtJambi et Webkit - problème avec un background transparent
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 :
Pièce jointe 229496
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:
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:
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:
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. :)