Use Color / Font,FontSize parameterized tables



  • Today I use hard coded color, font, fontsize in my qml and code.
    Such as,

    [QML]
    Rectangle {
    width: parent.width
    height : 75
    color: "#666666"
    }
    Text {
    color: "#FFFFFF"
    font.family: "Open Sans"
    font.pixelSize: 11
    }

    [CPP]
    list itemitem->setProperty(propertyName.c_str(), value);

    However, I would like to switch those to parameterized tables. And probably I could expand those to schme and theme for later.
    such as parser class to retrieve value from XML, Jason tables
    <XML>
    <Color x:Key="HighlightColor">#FF086F9E</Color>
    <Color x:Key="AccentColor">#CC119EDA</Color>
    ....

    Is there any simple way to manage them?
    I would like to ask you any Ideas for this.


  • Moderators

    Hi @Jehyeok,

    One way would be to create a custom component which reads the XML or JSON values. This component will provide individual properties which will contain the actual data. for eg. font, color etc.. Register this component and make it available to QML.
    Something like:

    import ThemeLoader 1.0
    
    ThemeLoader {
       id: myTheme
    }
    
    //Use it in QML
    
    Text {
      font: myTheme.font
      color: myTheme.color
      ...
    }
    

    If the JSON or XML changes in the background you can re-read it load the new values in custom component and notify the changes by emitting signals. Now on QML side as we have binded these properties to other components they will get updated on the fly.
    Hope this is what you were thinking to do...



  • @p3c0 Thank you for sharing the idea.
    I would like to use a color theme globally.
    So, I structured a color xml and I parsed a xml file to build my color map(QMap).
    And access the color from the Color object from rootcontext.
    Now I am able to set all default theme colors on UI components. :)

    Furthermore, I would like to apply theme changes in run time on the fly.
    Such as, setting dialog -> change theme -> Set button -> Bring another theme color map form XML -> update UI? ->See color changes in Window
    And I succeeded update QMap data (replace a value by new value).
    But, it didn't update UI(repaint, redraw) to see the changes right away.
    I could propagate event when I move tab or invoke events that changes colors. But it is not what I want. I want to see changes right away.

    Do you know how to apply them to all my windows in run time on the fly?


  • Moderators

    @Jehyeok Instead of setting it as a context property I would suggest you to create and register it as a singleton object as explained earlier. This way you can easily bind the properties from the singleton object. And thus on XML update from singleton the binded properties in your QML too gets updated.



  • @p3c0 Thank you. I got point. and it wokrs indeed.
    I am able to get the singleton object (ThemeLoader) in qml using 'qmlRegisterSingletonType'.
    ex, MYQML.qml
    import ThemeLoader 1.0
    Text {
    color: ThemeLoader.colorText
    }

    Two more questions,

    1. How I can get the singleton object and call the function in cpp code?
    2. How to notify the changes in MYQML.qml Text by emitting signals when ThemeLoader colorText changes? Also how do you emmit signals when QMap property changes?

  • Moderators

    @Jehyeok

    How I can get the singleton object and call the function in cpp code?

    Like this.

    How to notify the changes in MYQML.qml Text by emitting signals when ThemeLoader colorText changes?

    By using Q_PROPERTY. AddNOTIFY to allow QML bindings.

    Also how do you emmit signals when QMap property changes?

    Perhaps in the same way ? Using datatype as QMap in Q_PROPERTY. But IMO instead of using QMap of properties I think its better to use individual properties so that the binding is executed per property.



  • @p3c0
    Thank you for quick reply.
    I take your advice and I will use individual properties. But it doesn't work ...

    Please take a look

    Theme.h
    Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY colorChanged)
    public:
    void setColor(QColor inputcolor)
    {
    m_color= inputcolor;
    emit colorChanged();
    }
    QColor getColor() const
    {
    return m_color;
    }
    signals:
    void colorChanged();
    private:
    QColor m_color;

    Theme.cpp
    // init
    setColor("red")

    // later to see changes, supposed to update color on text
    setColor("blue")

    text.qml
    Text {
    id: text_
    color: Theme.color


  • Moderators

    @Jehyeok That's strange. Does the Theme class haveQ_OBJECT macro ?
    Can you share rest of the code ? When are you changing the color to new one.



  • @p3c0 this is details

    !!!! PS text color has been changed !! but the current top position dialog which triggered the change theme only.
    Not main and existed other windows !! I would like to update colors in all window

    Header
    class SPColors : public QObject
    {
    Q_OBJECT
    Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY colorChanged)
    public:
    SPColors();
    virtual ~SPColors();

    		Q_INVOKABLE QString getTheme() const;
    		Q_INVOKABLE bool setTheme(const QString& theme);
    		void setColor(QColor inputcolor)
    		{
    			color = inputcolor;
    			emit colorChanged();
    		}
    		QColor getColor() const
    		{
    			return color;
    		}
    	signals:
    		void colorChanged();
    
    	private:
    		QString currentTheme_;
    		QColor color;
    	};
    

    CPP
    SPColors::SPColors()
    {
    setColor(QColor("#FFFFFF"));
    }

    setTheme(...String theme) // this is called by other dialog
    {
    if (theme=="white")
    setColor(QColor("#000000"));
    else
    setColor(QColor("#FFFFFF"));
    }

    QML
    Text {
    id: text_
    color: SPColors.color


  • Moderators

    @Jehyeok

    !!!! PS text color has been changed !! but the current top position dialog only. Not main window !! I would like to update colors in all window

    Good. Apply the same logic to other windows too.



  • @p3c0
    Oh may you miss-understood.

    I set this color in the Text component which is used all my windows.
    MyText.qml
    Text
    {
    color: SPColors.color
    }

    DialogA.qml
    MyText
    {
    }
    DialogB.qml
    MyText
    {
    }

    I expected to see all text color changes (in dialogA, dialogB).
    But it is applied only one dialog(DialogA which trigger setTheme and emit colorChanged).
    Do you know how to apply it in entire windows?


  • Moderators

    @Jehyeok It should work too. I tested a similar case and it works.

    Do you know how to apply it in entire windows?

    The way you tried should work.



  • @p3c0 You are right !!!
    Beautiful !!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.