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

Qt Discussion :

Rafraichir le CSS


Sujet :

Qt

  1. #1
    Membre éprouvé
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Par défaut Rafraichir le CSS
    Bonjour,
    J'utilise le CSS et les propriétés "méta-objet" pour modifier l'apparence de widget en fonction d'une "classe css", en fait un simple attribut string qui nomme (ou pas) une certaine classe.
    Comme le suggère la doc http://qt.developpez.com/doc/4.7/exe...tes-dynamiques

    Le problème est qu'il faut définir ces propriétés sur les objets avant de charger le CSS sinon l'affichage ne les prends pas en compte. Je cherche donc la meilleure méthode pour "rafraichir" l'affichage du CSS. Pour le moment je recharge carrément le fichier avec "qApp->setStyleSheet".

    Y'a-t-il une méthode propre ou plus rapide à l'exécution ? merci d'avance !

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par YoniBlond Voir le message
    Le problème est qu'il faut définir ces propriétés sur les objets avant de charger le CSS sinon l'affichage ne les prends pas en compte.
    C'est pas dynamique?? ça m'étonne.

    Ça tombe bien, je vais utiliser ceci tout à l'heure. Je te dirais si j'obtient le même problème.

  3. #3
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour

    A priori, il faut effectivement forcer la mise à jour du control avec setStyleSheet (update, refresh, etc. ne fonctionnent pas)

    Par contre, tu peux simplement forcer le controle qui doit être mit à jour (et les controles "enfants") avec setStyleSheet(b->styleSheet());

    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
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
     
    private:
        QPushButton* b;
     
    public:
        MainWindow(QWidget *parent = 0)
            : QMainWindow(parent)
        {
            b = new QPushButton("cliquer ici", this);
            b->setProperty("prop", QVariant(false));
            b->setStyleSheet("* [prop='true'] { background-color: yellow }");
            connect(b, SIGNAL(clicked()), this, SLOT(clique()));
        }
     
    public slots:
        void clique()
        {
            if(b->property("prop").toBool() == true)
            {
                b->setProperty("prop", QVariant(false));
                setStyleSheet(b->styleSheet());
            }
            else
            {
                b->setProperty("prop", QVariant(true));
                setStyleSheet(b->styleSheet());
            }
        }
    };
    Le mieux est encore de forcer la mise à jour des controles dans les fonctions d'accès des propriétés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class MyWidget : public QWidget
    {
        Q_OBJECT
        Q_PROPERTY(bool myproperty READ getMyProperty WRITE setMyProperty)
     
    public:
        bool getMyProperty() { return property("myproperty").toBool(); }
        void setMyProperty(bool value)
        {
            setProperty("myproperty", QVariant(value));
            setStyleSheet(b->styleSheet());
        }
    };

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Bon y as rien de documenté... APrés mes teste et recherche sur le net, on peut demander au style de repolishé (je sais pas comment le traduire) une widget.
    J'ai trouvé sur le net
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    myWidget->style()->unpolish(myWidget);
    myWidget->ensurePolished();
    Sous Qt 4.6
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myWidget->style()->polish(myWidget);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myWidget->style()->unpolish(myWidget);
    fonctionne très bien pour moi.


    Bizzare qu'il n'ai pas prévue une fonction pour cela dans QWidget
    En lisant la doc, j'arrive pas à savoir si c'est correcte ou dangereux.... A la limite la version avec unpolish semble plus correspondre.

    [lancement de rumeur]
    Tant pis on la rajoutera dans la ... BIPPPPPPPPPP... Ha oui j'ai pas encore le droit d'en parler encore

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Par contre, tu peux simplement forcer le controle qui doit être mit à jour (et les controles "enfants") avec setStyleSheet(b->styleSheet());
    SI tu fait cela, tu va recopier le stylesheet, et il ne sera plus partagé. Ce qui veut dire que si tu modifie le stylesheet avec QApplication, cela n'affectera pas ces widgets...

    Sans compté qu'il devra reparser tous le qss ce qui peut couter en temps.

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    SI tu fait cela, tu va recopier le stylesheet, et il ne sera plus partagé. Ce qui veut dire que si tu modifie le stylesheet avec QApplication, cela n'affectera pas ces widgets...
    Que veux-tu dire par "partagé" ?

    En fait, setStyleSheet(b->styleSheet()); force la mise à jour du controle et des enfants et prend en compte les styles hérités

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    qApp->setStyleSheet("* [prop='true'] { background-color: yellow }");
    ...
    b->setProperty("prop", QVariant(true));
    b->setStyleSheet(b->styleSheet());
    fonctionne correctement.

    Par contre, cela "oblige" à recopier une chaine de caractère (si elle est définie dans le controle mais pas si les stylesheet sont définies dans qApp), mais ce n'est pas important (en terme de temps) comparé à la mise à jour du controle.

    Mais c'est quand même plus "propre" (visuellement) avec polish().

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Que veux-tu dire par "partagé" ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setStyleSheet(b->styleSheet())
    créé un style spécifique pour la widget. Ce ne sera plus celui de QApplication.

    Donc si tu modifie le styleSheet globale, la widget ne sera pas modifié.


    Mais c'est quand même plus "propre" (visuellement) avec polish().
    je ne suis pas d'accord.
    1- polish == Le style réadapte l'affichage d'un widget.
    2- redonner un style sheet == appliquer un nouveau style. Sans compter qu' il va devoir tous reparser pour initialiser le nouveau style...

  8. #8
    Membre éprouvé
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Par défaut
    La première méthode de yan fonctionne aussi bien que ce que je faisais avant, et est sûrement plus efficace car je lisais/rechargeais tout le fichier qss à chaque fois. Ça ne prend que 2 lignes donc ça reste acceptable.

  9. #9
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Donc si tu modifie le styleSheet globale, la widget ne sera pas modifié.
    Non. C'est ce que je précisais avec le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    qApp->setStyleSheet("* [prop='true'] { background-color: yellow }");
    ...
    b->setProperty("prop", QVariant(true));
    b->setStyleSheet(b->styleSheet());
    le style peut être défini au niveau global sans problème. Dans ce cas, b->setStyleSheet(b->styleSheet()); repcopie simplement une chaine de caractères vide puis met à jour le control (en vérifiant les stylesheet des parents, dont qApp)

    Le résultat est identique avec les 2 méthodes

    EDIT: en fait setStyleSheet recopie la style (donc ici b->setStyleSheet(b->styleSheet()); ne fais rien de particulier) puis appelle polish() (http://qt.gitorious.org/qt/qt/blobs/...el/qwidget.cpp). Donc c'est bien la même chose au final.

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    repcopie simplement une chaine de caractères vide puis met à jour le control (en vérifiant les stylesheet des parents, dont qApp)
    Tu as raison, je pensais qu'il enverrai celui de qApp
    Mais autant faire b->setStyleSheet(""); alors.

    Seulement, que ce passe t'il si le styleSheet est propre au widget?
    Et là on tombe bien sur un problème de ré-initialisation du style locale au widget qui est inutile.

    Mais je sais pas ce qu'il est préférable de faire. Dans la logique, je dirais que c'est unpolish + polish.

  11. #11
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Une chtite fonction qui fera cela pour nous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    inline void updateQssProperty(QWidget * w,const char * prop, const QVariant & val)
    {
     
        if(w->property(prop) == val)
        {
            return;
        }
        w->setProperty(prop,val);
        w->style()->unpolish(w);
        w->style()->polish(w);
    }

  12. #12
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Si on définit les style uniquement au niveau global, b->setStyleSheet(""); sera identique à b->setStyleSheet(b->styleSheet()); puisque b->styleSheet() retourne une chaine vide. Par contre, si on utilise des styles globaux et locaux (par exemple dans un dialogue de selection de style qui afficherait l'apparance de plusieurs styles), cela risque de poser problème (voila peut etre un module à ajouter à ........... : un dialogue de selection de style avec prévisualisation )

    D'après la doc (si j'ai bien compris), il faut appeler unpolish() avant polish()
    http://qt.developpez.com/doc/latest/....html#unpolish
    It is called for every polished widget whenever the style is dynamically changed; the former style has to unpolish its settings before the new style can polish them again.
    Par contre, ensurePolished() ne semble par forcer la mise à jour (si je comprend bien) :
    http://qt.developpez.com/doc/latest/...ensurepolished

    Pour updateQssProperty, je prefère plutôt utiliser Q_PROPERTY avec le code que j'avais indiqué avant (ça me parait plus Qt like...)

  13. #13
    Membre éprouvé
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Par défaut
    L'idée est qu'après avoir appelée unpolish, le widget ait forcément besoin de se mettre à jour lors du polish que va appeler ensurePolished. En tout cas ça a marché dans mon cas, mais ça reste assez simple (un CSS global à l'appli).

    Après j'ai du mal à voir quelle méthode serait la moins coûteuse en performances.

  14. #14
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    voila peut etre un module à ajouter à .......... : un dialogue de selection de style avec prévisualisation
    faut pas encore en parler

    Par contre, ensurePolished() ne semble par forcer la mise à jour (si je comprend bien) :
    http://qt.developpez.com/doc/latest/...ensurepolished
    Apparemment cela ne sert qu'une fois avant la premier affichage

    Citation Envoyé par gbdivers Voir le message
    Pour updateQssProperty, je prefère plutôt utiliser Q_PROPERTY avec le code que j'avais indiqué avant (ça me parait plus Qt like...)
    C'est deux butes différents.
    updateQssProperty permet d'utiliser cela avec n'importe quel widget grâce au property dynamique. Et évite du code à écrire.
    Mais la solution Q_PROPERTY est aussi intéressante.


    [edit]
    une autre manière pour faire cela que j'aime bien

    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
    struct Qss
    {
        QWidget * w;
        Qss(QWidget * w)
            :w(w)
        {}
     
        Qss * operator->(){return this;}
     
        void setProperty(const char * prop, const QVariant & val)
        {
            if(w->property(prop) == val)
            {
                return;
            }
            w->setProperty(prop,val);
            w->style()->unpolish(w);
            w->style()->polish(w);
        }
    };
     
    /*.....*/
     
    Qss(maWidget)->setProperty("prop",true);

  15. #15
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class MyWidget : public QWidget
    {
        Q_OBJECT
        Q_PROPERTY(bool myproperty READ getMyProperty WRITE setMyProperty)
     
    public:
        bool getMyProperty() { return property("myproperty").toBool(); }
        void setMyProperty(bool value)
        {
            setProperty("myproperty", QVariant(value));
            setStyleSheet(b->styleSheet());
        }
    };
    ca fait pas un appel récursive?
    car property("myproperty") appel getMyProperty() qui appel property("myproperty") qui... ?

  16. #16
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Oups, j'ai perdu une occasion de me taire...

    Concernant les performances, les stylesheets ne sont peut être pas ce qu'il ya de mieux.
    Comme les styles sont définis dans un QString, il est nécessaire de parser les styles (et tous les parents de chaque objet), ce qui peut être lent.

    Un solution plus rapide serait de redéfinir un QStyle spécifique. C'est ce que fait Qt Creator :
    http://qt.gitorious.org/qt-creator/q...nhattanstyle.h
    http://qt.gitorious.org/qt-creator/q...attanstyle.cpp
    puis appeler au démarrage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    qApp->setStyle(new ManhattanStyle(baseName));
    Ca n'a pas l'air très compliqué à faire

  17. #17
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Concernant les performances, les stylesheets ne sont peut être pas ce qu'il ya de mieux.
    Comme les styles sont définis dans un QString, il est nécessaire de parser les styles (et tous les parents de chaque objet), ce qui peut être lent.
    Normalement il ne le fait qu'une fois pour initialiser le style interne.

    Pour créer un autres style c'est plus compliqué, mais tu peut faire beaucoup plus de chose.

  18. #18
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    On voit ici que le style est mit à jour en fonction d'une propriété qui peut être changer en cours d'execution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    b->setStyleSheet("* [prop='true'] { background-color: yellow }");
    Donc 2 styles sont créés à l'initialisation et le style "visible" est selectionné en fonction de la valeur de la propriétés, soit les stylesheets sont "relus" à chaque mise à jour... je penche pour la seconde possibilité. A tester.

    EDIT:
    ca fait pas un appel récursive?
    car property("myproperty") appel getMyProperty() qui appel property("myproperty") qui... ?
    Tu as raison, je dis n'importe quoi
    La fonction dépend de comment la propriété est enregistré.
    Dans le nouvel objet :
    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
    class MyWidget : public QWidget
    {
        Q_OBJECT
        Q_PROPERTY(bool myproperty READ getMyProperty WRITE setMyProperty)
     
    public:
        bool getMyProperty() { return m_value; }
        void setMyProperty(bool value)
        {
            m_value = value;
            style()->unpolish(this);
            style()->polish(this);
        }
    private:
        bool m_value;
    };
    dans une autre classe (par exemple en fonction de la propriétés "objectName" du parent) :
    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
    class MyWidget : public QWidget
    {
        Q_OBJECT
        Q_PROPERTY(QString myproperty READ getMyProperty WRITE setMyProperty)
     
    public:
        QString getMyProperty() { return m_parent->qetObjectName(); }
        void setMyProperty(QString value)
        {
            m_parent->setObjectName(value);
            style()->unpolish(this);
            style()->polish(this);
        }
    private:
        QObject* m_parent;
    };

  19. #19
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Quand une property dynamique est modifié, un event est emit. Ca permet de faire la MAJ de manière transparente


    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
    //.h
    class QssDynamiqueProperty :public QObject
    {
        Q_DISABLE_COPY(QssDynamiqueProperty)
        QssDynamiqueProperty()
        {}
    protected :
        bool	eventFilter ( QObject * watched, QEvent * event );
     
    public :
        static QObject * filter();
     
        static void  installTo(QWidget *);
    };
     
     
     
     
     
    //.cpp
    QObject * QssDynamiqueProperty::filter()
    {
        static QssDynamiqueProperty singleton;
        return & singleton;
    }
    bool	QssDynamiqueProperty::eventFilter ( QObject * watched, QEvent * event )
    {
        QWidget * w = qobject_cast<QWidget *>(watched);
        if(w && event->type() == QEvent::DynamicPropertyChange)
        {
            w->style()->unpolish(w);
            w->style()->polish(w);
        }
        return QObject::eventFilter ( watched,event );
     
    }    
     
    void  QssDynamiqueProperty::installTo(QWidget * w)
    {
        w->installEventFilter(filter());
    }
    on l'utilise comme cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Qxxx * maWidget  = new Qxx;
    QssDynamiqueProperty::installTo(maWidget);
     
    ....
     
    mawidget->setProperty("prop",true); // <- ici l'eventfilter va être exploité

  20. #20
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Je me suis amusé a faire quelques tests entre QStyle et les stylesheet.

    Le code :
    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
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
     
    #include <QtGui/QMainWindow>
    #include <QtGui/QProxyStyle>
    #include <QtGui/QStyleFactory>
    #include <QtGui/QApplication>
    #include <QtGui/QPainter>
    #include <QtGui/QPushButton>
    #include <QtGui/QGridLayout>
    #include <qdebug.h>
    #include "time.h"
     
    class TestStyle : public QProxyStyle
    {
    public:
        TestStyle() : QProxyStyle(QStyleFactory::create("TestStyle")) {}
     
        void drawControl(
                ControlElement element,
                const QStyleOption* option,
                QPainter* painter,
                const QWidget* widget = 0) const
        {
            if(element == QStyle::CE_PushButton)
            {
                QRect r = widget->rect();
                painter->setPen(QPen(Qt::blue, 2));
                painter->setBrush(QBrush(Qt::red));
                painter->drawRoundedRect(r, 5, 5);
                painter->setPen(QPen(Qt::yellow));
                painter->drawText(r, Qt::AlignCenter, "A");
            }
            else
                QProxyStyle::drawControl(element, option, painter, widget);
        }
    };
     
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    private:
        bool stylesheet_selected;
        QString test_stylesheet;
        TestStyle* test_style;
     
     
    private slots:
        void changeStyle()
        {
            double debut = clock();
     
            if(stylesheet_selected)
            {
                qApp->setStyleSheet(test_stylesheet);
            }
            else
            {
                qApp->setStyle(test_style);
                qApp->setStyleSheet("");
            }
            stylesheet_selected = !stylesheet_selected;
     
            qDebug() << (stylesheet_selected ? "stylesheet" : "style") << (clock() - debut);
        }
     
    public:
        MainWindow(QWidget *parent = 0) : QMainWindow(parent)
        {
            // init styles
            stylesheet_selected = true;
            test_style = new TestStyle();
            test_stylesheet = "QPushButton { color:yellow; background:red; border: 2px solid blue }";
            changeStyle();
     
            QWidget* content = new QWidget();
            QGridLayout* layout = new QGridLayout(content);
            for(int i=0; i<50; ++i)
            {
                for(int j=0; j<50; ++j)
                {
                    QPushButton* b = new QPushButton("A", this);
                    const int s = 10;
                    b->resize(s, s);
                    b->setMinimumSize(s, s);
                    b->setMaximumSize(s, s);
                    layout->addWidget(b, i, j);
                    connect(b, SIGNAL(clicked()), this, SLOT(changeStyle()));
                }
            }
            content->setLayout(layout);
            setCentralWidget(content);
        }
    };
     
    #endif // MAINWINDOW_H
    Le temps d'execution moyen :
    - avec QStyle = 0.231 sec
    - avec stylesheet = 0.383 sec
    donc une différence importante (+68% de temps).

    Quelques remaques :
    - on doit pas mesurer exactement la même chose. Avec stylesheet, on redessine entièrement les boutons avec des propriétés différentes. Avec QStyle, on redessine le minimum. Mais en modifiant le code pour redessiner un bouton complet avec QStyle en changeant simplement la couleur de texte, les temps d'execution sont identique aux temps précedent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                QProxyStyle::drawControl(element, option, painter, widget);
                QRect r = widget->rect();
                painter->setPen(QPen(Qt::yellow));
                painter->drawText(r, Qt::AlignCenter, "A");
    - C'est beaucoup plus complexe d'implémenter la méthode avec QStyle. Donc dans le cas où l'on veut changer simplement la couleur du texte d'un bouton... ca fait beaucoup pour pas grand chose. Par contre, s'il l'aspect des widgets est totalement différent (par exemple pour Qt Creator), alors ça devient intéressant.

    @Yan : j'aime bien ta méthode avec event

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [AJAX] possible de rafraichir du CSS dans la page via Ajax?
    Par freeriders88 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 12/06/2007, 10h39
  2. Mail et css
    Par Truc dans le forum Modules
    Réponses: 2
    Dernier message: 01/10/2003, 22h25
  3. .css
    Par rgarnier dans le forum XMLRAD
    Réponses: 4
    Dernier message: 25/04/2003, 15h34

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