QTJambi和Webkit,透明背景问题

时间:2016-12-20 10:45:08

标签: java qt webkit qt-jambi

我对QTJambi和Webkit有一个非常持久的问题。

这是我想要做的。

我想加载一个HTML文件编码的Web界面(它可以工作),在Javascript和Java之间进行一些交互(它也可以工作),在透明背景上显示另一个显示图像的小部件的Web界面(一个2D游戏)只要Web界面是静态的,它也可以工作。

Web界面发生变化时出现问题(DOM和css操作)。当它更改时,不会清除先前的Web视图渲染,并且会绘制新的渲染。 所以,我有这样的渲染:

Picture of the graphic bug

我理解它是如何工作的:显示一个带有背景颜色的矩形以隐藏先前的渲染并显示新的渲染。但背景颜色是透明的。所以它什么也没隐藏。

我尝试了一些我在网络上找到的具有合成模式的解决方案,但它不起作用。我有同样的问题或黑屏。

这是我的代码。

HTML文件:

<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 --> <!-- This red button calls Java -->
    <div id="console" >Console. <br /></div> <!-- Le bloc bleu où on affiche les messages --> <!-- Messages are displayed in this blue block. -->
    <div id="token" >Je bouge.</div> <!-- Le petit bloc vert qui bouge tout seul --> <!-- The moving green block. -->

    <script type="text/javascript" >

        // Fonction javascript appelée par Java au chargement de la page 
        // Java calls this Javascript function when the HTML file is loaded. 
        var fromJavaToJavascript = function()
        {
            document.getElementById("console").appendChild(document.createTextNode("J'ai été appelé par le Java. ")); 
            document.getElementById("console").appendChild(document.createElement("br")); 
        }; 

        // Mon image qui doit recevoir la QPixmap 
        //var qPixmap = new Image(); 

        var readImage = function()
        {
            document.getElementById("console").appendChild(document.createTextNode("Je reçoit une image de java. " + qPixmap)); 
            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 
            // When the red button is clicked, it calls this javascript function which calls a Java function. 
           document.getElementById("button").onclick = function()
           {
               count++; 

               // On affiche l'incrément dans le bouton rouge 
               // Text in red button is updated. 
               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 
               // New message is displayed in the blue block. 
               document.getElementById("console").appendChild(document.createTextNode("Je dois appeler le Java. " + javaObject)); 
               document.getElementById("console").appendChild(document.createElement("br")); 

               // On appelle Java
               // Call Java. 
               javaObject.submit(); 
           }; 

            var initPos = 20; 

            // Le bloc vert bouge tout seul. 
            // The green block is moving. 
            var timer = setInterval(function()
            {
                initPos = initPos + 5; 

                document.getElementById("token").style.top = initPos + "px"; 

            }, 500); 
        }; 

    </script>

</body>
</html>

主框架:

public class WebBrowserTestFrame extends QMainWindow
{
    protected QGraphicsView view; 
    protected QGraphicsScene scene;
    protected WebBrowserTestQWebView browser; 
    protected QGridLayout gridLayout; 

    public WebBrowserTestFrame()
    {
        this.gridLayout = new QGridLayout(); 

        // Le widget où on affiche une image
        // This widget displays an 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 widget loads an HTML file 
        this.browser = new WebBrowserTestQWebView(this.view);
        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 widgets 
        // The 2 widgets are stacked 
        this.gridLayout.addWidget(this.view, 0, 0); 
        this.gridLayout.addWidget(this.browser, 0, 0); 

        // On attache le tout à la fenêtre principale 
        // Widgets are appended to the main frame 
        QWidget widget = new QWidget(); 
        widget.setLayout(this.gridLayout); 
        this.setCentralWidget(widget); 
        this.setWindowTitle("Hello WebKit");

        // Evénements de la Web view
        // Web view events 
        this.browser.loadStarted.connect(this, "loadStarted()");
        this.browser.loadProgress.connect(this, "loadProgress(int)");
        this.browser.loadFinished.connect(this, "loadDone()");
        this.browser.urlChanged.connect(this, "urlChanged(QUrl)");

        // On charge la page
        // Load the HTML file 
        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 loadStarted() 
    {
        System.out.println("Load started"); 
    }

    public void loadDone() 
    {
        WebBrowserTestJavascript javascript = new WebBrowserTestJavascript(); 
        this.browser.page().mainFrame().addToJavaScriptWindowObject("javaObject", javascript); 
        this.browser.page().mainFrame().evaluateJavaScript("fromJavaToJavascript()"); 
    }

    public void loadProgress(int x) 
    {
        System.out.println("Loading: " + x + " %"); 
    }

    public void urlChanged(QUrl url) 
    {
        System.out.println("Url changed : " + url); 
    }
}

继承自QWebView的类:

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. 
        // Clears the previous web view rendering and here is the problem 
        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); 
    }
}

提前谢谢你。 :)

1 个答案:

答案 0 :(得分:1)

我终于找到了解决方案。这很简单。 ^^'

我从WebBrowserTestFrame类中删除了将Web视图背景设置为透明的代码,并将其放在WebBrowserTestQWebView类的paintEvent方法中。 像这样:

    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); 
    }
}

它对我有用! :d

Here is finally the expected rendering

相关问题