Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Candidat au Club
    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 :



    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.

  2. #2
    Candidat au Club
    Hello !

    J'ai finalement trouvé la solution par moi même est c'était on ne peut plus con. Il ne fallait pas mettre le code qui met le fond de la QWebView à transparent dans la classe de la fenêtre mais dans une surcharge de la méthode paintEvent de QWebView.

    Comme ceci :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	public class WebBrowserTestQWebView extends QWebView
    	{
    		@Override
    		public void paintEvent(QPaintEvent event)
    		{
    			QPalette palette = this.palette(); 
    			palette.setBrush(QPalette.ColorRole.Base, new QBrush(new QColor(Qt.GlobalColor.transparent)));
    			this.setPalette(palette); 
    			this.setAttribute(Qt.WidgetAttribute.WA_OpaquePaintEvent, false);
    			super.paintEvent(event); 
    		}
    	}


    Maintenant ça se comporte comme je le souhaite.