RkBlog

Hardware, programming and astronomy tutorials and reviews.

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_())
Efekt b臋dzie np taki:
qtwebkit0

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):

qtwebkit

Tworzymy teraz odpowiadaj膮c膮 interfejsowi klas臋 Pythona:
pyuic4 httpWidget.ui > httpWidget.py
I mo偶emy przyst膮pi膰 do jego oprogramowania: Oto gotowy kod:
# -*- 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_())
Zapisz powy偶szy kod do pliku znajduj膮cego si臋 w tym samym katalogu co projekt interfejsu i uruchom (ja u偶y艂em run.py):
python run.py
Przyk艂adowy efekt to:
qtwebkit1
W konstruktorze podajemy adres startowej strony, a tak偶e m.in. zmniejszamy marginesy mi臋dzy poszczeg贸lnymi widgetami. Nast臋pnie definiujemy wszystkie sloty: Powy偶sza aplikacja posiada ju偶 bazow膮 funkcjonalno艣膰 i prosty dzia艂aj膮cy interfejs, lecz mo偶liwo艣ci klas qt-webkit s膮 znacznie wi臋ksze - ch臋tnym polecam odwiedzenie dokumentacji. Nale偶y te偶 zwr贸ci膰 uwag臋 偶e qt-webkit w Qt 4.4 nie obs艂uguje jeszcze wtyczek przegl膮darek. Funkcjonalno艣膰 ta zosta艂a dodana do Qt 4.5 (jak i kilka innych).

Kod 藕r贸d艂owy

Pobierz kod przegl膮darki zaprezentowanej w artykule.
RkBlog

PyQt, 6 December 2008, Piotr Mali艅ski

Comment article