WebKit w PyQt - renderowanie stron www
Wydanie Qt 4.4 przyniosło integrację silnika renderowania stron www - WebKit. Z silnika można korzystać zarówno w samym Qt, czy w API dostępnych dla innych języków, w tym PyQt4. W przypadku Linuksa i pokrewnych systemów należy upewnić się czy posiadamy zainstalowany pakiet qt-webkit (jeżeli Qt jest rozbijana na oddzielne moduły). W Qt Designer powinniśmy widzieć widżet "QWebView" w zakładce "Display Widgets".
Najprostszy przykład wykorzystania widgeta QWebView do wyświetlenia podanej strony wyglądałby tak:
#!/usr/bin/env python
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
app = QApplication(sys.argv)
web = QWebView()
web.load(QUrl("http://google.pl"))
web.show()
sys.exit(app.exec_())

Funkcjonalność jak na razie niewielka, lecz moduł WebKit dostarcza kilka rozbudowanych klas. Załadowana strona www staje się obiektem QWebPage, a obiekt ten ma własną historię URLi - QWebHistory. Do tego klasa QWebView może wysyłać różne sygnały - jak stan ładowania strony, kliknięcie na link znajdujący się na stronie www, czy też wiele innych możliwości.
Zajmiemy się teraz stworzeniem bardziej rozbudowanej przeglądarki internetowej. Zaczniemy od stworzenia interfejsu w QtDesignerze - składającego się z przycisków: wstecz, dalej, zatrzymaj, odśwież, paska na adres oraz oczywiście widżeta QtWebView. Oto jak mógłby wyglądać (zapisałem pod nazwą httpWidget.ui):
- Połączyć sygnały z odpowiednimi slotami
- Sygnały pochodzące z QWebView (stan ładowania strony, tytuł strony itp.)
- Sygnały pochodzące z przycisków i wpływające na zachowanie QWebView (zatrzymanie ładowania strony, historia, podanie URLa)
- Ustawić wygląd interfejsu
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from httpWidget import Ui_HttpWidget
class httpWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(httpWidget, self).__init__(parent)
self.ui = Ui_HttpWidget()
self.ui.setupUi(self)
# set margins
l = self.layout()
l.setMargin(0)
self.ui.horizontalLayout.setMargin(5)
# set the default page
url = 'http://google.pl'
self.ui.url.setText(url)
# load page
self.ui.webView.setUrl(QtCore.QUrl(url))
# history buttons:
self.ui.back.setEnabled(False)
self.ui.next.setEnabled(False)
QtCore.QObject.connect(self.ui.back,QtCore.SIGNAL("clicked()"), self.back)
QtCore.QObject.connect(self.ui.next,QtCore.SIGNAL("clicked()"), self.next)
QtCore.QObject.connect(self.ui.url,QtCore.SIGNAL("returnPressed()"), self.url_changed)
QtCore.QObject.connect(self.ui.webView,QtCore.SIGNAL("linkClicked (const QUrl&)"), self.link_clicked)
QtCore.QObject.connect(self.ui.webView,QtCore.SIGNAL("urlChanged (const QUrl&)"), self.link_clicked)
QtCore.QObject.connect(self.ui.webView,QtCore.SIGNAL("loadProgress (int)"), self.load_progress)
QtCore.QObject.connect(self.ui.webView,QtCore.SIGNAL("titleChanged (const QString&)"), self.title_changed)
QtCore.QObject.connect(self.ui.reload,QtCore.SIGNAL("clicked()"), self.reload_page)
QtCore.QObject.connect(self.ui.stop,QtCore.SIGNAL("clicked()"), self.stop_page)
QtCore.QMetaObject.connectSlotsByName(self)
def url_changed(self):
"""
Url have been changed by user
"""
page = self.ui.webView.page()
history = page.history()
if history.canGoBack():
self.ui.back.setEnabled(True)
else:
self.ui.back.setEnabled(False)
if history.canGoForward():
self.ui.next.setEnabled(True)
else:
self.ui.next.setEnabled(False)
url = self.ui.url.text()
self.ui.webView.setUrl(QtCore.QUrl(url))
def stop_page(self):
"""
Stop loading the page
"""
self.ui.webView.stop()
def title_changed(self, title):
"""
Web page title changed - change the tab name
"""
self.setWindowTitle(title)
def reload_page(self):
"""
Reload the web page
"""
self.ui.webView.setUrl(QtCore.QUrl(self.ui.url.text()))
def link_clicked(self, url):
"""
Update the URL if a link on a web page is clicked
"""
page = self.ui.webView.page()
history = page.history()
if history.canGoBack():
self.ui.back.setEnabled(True)
else:
self.ui.back.setEnabled(False)
if history.canGoForward():
self.ui.next.setEnabled(True)
else:
self.ui.next.setEnabled(False)
self.ui.url.setText(url.toString())
def load_progress(self, load):
"""
Page load progress
"""
if load == 100:
self.ui.stop.setEnabled(False)
else:
self.ui.stop.setEnabled(True)
def back(self):
"""
Back button clicked, go one page back
"""
page = self.ui.webView.page()
history = page.history()
history.back()
if history.canGoBack():
self.ui.back.setEnabled(True)
else:
self.ui.back.setEnabled(False)
def next(self):
"""
Next button clicked, go to next page
"""
page = self.ui.webView.page()
history = page.history()
history.forward()
if history.canGoForward():
self.ui.next.setEnabled(True)
else:
self.ui.next.setEnabled(False)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = httpWidget()
myapp.show()
sys.exit(app.exec_())

- url_changed - użytkownik zmienił URL w QLineEdit, pobieramy go i próbujemy utworzyć podaną stronę (przydałoby się sprawdzanie poprawności, dodawanie http itp.)
- stop_page - kliknięto przycisk stop - kończymy ładowanie strony
- title_changed - QWebView wysyła tytuł załadowanej strony, gdy ją pobierze - wykorzystujemy by ustawić tytuł okna aplikacji
- reload_page - kliknięto przycisk odświeżenia - ponownie ładujemy stronę
- link_clicked - użytkownik kliknął w link na załadowanej stronie. Aktualizujemy URL w QLineEdit
- load_progress - obserwujemy postęp ładowania strony i wyłączamy przycisk stop po zakończeniu pobierania strony
- back - kliknięto przycisk wstecz - ładujemy poprzedni URL
- next - kliknięto przycisk dalej - ładujemy następny URL z historii przeglądania
Comment article