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 :

Appeler du Python dans un lien hypertexte ? [QtGui]


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut Appeler du Python dans un lien hypertexte ?
    Bonjour,

    J'utilise souvent du texte html (que Qt appelle 'richtext') dans les QMessageBox. Cela permet les "embellissements" du texte (gras, couleur, ...), et aussi de présenter des adresses web dans des liens hypertexte: quand on clique dessus, cela appelle la page dans le navigateur par défaut de l'OS.

    Exemple d'application: dans une page 'à propos' (QMessageBox.about), cela permet de présenter le site web de référence pour le logiciel.

    Ma question: au lieu d'appeler une page web dans ce lien hypertexte, est-ce qu'on peut appeler une fonction Python, quitte à passer par du JavaScript?

    Merci d'avance!

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    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 738
    Par défaut
    Salut,
    Regardez la mécanique proposée dans la discussion
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour wiztricks, et merci: avec ce fil et d'autres pages du web, j'ai réussi!

    J'ai utilisé cela pour moderniser le modèle de fenêtre "A propos" que j'utilise pour mes logiciels. J'ai été obligé pour cela d'abandonner mon QMessageBox.about et d'utiliser un QtWebKit.QWebView, mais finalement, ça ouvre des perspectives plus intéressantes.

    Voilà ce que donne ma nouvelle fenêtre "A propos":



    Cette fenêtre affiche les infos sur le logiciel en question, et des infos sur le contexte d'exécution (OS et versions).

    Cliquer sur le lien hypertexte affiche la page web dans le navigateur par défaut de l'OS.

    Cliquer sur le bouton affiche la fenêtre de la licence Qt. On pourrait faire la même chose avec un lien hypertexte. Attention: il s'agit ici d'un bouton défini en html!

    Tout cela fonctionne en multiplateforme. J'ai vérifié sur : Windows 7, Linux (Mint 13 compatible Ubuntu 12.04) et Mac OS X (10.8 Montain Lion).

    Le principe d'appel de fonctions Python à partir du javascript est simple:

    1- on crée une classe (que j'ai appelée PythonObj dans le code ci-dessous) qui contiendra toutes les méthodes Python que javascript pourra appeler. Cette classe agit comme une "interface":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class PythonObj(QtCore.QObject):
     
        def __init__(self, parent=None):
            super(PythonObj, self).__init__(parent)
     
        @QtCore.pyqtSlot()
        def aproposdeqt(self):
            QtGui.qApp.aboutQt()
     
        @QtCore.pyqtSlot(str)
        def siteweb(self, site):
            webbrowser.open(site)
    2- on signale cette interface au QWebView grâce à la ligne (self est ici une instance QWebView):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.page().mainFrame().addToJavaScriptWindowObject('pythonObj', PythonObj())
    3- on intègre dans le texte html tous les appels qu'on veut. Par exemple, cette ligne html affiche un lien hypertexte qui va appeler la méthode Python 'siteweb' de la classe interface 'pythonObj':

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="#" onclick='pythonObj.siteweb("http://www.jpvweb.com")'">http://www.jpvweb.com</a>
    Voilà mon code complet (Python 2.7, PyQt4) qui donne la fenêtre affichée plus haut:

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7 (>=2.6)
     
    __logiciel__ = "monlogiciel"
    __version__ = "1.02.4567"
    __date__ = "9/2012"
     
    import sys
    from PyQt4 import QtCore, QtGui, QtWebKit
    import webbrowser # pour appel du navigateur par défaut
     
    #############################################################################
    class PythonObj(QtCore.QObject):
     
        def __init__(self, parent=None):
            super(PythonObj, self).__init__(parent)
     
        @QtCore.pyqtSlot()
        def aproposdeqt(self):
            QtGui.qApp.aboutQt()
     
        @QtCore.pyqtSlot(str)
        def siteweb(self, site):
            webbrowser.open(site)
     
    #############################################################################
    class Apropos(QtWebKit.QWebView):
     
        def __init__(self, parent=None):
            super(Apropos, self).__init__(parent)
            self.resize(550,260)
            self.setWindowTitle("A propos")
            # met en place l'icone s'il en a une
            #self.setWindowIcon(u"icone.ico")
            # place la fenêtre au milieu de l'écran
            screen = QtGui.QDesktopWidget().screenGeometry()
            size =  self.geometry()
            self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)
            # empêche le redimensionnement
            size = self.geometry()
            self.setFixedSize(size.width(), size.height())
     
            # permettre l'appel de méthodes Python par javascript
            self.page().mainFrame().addToJavaScriptWindowObject('pythonObj', PythonObj())
     
            plateforme = sys.platform
            if plateforme=='win32': plateforme ='Windows'
            elif plateforme=='linux2': plateforme = 'Linux'
            elif plateforme=='darwin': plateforme = 'Mac OS X'
            else: pass
            self.setHtml(u"""
                <p style="font-family:DejaVu Sans, Arial, Helvetica, sans-serif; font-size:10pt;color:green;"> 
                <br/><span style="font-size:12pt;font-weight:bold;">Logiciel {0} version {1} ({2})</span>
                <br/>Copyright Tyrtamos 2012
                <br/>Licence GPL3
                <br/>Sources sur demande ici: <a href="#" onclick='pythonObj.siteweb("http://www.jpvweb.com")'">http://www.jpvweb.com</a>
                <br/>
                <br/><span style="font-size:12pt;font-weight:bold;">Contexte d'exécution en cours:</span>
                <br/>Système d'exploitation: {3}
                <br/>Python version: {4}
                <br/>Qt version: {5}
                <br/>PyQt4 version: {6}
                <br/>
                <br/><button onClick="pythonObj.aproposdeqt()">&nbsp;&nbsp;A propos de Qt&nbsp;&nbsp;</button>
                </font></p>
                """.format(__logiciel__, __version__, __date__,
                plateforme,
                sys.version, 
                QtCore.QT_VERSION_STR, 
                QtCore.PYQT_VERSION_STR)
                )
     
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        fen = Apropos()
        fen.show()
        sys.exit(app.exec_())
    Pour l'appel à la page de licence Qt, j'ai choisi le bouton parce que je le trouve plus joli, mais le lien hypertexte marcherait pareil:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="#" onclick="pythonObj.aproposdeqt()">A propos de Qt</a>

  4. #4
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 180
    Par défaut Super ce truc
    Bonjour Tyrtamos,

    Ton truc à l'air vraiment bien fait, il faut que j'essaie

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    En plus, puisque c'est du html, on peut mettre un fond avec répétition. La seule astuce ici est que l'image utilisée (jpg par exemple) doit être intégrée avec son chemin absolu sur le disque dans le code html précédé de "file:///". Ce qui veut dire que ces images locales doivent être paramétrées dans le format.

    Par exemple, j'ai une petite image 'fond.jpg' placée dans le répertoire courant qui sera utilisée avec répétition sur le fond. Le texte html sera modifié comme suit (on voit le '{}' devant fond.jpg pour insertion du répertoire):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <body style="background-image:url({}fond.jpg); background-repeat:repeat">
    <p>
     
    ... le texte...
     
    </p>
    </body>
    On calcule le répertoire (courant dans notre cas) qui devra précéder le nom du fichier fond.jpg:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    repimages =  QtCore.QUrl.fromLocalFile(os.getcwd()).toString() + "/"
    Et on l'intègrera dans les paramètres de format:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    html = "<body style=...> ...</body>".format(repimages, ...)
    Voilà le résultat avec un fond style "Mac":



    On devrait pouvoir intégrer des logos et autres images dans le code html pour avoir un "à propos" personnalisé.

    [Edit] logiquement, d'après la doc, le répertoire où il faut aller chercher les images devrait être donné en 2e argument de setHtml. Ce serait plus élégant que d'avoir des adresses absolues dans le texte html, mais je n'ai pas réussi. Si quelqu'un sait comment il faut faire ça, ça m'intéresse!

    [Edit 2] Eh, si ça marche, mais le répertoire doit se terminer par un slash! Ce qui donne avec le répertoire courant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.setHtml(html, QtCore.QUrl.fromLocalFile(os.getcwd()+'/'))
    Les fichiers n'ont donc plus besoin de leur chemin absolu dans le texte html: c'est beaucoup mieux comme ça!

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

Discussions similaires

  1. Appeler une fonction dans un lien
    Par jobim08 dans le forum Langage
    Réponses: 3
    Dernier message: 16/04/2009, 11h45
  2. window.open avec des variables dans un lien hypertexte
    Par ledisciple dans le forum Général JavaScript
    Réponses: 16
    Dernier message: 09/04/2009, 12h41
  3. appelle de python dans C
    Par julien25 dans le forum Interfaçage autre langage
    Réponses: 3
    Dernier message: 02/03/2009, 17h15
  4. Insérer du javascript dans un lien hypertext
    Par X3Rnou dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 18/11/2008, 12h35
  5. [langage] Appel de fonction dans un lien
    Par drakan dans le forum Langage
    Réponses: 1
    Dernier message: 17/05/2005, 18h30

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