2014-03-22 4 views
5

Как можно обслуживать ресурс (такие файлы, как html, css, js, fonts) для настольного приложения для QWebView (в PyQT5)?Сервисный ресурс для QWebView PyQT5

Что я хочу:

  1. Если возможно обращение запрошенного ресурса по Webkit двигателя PyQT5 с пользовательской схемой, как говорит custom://app/jquery.js и возвращая файл.
  2. Если возможно, обработка стандартных HTTP-глаголов (GET, POST, ...) для этого пользовательская схема.

Если эти 2 не представляется возможным (по крайней мере, не представляется возможным в чистом вещий образом):

  • Как я могу перехватить запросы, поступающие от встроенного Webkit и обеспечивают ресурс (HTML, CSS, JS) на основе шаблона в URL-адресе (например, некоторое регулярное выражение (?<controller>[^/])/(?<action>[^/]))?

ответ

7

Вам необходимо создать свой собственный подкласс QNetworkAccessManager, который возвращает настраиваемый QNetworkReply для нужного протокола, а затем задает это как диспетчер сетевого доступа для вас страницы QWebView.

This article показывает хороший пример того, как это можно сделать - применительно к PyQt5, это то, как это может выглядеть:

from PyQt5.QtCore import QUrl, QTimer, QIODevice 
from PyQt5.QtWidgets import QApplication 
from PyQt5.QtNetwork import (QNetworkAccessManager, 
          QNetworkReply, 
          QNetworkRequest) 
from PyQt5.QtWebKitWidgets import QWebView 

import sys 

class ExampleNetworkAccessManager(QNetworkAccessManager): 

    def __init__(self, parent=None): 
     super().__init__(parent=parent) 

    def createRequest(self, operation, request, device): 
     if request.url().scheme() == 'example': 
      return ExampleReply(self, operation, request, device) 
     return super().createRequest(operation, request, device) 


class ExampleReply(QNetworkReply): 

    def __init__(self, parent, operation, request, device): 
     super().__init__(parent=parent) 
     self.setRequest(request) 
     self.setOperation(operation) 
     self.setUrl(request.url()) 
     self.bytes_read = 0 
     self.content = b'' 

     # give webkit time to connect to the finished and readyRead signals 
     QTimer.singleShot(200, self.load_content) 

    def load_content(self): 
     if self.operation() == QNetworkAccessManager.PostOperation: 
      # handle operations ... 
      pass 
     # some dummy content for this example 
     self.content = b'''<html> 
      <h1>hello world!</h1> 
      <p>...</p> 
      </html>''' 
     self.open(QIODevice.ReadOnly | QIODevice.Unbuffered) 
     self.setHeader(QNetworkRequest.ContentLengthHeader, len(self.content)) 
     self.setHeader(QNetworkRequest.ContentTypeHeader, "text/html") 
     self.readyRead.emit() 
     self.finished.emit() 

    def abort(self): 
     pass 

    def isSequential(self): 
     return True 

    def bytesAvailable(self): 
     ba = len(self.content) - self.bytes_read + super().bytesAvailable() 
     return ba 

    def readData(self, size): 
     if self.bytes_read >= len(self.content): 
      return None 
     data = self.content[self.bytes_read:self.bytes_read + size] 
     self.bytes_read += len(data) 
     return data 

    def manager(self): 
     return self.parent() 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    wv = QWebView() 
    enam = ExampleNetworkAccessManager() 
    wv.page().setNetworkAccessManager(enam) 
    wv.show() 
    wv.setUrl(QUrl("example://test.html")) 
    app.exec() 

 Смежные вопросы

  • Нет связанных вопросов^_^