2016-12-20 10 views
1

У меня очень постоянная проблема с QTJambi и Webkit.QTJambi и Webkit, проблемы с прозрачным фоном

Вот что я хочу сделать.

Я хочу загрузить веб-интерфейс, закодированный в HTML-файле (он работает), установить некоторые взаимодействия между Javascript и Java (он тоже работает), отобразить веб-интерфейс с прозрачным фоном над другим виджетами, который отображает изображения (2D игровой пейзаж), и он работает слишком долго, пока веб-интерфейс статичен.

Проблемы возникают при изменении веб-интерфейса (манипуляции DOM и css). Когда он изменяется, предыдущий рендеринг веб-представления не очищается, и новый рендеринг окрашивается. Итак, у меня есть такой рендеринг:

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

Я, наконец, нашел решение самостоятельно. Это было очень просто. ^^ '

Я удалил код, который задал фон веб-представления прозрачным из класса WebBrowserTestFrame и поместил его в метод paintEvent класса WebBrowserTestQWebView. Как это:

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