Outils pour utilisateurs

Outils du site


pyqt4_navigateur_web

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

pyqt4_navigateur_web [2013/09/13 10:55] (Version actuelle)
tyrtamos créée
Ligne 1: Ligne 1:
 +
 +
 +En construction!
 +
 +
 +<code python>
 +#​!/​usr/​bin/​python
 +# -*- coding: utf-8 -*-
 +from __future__ import division
 +#Python 2.7
 +
 +__logiciel__ = u"​navigweb"​
 +__version__ = u"​1.0.0"​
 +__date__ = u"​8/​10/​2012"​
 +
 +import os, sys
 +from functools import partial
 +
 +from PyQt4 import QtCore, QtGui, QtNetwork, QtWebKit
 +from apropos import Apropos
 +
 +#############################################################################​
 +class Navigateurweb(QtGui.QMainWindow):​
 +    """​navigateur web: affichage des pages web et des fichiers html disque"""​
 + 
 +    # =======================================================================
 +    def __init__(self,​ url=None, repdefaut=u"",​ imprimepdf=None,​ parent=None):​
 +        """​initialisation du navigateur"""​
 +        super(Navigateurweb,​ self).__init__(parent)
 + 
 +        # met le titre de la fenêtre
 +        self.setWindowTitle(u"​Navigateur web")
 +        # affiche l'​icone de la fenêtre s'il n'y en pas déjà une par défaut
 +        if self.windowIcon().isNull():​
 +            # mettre ici l'​icone si elle n'est pas donnée par l'​appelant
 +            #​self.setWindowIcon(QtGui.QIcon(u"​navigweb.png"​))
 +            pass
 +        # stocke la page '​home'​ en la corrigeant si nécessaire
 +        self.urlblank = QtCore.QUrl(u"​about:​blank"​)
 +        if url==None:
 +            self.urlhome = self.urlblank
 +        else:
 +            self.urlhome = self.corrigeurl(url)
 +        ​
 +        # fichier pdf dans lequel l'​impression demandée se fera
 +        if imprimepdf==None:​
 +            home = os.path.expanduser("​~"​).decode('​latin1'​)
 +            fichier = u"​imprimer_3FBH2XO1P8.pdf"​
 +            self.imprimepdf = os.path.join(home,​ fichier)
 +        else:
 +            self.imprimepdf = os.path.abspath(os.path.expanduser(imprimepdf))
 +        ​
 +        # répertoire par défaut dans lequel on va chercher les fichiers html
 +        self.repdefaut = os.path.abspath(os.path.expanduser(repdefaut))
 +        ​
 +        ​
 +        # fabrique le menu principal de la fenêtre
 +        menubar = self.menuBar()
 +        fileMenu = menubar.addMenu('​Fichier'​)
 +        ​
 +        ouvrirAction = QtGui.QAction('&​Ouvrir',​ self)
 +        ouvrirAction.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_O)
 +        ouvrirAction.setStatusTip(u"​Ouvrir un fichier html")
 +        ouvrirAction.triggered.connect(self.ouvrir_m)
 +        fileMenu.addAction(ouvrirAction)
 +        ​
 +        imprimerAction = QtGui.QAction('&​Imprimer',​ self)
 +        imprimerAction.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_I)
 +        imprimerAction.setStatusTip(u"​Imprimer dans un fichier pdf")
 +        imprimerAction.triggered.connect(self.imprimer_m)
 +        fileMenu.addAction(imprimerAction)
 +        ​
 +        fileMenu.addSeparator()
 +        ​
 +        quitterAction = QtGui.QAction('&​Quitter',​ self)        ​
 +        quitterAction.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_Q) ​       ​
 +        quitterAction.setStatusTip(u"​Quitter le programme"​)
 +        quitterAction.triggered.connect(lambda : self.close())
 +        fileMenu.addAction(quitterAction)
 +
 +        aideMenu = menubar.addMenu('​Aide'​)
 +        ​
 +        aproposAction = QtGui.QAction('&​A propos',​ self)        ​
 +        aproposAction.setStatusTip(u"​A propos du programme"​)
 +        aproposAction.triggered.connect(self.apropos_m)
 +        aideMenu.addAction(aproposAction)
 +        ​
 +        # crée le QWebView pour affichage des pages html
 +        self.vuehtml = QtWebKit.QWebView()
 +        ​
 +        # configure viewhtml (interdire '​JavaEnabled'​ => plante le programme!))
 +        reglage = self.vuehtml.settings() ​
 +        # activer javascript
 +        reglage.setAttribute(QtWebKit.QWebSettings.JavascriptEnabled,​ True)
 +        reglage.setAttribute(QtWebKit.QWebSettings.JavascriptCanOpenWindows,​ True)
 +        reglage.setAttribute(QtWebKit.QWebSettings.JavascriptCanAccessClipboard,​ True)
 +
 +        # activer les plugins
 +        reglage.setAttribute(QtWebKit.QWebSettings.PluginsEnabled,​ True)
 +
 +        # fait que les couleurs et motifs de fond de page ne seront pas imprimés
 +        reglage.setAttribute(QtWebKit.QWebSettings.PrintElementBackgrounds,​ False)
 +
 +        # connecte les évènements du QWebView avec les méthodes
 +        self.vuehtml.loadProgress.connect(self.loadProgress_m)
 +        self.vuehtml.loadFinished.connect(self.loadFinished_m)
 +        self.vuehtml.linkClicked.connect(self.linkClicked_m)
 +        self.vuehtml.urlChanged.connect(self.urlChanged_m)
 +        ​
 +        # crée la ligne de saisie des adresses des pages html (web ou disque)
 +        self.adresse = QtGui.QLineEdit()
 +        self.adresse.setSizePolicy(QtGui.QSizePolicy.Expanding,​
 +                                   ​self.adresse.sizePolicy().verticalPolicy())
 +        self.adresse.returnPressed.connect(self.returnPressed_m)
 +        ​
 +        # initialise la barre d'​outils (pré-existe dans le QMainWindoww)
 +        self.toolBar = self.addToolBar("​Navigation"​)
 +        self.toolBar.addAction(self.vuehtml.pageAction(QtWebKit.QWebPage.Back))
 +        self.toolBar.addAction(self.vuehtml.pageAction(QtWebKit.QWebPage.Forward))
 +        self.toolBar.addAction(self.vuehtml.pageAction(QtWebKit.QWebPage.Reload))
 +        self.toolBar.addAction(self.vuehtml.pageAction(QtWebKit.QWebPage.Stop))
 +        self.toolBar.addWidget(self.adresse)
 +
 +        # initialisation de la barre de status (affiche le nom de page html)
 +        self.statusBar().showMessage(u''​)
 +        ​
 +        # positionne le QWebView dans la partie centrale de la fenêtre
 +        self.setCentralWidget(QtGui.QFrame())
 +        posit = QtGui.QGridLayout()
 +        posit.addWidget(self.vuehtml,​ 0, 0)
 +        self.centralWidget().setLayout(posit)
 +        ​
 +        # permet les liens hypertexte
 +        self.vuehtml.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateAllLinks)
 +        ​
 +        # met en place un nouveau menu popup du QWebView
 +        self.vuehtml.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
 +        self.vuehtml.customContextMenuRequested.connect(self.popupmenuvuehtml) ​       ​
 +        ​
 +        # met en place un nouveau menu popup pour la barre d'​outils
 +        self.toolBar.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
 +        self.toolBar.customContextMenuRequested.connect(self.popupmenutoolbar) ​       ​
 +        ​
 +        # active la capacité de charger des pages https://
 +        # certif: https://​certs.starfieldtech.com/​anonymous/​repository.seam
 +        config = QtNetwork.QSslConfiguration.defaultConfiguration()
 +        certs=config.caCertificates()
 +        certs.append(QtNetwork.QSslCertificate(QtCore.QFile("​starfieldcert"​)))
 +        config.setCaCertificates(certs)
 +        ​
 +        # charge la page demandée au lancement
 +        self.adresse.setText(self.urlhome.toString())
 +        self.returnPressed_m()
 +
 +        # met le focus sur la page affichée
 +        self.vuehtml.setFocus()
 +        ​
 +    # =======================================================================
 +    def ouvrir_m(self):​
 +        """​Sélectionner et charger un fichier html du disque"""​
 +        ​
 +        fichier = QtGui.QFileDialog.getOpenFileName(self, ​
 +                     ​u"​Sélectionnez le fichier html", ​
 +                     ​self.repdefaut, ​
 +                     ​u"​Fichier html (*.html;​*.htm);;​Tous (*.*)"​)
 +        fichier = unicode(fichier)
 +
 +        if fichier==u"":​
 +            return
 +
 +        # charge la page demandée au lancement
 +        self.adresse.setText(fichier)
 +        self.returnPressed_m()
 +        ​
 +    # =======================================================================
 +    def bidon(self):​
 +        pass
 +    ​
 +    # =======================================================================
 +    def popupmenutoolbar(self,​ position):
 +        """​menu popup de la barre d'​outils:​ remplace celui d'​origine"""​
 +        ​
 +        # récupération de la liste des pages de l'​historique
 +        history = self.vuehtml.page().history()
 +        hitems = []
 +        for hitem in history.items():​
 +            hitems.append(hitem)
 +        ihitem =  history.currentItemIndex()
 +        i1 = max(ihitem-10,​ 0)
 +        i2 = min(ihitem+10,​ len(hitems)-1)
 +        ​
 +        # création de l'​objet "menu popup"
 +        popupmenu = QtGui.QMenu(self.toolBar)
 +        ​
 +        # retour à la page '​home'​
 +        actionHome = popupmenu.addAction(u"​Retour à la page Home")
 +        actionHome.triggered.connect(self.home_m)
 +
 +        # ajout d'un séparateur des items du menu
 +        popupmenu.addSeparator()
 +        ​
 +        # création des items à ajouter au menu
 +        actions = []
 +        for i in xrange(i1, i2+1):
 +            hitem = hitems[i]
 +            url = unicode(hitem.url().toString())
 +            if len(url)>​70:​
 +                # l'​adresse est trop longue: on ne prend que le début et la fin
 +                url = url[:33] + u"​...."​ + url[-33:]
 +
 +            # créaction d'une action
 +            act = QtGui.QAction(url,​ self)
 +            # mettre en gras l'​adresse de la page déjà affichée
 +            if i==ihitem: ​
 +                police = act.font()
 +                police.setBold(True)
 +                act.setFont(police)
 +            # connecter l'item avec la méthode à exécuter
 +            act.triggered.connect(partial(self.allera,​ hitem))
 +            ​
 +            # on ajoute l'​action au menu
 +            action = popupmenu.addAction(act)
 +            actions.append(action)
 +
 +        # exécution du menu popup
 +        popupmenu.exec_(self.toolBar.mapToGlobal(position))
 +        ​
 +    # =======================================================================
 +    def allera(self,​ hitem):
 +        """​affiche la page '​hitem'​ de l'​historique"""​
 +        self.vuehtml.page().history().goToItem(hitem)
 +        ​
 +    # =======================================================================
 +    def popupmenuvuehtml(self,​ position):
 +        """​menu popup spécifique au QWebView: remplace celui d'​origine"""​
 +        ​
 +        # crée l'​objet "menu popup"
 +        popupmenu = QtGui.QMenu(self.vuehtml)
 +        ​
 +        # fait un "zoom plus" avec Alt-P
 +        actionZPlus = popupmenu.addAction(u"​Zoom &​Plus"​)
 +        actionZPlus.setShortcut(QtGui.QKeySequence(QtCore.Qt.AltModifier | QtCore.Qt.Key_P))
 +        actionZPlus.triggered.connect(partial(self.zoom,​ +0.1))
 +
 +        # fait un "zoom moins" avec Alt-M
 +        actionZMoins = popupmenu.addAction(u"​Zoom &​Moins"​)
 +        actionZMoins.setShortcut(QtGui.QKeySequence(QtCore.Qt.AltModifier | QtCore.Qt.Key_M))
 +        actionZMoins.triggered.connect(partial(self.zoom,​ -0.1))
 +        ​
 +        # ajout d'un séparateur des items du menu
 +        popupmenu.addSeparator()
 +        ​
 +        # lance et affiche une impression en pdf avec Alt-I
 +        actionZMoins = popupmenu.addAction(u"&​Imprimer"​)
 +        actionZMoins.setShortcut(QtGui.QKeySequence(QtCore.Qt.AltModifier | QtCore.Qt.Key_I))
 +        actionZMoins.triggered.connect(self.imprimer_m)
 +        ​
 +        # exécute le menu popup
 +        popupmenu.exec_(self.vuehtml.mapToGlobal(position))
 +
 +    # =======================================================================
 +    def corrigeurl(self,​ url):
 +        """​corrige l'​adresse url (unicode) pour obtenir une adresse viable
 +           si adresse disque: l'​adresse doit être absolue
 +           si adresse web: l'​adresse peut être incomplète
 +        """​
 +        # comme "​ftp:"​ ne marche pas => remplacer par "​http:"​
 +        if url[:​4]==u"​ftp:":​
 +            url = u"​http:"​ + url[4:]
 +        ​
 +        if os.path.exists(url):​
 +            # cas d'un fichier disque html:  met "​file://"​ si nécessaire
 +            return QtCore.QUrl.fromLocalFile(url)
 +        ​
 +        # cas d'une adresse web:  met "​http://"​ si nécessaire
 +        return QtCore.QUrl.fromUserInput(url)
 +    ​
 +    # =======================================================================
 +    def home_m(self):​
 +        """​affiche la page '​home'​ comme nouvelle page html"""​
 +        self.vuehtml.setUrl(self.urlhome) #​load(self.urlhome)
 +        self.vuehtml.setFocus()
 +    ​
 +    # =======================================================================
 +    def returnPressed_m(self):​
 +        """​affiche la page correspondant à la ligne d'​adresse"""​
 +
 +        # compléte si nécessaire l'url de la ligne d'​adresse
 +        url = unicode(self.adresse.text()).strip()
 +        if url==u"":​
 +            url = self.urlblank # => "​about:​blank"​
 +        else:
 +            url = self.corrigeurl(url)
 +
 +        # affiche la page html demandée
 +        self.vuehtml.setUrl(url) #load(url)
 +        self.vuehtml.setFocus()
 + 
 +    # =======================================================================
 +    def loadProgress_m(self,​ progression):​
 +        """​progression du chargement: affiche le nom de page dans la fenêtre"""​
 +        nompage = self.vuehtml.title()
 +        msg = "%s (%s %%)" % (nompage, progression)
 +        #​self.setWindowTitle("​%s (%s %%)" % (nompage, progression))
 +        self.statusBar().showMessage(msg)
 +
 +    # =======================================================================
 +    def loadFinished_m(self,​ ok):
 +        """​fin de chargement: affiche le nom de page dans la fenêtre"""​
 +        nompage = self.vuehtml.title()
 +        if not ok:
 +           ​nompage = nompage + u" (erreur page)" ​
 +        #​self.setWindowTitle(nompage)
 +        self.statusBar().showMessage(nompage) ​   ​
 +    ​
 +    # =======================================================================
 +    def linkClicked_m(self,​ url):
 +        """​charge la page correspondant à l'url du lien hypertexte cliqué"""​
 +        self.vuehtml.setUrl(url) #load(url)
 +        self.vuehtml.setFocus()
 +
 +    # =======================================================================
 +    def urlChanged_m(self,​ url):
 +        """​met à jour la ligne d'​addresse à chaque changement d'​url"""​
 +        self.adresse.setText(url.toString())
 +        ​
 +    #​========================================================================
 +    def imprimer_m(self):​
 +        """​Imprimer le contenu de la page affichée"""​
 +        ​
 +        # créer et configurer l'​objet printer pour imprimer
 +        printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
 +        dest = self.imprimepdf
 +        printer.setOutputFileName(dest)
 +        printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
 +        printer.setCreator(u"​aidehtml.py"​)
 +        printer.setDocName(u"​aidehtml"​)
 +        printer.setPageSize(QtGui.QPrinter.A4)
 +        printer.setOrientation(QtGui.QPrinter.Portrait) #​QtGui.QPrinter.Landscape
 +        #ordre des valeurs float des marges: left, top, right, bottom
 +        printer.setPageMargins(20.0,​ 10.0, 10.0, 10.0, QtGui.QPrinter.Millimeter)
 +        #​printer.setFullPage(True) # NB: neutralise les marges!
 +        printer.setColorMode(QtGui.QPrinter.Color)
 +        ​
 +        # imprimer la page affichée
 +        self.vuehtml.print_(printer)
 +        ​
 +        # afficher le fichier pdf avec le visualiseur pdf par défaut
 +        if os.path.exists(dest):​
 +            try:
 +                # solution pour Windows
 +                os.startfile(dest)
 +            except:
 +                # solution pour les Linux récents
 +                os.system('​xdg-open ' + dest)
 +
 +    # =======================================================================
 +    def zoom(self, increment):
 +        """​applique un zoom + ou - selon l'​incrément passé en argument"""​
 +        current = self.vuehtml.textSizeMultiplier()
 +        self.vuehtml.setTextSizeMultiplier(current + increment)
 +    ​
 +    # =======================================================================
 +    def keyPressEvent(self,​ event):
 +        """​raccourcis clavier: zoom+ =Alt-P, zoom- =Alt-M, impression =Alt-I"""​
 +        if self.vuehtml.hasFocus():​
 +            # avec Alt-P => zoom+
 +            if event.key() == QtCore.Qt.Key_P and \
 +                                   ​(event.modifiers() & QtCore.Qt.AltModifier):​
 +                self.zoom(0.1)
 +                event.accept()
 +            # avec Alt-M => zoom-
 +            elif event.key() == QtCore.Qt.Key_M and \
 +                                   ​(event.modifiers() & QtCore.Qt.AltModifier):​
 +                self.zoom(-0.1)
 +                event.accept()
 +            # avec Alt-I => Imprime la page affichée
 +            elif event.key() == QtCore.Qt.Key_I and \
 +                                   ​(event.modifiers() & QtCore.Qt.AltModifier):​
 +                self.imprimer_m()
 +                event.accept()
 +            else:
 +                event.ignore()
 +        else:
 +            event.ignore()
 +                    ​
 +    #​========================================================================
 +    @QtCore.pyqtSlot()
 +    def apropos_m(self):​
 +        """​Fenêtre 'à propos'​ """​
 +        pass
 +
 +#############################################################################​
 +if __name__ == '​__main__':​
 +    # code non exécuté si appel en tant que module
 +
 +    app = QtGui.QApplication(sys.argv)
 +
 +    if len(sys.argv) > 1:
 +        url = sys.argv[1]
 +    else:
 +        url = None
 +
 +    url = "​http://​www.google.fr"​
 +    ​
 +    fen = Navigateurweb(url)
 +    fen.show()
 +    sys.exit(app.exec_())
 +</​code>​
 +
  
pyqt4_navigateur_web.txt · Dernière modification: 2013/09/13 10:55 par tyrtamos