IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

Utilisation de QtWebKit avec PyQt4 : fancybrowser.py [QtWebKit]


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 696
    Par défaut Utilisation de QtWebKit avec PyQt4 : fancybrowser.py
    Enjoy!
    Il existe déjà pas mal de démos PyQt4 utilisant le QtWebKit mais je n'en ai pas trouvé aussi complète que le fancy browser. Le code joint en est une traduction assez fidèle.
    J'ai juste pris quelques libertés avec le chargement de JQuery et raccourci un peu les appels à javascript.
    - W


    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    from PyQt4.QtWebKit import QWebView, QWebPage
    from PyQt4.QtCore import QUrl, QObject, SIGNAL
    from PyQt4.QtGui import QApplication, QMainWindow, QLineEdit, QSizePolicy, \
                            QAction, QStyle
     
     
    def url_fetch(url, path):
        from urllib import urlretrieve
     
        name = os.path.basename(url)
        fullname = "%(path)s/%(name)s" % vars()
        if not os.path.exists(fullname):
            urlretrieve(url, fullname)
        with open(fullname, 'r') as f:
            buffer = f.read()
        return buffer
     
     
    class Browser(QMainWindow):
     
        def __init__(self, url, jquery):
            super(Browser, self).__init__()
     
            self._progress = 0
     
            self._jquery = jquery
            self._js_loaded = False
            connect = self.connect
     
            # create WebView
            view = self._view = QWebView()
            view.load(QUrl(url))
            connect(view, SIGNAL("loadFinished (bool)"), self._adjustLocation)
            connect(view,SIGNAL("titleChanged(const QString&)"), self._adjustTitle);
            connect(view,SIGNAL("loadProgress(int)"), self._setProgress);
            connect(view,SIGNAL("loadFinished(bool)"), self._finishLoading);
            # setup location editable line
            locationEdit = self._locationEdit = QLineEdit()
            locationEdit.setSizePolicy(QSizePolicy.Expanding,
                locationEdit.sizePolicy().verticalPolicy())
            connect(locationEdit, SIGNAL("returnPressed()"), self._changeLocation)
            # setup toolbar
            toolBar = self._toolBar = self.addToolBar("Navigation")
            actions = map(view.pageAction, [ QWebPage.Back, QWebPage.Forward,
                        QWebPage.Reload, QWebPage.Stop])
            toolBar.addActions(actions)
            toolBar.addWidget(locationEdit)
            # setup effects menu
            effectMenu = self._effectMenu = self.menuBar().addMenu("&Effect")
            code = r"""
                $('a').each( function () {
                    $(this).css('background-color', 'yellow') } )
                """
            effectMenu.addAction("Highlight all links", lambda: self._eval_js(code))
            rotateAction = self._rotateAction = QAction(self)
            rotateAction.setIcon(self.style().standardIcon(QStyle.SP_FileDialogDetailedView))
            rotateAction.setCheckable(True)
            rotateAction.setText("Turn images upside down")
            connect(rotateAction, SIGNAL("toggled(bool)"), self._rotateImages)
            effectMenu.addAction(rotateAction)
            # setup tools menu
            toolsMenu = self._toolsMenu = self.menuBar().addMenu("&Tools")
            toolsMenu.addAction("Remove all GIF images",
                    lambda: self._eval_js(r"$('[src*=gif]').remove()"))
            toolsMenu.addAction("Remove all inline frames",
                    lambda: self._eval_js( r"$('iframe').remove()"))
            toolsMenu.addAction("Remove all object elements",
                    lambda: self._eval_js(r"$('object').remove()"))
            toolsMenu.addAction("Remove all embedded elements",
                    lambda: self._eval_js(r"$('embed').remove()"))
            # set everything together
            self.setCentralWidget(view);
            # grabs frame
            self._frame = view.page().mainFrame()
     
        def _adjustLocation(self): 
            self._locationEdit.setText(self._view.url().toString());
     
        def _changeLocation(self):
            url = QUrl(self._locationEdit.text())
            view = self._view
            view.load(url)
            view.setFocus()
     
        def _adjustTitle(self): 
            view = self._view
            progress = self._progress
            if progress <= 0 or progress >= 100:
                self.setWindowTitle(view.title())
            else: self.setWindowTitle("%s (%s %%)" % (view.title(), progress))
     
        def _setProgress(self, p):
            self._progress = p
            self._adjustTitle()
     
        def _finishLoading(self, bool):
            self._progress = 100
            self._adjustTitle()
            self._js_loaded = False
     
        def _rotateImages(self, toggle):
            code = r"""$('img').each( function () {
                    $(this).css('-webkit-transition', '-webkit-transform 2s') } )"""
            self._eval_js(code)
            if (toggle):
                code = r"""$('img').each( function () {
                        $(this).css('-webkit-transform', 'rotate(180deg)') } )"""
            else:
                code = r"""$('img').each( function () {
                        $(this).css('-webkit-transform', 'rotate(0deg)') } )"""
            self._eval_js(code)
     
        def _eval_js(self, js_code):
            js_eval = self._frame.evaluateJavaScript
            if not self._js_loaded: 
                 js_eval(self._jquery)
                 self._js_loaded = True
            js_eval(js_code)
     
    if __name__ == '__main__':
        import sys
        import os
     
        URL = 'http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js'
        PATH = os.getcwd()
        jquery = url_fetch(URL, PATH)
     
        app = QApplication(sys.argv)
        Browser('http://www.google.com/ncr', jquery).show()
        sys.exit(app.exec_())
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  2. #2
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Merci pour ce cadeau.

    Je mettrais dans la journée un exemple tout bête montrant comment communiquer avec JS depuis PyQt.

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 696
    Par défaut
    Chouette.
    En fait ici, on se contente d'appeler des "procédures" au sens ou on appelle des fonctions JS sans récupérer d'infos.
    Ah.... Pour info, j'ai lu sur le ouèbe que certains développeurs de pyjamas trouvaient le webkit plutôt sympa pour réaliser la cohérence entre client-side et server-side.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Comme promis voici un code trouvé sur le net qui montre comment, dans un cas simple, agir depuis JavaScript sur une méthode Python.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #! /usr/bin/env python3
     
    # Source :
    #    http://pysnippet.blogspot.com/2010/01/calling-python-from-javascript-in-pyqts.html
     
    import sys
    from PyQt4 import QtCore, QtGui, QtWebKit
     
    """Html snippet."""
    html = """
    <html><body>
      <center>
      <script language="JavaScript">
        document.write('<p>Python ' + pyObj.pyVersion + '</p>')
      </script>
      <button onClick="pyObj.showMessage('COOOL')">Press me</button>
      </center>
    </body></html>
    """
     
    class StupidClass(QtCore.QObject):
        """Simple class with one slot and one read-only property."""
     
        @QtCore.pyqtSlot(str)
        def showMessage(self, msg):
            """Open a message box and display the specified message."""
            QtGui.QMessageBox.information(None, "Info", msg)
     
        def _pyVersion(self):
            """Return the Python version."""
            return sys.version
     
        """Python interpreter version property."""
        pyVersion = QtCore.pyqtProperty(str, fget=_pyVersion)
     
    def main():
        app = QtGui.QApplication(sys.argv)
     
        myObj = StupidClass()
     
        webView = QtWebKit.QWebView()
        # Make myObj exposed as JavaScript object named 'pyObj'
        webView.page().mainFrame().addToJavaScriptWindowObject("pyObj", myObj)
        webView.setHtml(html)
     
        window = QtGui.QMainWindow()
        window.setCentralWidget(webView)
        window.show()
     
        sys.exit(app.exec_())
     
    if __name__ == "__main__":
        main()
    A titre perso., je voudrais utiliser ce genre de choses pour utiliser une applet Java dans une page HTML, puis ensuite en récupérer des paramètres via JavaScript (communication entre l'applet et JS), et enfin utiliser cela dans Python.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 696
    Par défaut
    Ah ben merci car appeler du python depuis le JS qu'on colle dans la page était un cas de figure que j'avais "zappé".
    Mais l'exemple Python appelle JS retour de paramètre reste à faire.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Voici la version Python 3, fabriquée par 2to3, du code de wiztricks :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    #!/usr/bin/python3
     
    # Source :
    #    http://www.developpez.net/forums/d979176/autres-langages/python-zope/gui/pyqt/utilisation-qtwebkit-pyqt4-fancybrowser-py/#post5488866
     
    from PyQt4.QtWebKit import QWebView, QWebPage
    from PyQt4.QtCore import QUrl, QObject, SIGNAL
    from PyQt4.QtGui import QApplication, QMainWindow, QLineEdit, QSizePolicy, \
                            QAction, QStyle
     
     
    def url_fetch(url, path):
        from urllib.request import urlretrieve
     
        name = os.path.basename(url)
        fullname = "%(path)s/%(name)s" % vars()
        if not os.path.exists(fullname):
            urlretrieve(url, fullname)
        with open(fullname, 'r') as f:
            buffer = f.read()
        return buffer
     
     
    class Browser(QMainWindow):
     
        def __init__(self, url, jquery):
            super(Browser, self).__init__()
     
            self._progress = 0
     
            self._jquery = jquery
            self._js_loaded = False
            connect = self.connect
     
            # create WebView
            view = self._view = QWebView()
            view.load(QUrl(url))
            connect(view, SIGNAL("loadFinished (bool)"), self._adjustLocation)
            connect(view,SIGNAL("titleChanged(const QString&)"), self._adjustTitle);
            connect(view,SIGNAL("loadProgress(int)"), self._setProgress);
            connect(view,SIGNAL("loadFinished(bool)"), self._finishLoading);
            # setup location editable line
            locationEdit = self._locationEdit = QLineEdit()
            locationEdit.setSizePolicy(QSizePolicy.Expanding,
                locationEdit.sizePolicy().verticalPolicy())
            connect(locationEdit, SIGNAL("returnPressed()"), self._changeLocation)
            # setup toolbar
            toolBar = self._toolBar = self.addToolBar("Navigation")
            actions = list(map(view.pageAction, [ QWebPage.Back, QWebPage.Forward,
                        QWebPage.Reload, QWebPage.Stop]))
            toolBar.addActions(actions)
            toolBar.addWidget(locationEdit)
            # setup effects menu
            effectMenu = self._effectMenu = self.menuBar().addMenu("&Effect")
            code = r"""
                $('a').each( function () {
                    $(this).css('background-color', 'yellow') } )
                """
            effectMenu.addAction("Highlight all links", lambda: self._eval_js(code))
            rotateAction = self._rotateAction = QAction(self)
            rotateAction.setIcon(self.style().standardIcon(QStyle.SP_FileDialogDetailedView))
            rotateAction.setCheckable(True)
            rotateAction.setText("Turn images upside down")
            connect(rotateAction, SIGNAL("toggled(bool)"), self._rotateImages)
            effectMenu.addAction(rotateAction)
            # setup tools menu
            toolsMenu = self._toolsMenu = self.menuBar().addMenu("&Tools")
            toolsMenu.addAction("Remove all GIF images",
                    lambda: self._eval_js(r"$('[src*=gif]').remove()"))
            toolsMenu.addAction("Remove all inline frames",
                    lambda: self._eval_js( r"$('iframe').remove()"))
            toolsMenu.addAction("Remove all object elements",
                    lambda: self._eval_js(r"$('object').remove()"))
            toolsMenu.addAction("Remove all embedded elements",
                    lambda: self._eval_js(r"$('embed').remove()"))
            # set everything together
            self.setCentralWidget(view);
            # grabs frame
            self._frame = view.page().mainFrame()
     
        def _adjustLocation(self):
            self._locationEdit.setText(self._view.url().toString());
     
        def _changeLocation(self):
            url = QUrl(self._locationEdit.text())
            view = self._view
            view.load(url)
            view.setFocus()
     
        def _adjustTitle(self):
            view = self._view
            progress = self._progress
            if progress <= 0 or progress >= 100:
                self.setWindowTitle(view.title())
            else: self.setWindowTitle("%s (%s %%)" % (view.title(), progress))
     
        def _setProgress(self, p):
            self._progress = p
            self._adjustTitle()
     
        def _finishLoading(self, bool):
            self._progress = 100
            self._adjustTitle()
            self._js_loaded = False
     
        def _rotateImages(self, toggle):
            code = r"""$('img').each( function () {
                    $(this).css('-webkit-transition', '-webkit-transform 2s') } )"""
            self._eval_js(code)
            if (toggle):
                code = r"""$('img').each( function () {
                        $(this).css('-webkit-transform', 'rotate(180deg)') } )"""
            else:
                code = r"""$('img').each( function () {
                        $(this).css('-webkit-transform', 'rotate(0deg)') } )"""
            self._eval_js(code)
     
        def _eval_js(self, js_code):
            js_eval = self._frame.evaluateJavaScript
            if not self._js_loaded:
                 js_eval(self._jquery)
                 self._js_loaded = True
            js_eval(js_code)
     
    if __name__ == '__main__':
        import sys
        import os
     
        URL = 'http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js'
        PATH = os.getcwd()
        jquery = url_fetch(URL, PATH)
     
        app = QApplication(sys.argv)
        Browser('http://www.google.com/ncr', jquery).show()
        sys.exit(app.exec_())

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [QtWebKit] Utiliser QML et QtWebKit avec PySide
    Par dourouc05 dans le forum PyQt
    Réponses: 0
    Dernier message: 17/01/2011, 21h37
  2. utilisation de dll avec diverses compilateurs
    Par Thylia dans le forum C++
    Réponses: 30
    Dernier message: 21/10/2004, 16h30
  3. Utiliser Borland C++ avec Emacs sous Windows
    Par Eikichi dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 02/03/2003, 08h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo