1

In this example, I'm writting the "stylesheet" on a QTextEdit and applying it to the QMainWindow

myStruct.a: 10;
myStruct.b: "hello world";

setStyleSheet(textEdit->toPlainText());

I tried to follow this question: https://forum.qt.io/topic/82325/best-way-to-access-a-cpp-structure-in-qml/6

But none of the functions is being called setA getA getMyStruct or setMyStruct when the stylesheet is applied.

What the proper way to update the values of MyStruct using the stylesheet?

struct MyStruct
{
    Q_GADGET
    int m_a;
    QString m_b;

    Q_PROPERTY(int a READ getA WRITE setA)
    Q_PROPERTY(QString b MEMBER m_b)

    void setA(int a) 
    { 
      m_a = a; 
    }
    int getA() const
    { 
        return m_a;
    }
};
Q_DECLARE_METATYPE(MyStruct)



class MainWindow : public QMainWindow
{
    Q_OBJECT
    Q_PROPERTY(MyStruct myStruct READ getMyStruct WRITE setMyStruct NOTIFY myStructChanged)
public:
    MainWindow() : QMainWindow(nullptr), ui(new Ui::MainWindow())
    {
        ui->setupUi(this);

        QVBoxLayout* layout = new QVBoxLayout();
        ui->centralWidget->setLayout(layout);

        QTextEdit* textEdit = new QTextEdit(this);
        textEdit->setText(R"(
            myStruct.a: 10;
            myStruct.b: "hello world";
        )");

        QPushButton* button = new QPushButton("update", this);
        connect(button, &QPushButton::clicked, [=] 
        { 
            setStyleSheet(textEdit->toPlainText()); 
        });

        layout->addWidget(textEdit);
        layout->addWidget(button);
    }    

    MyStruct myStruct;

    MyStruct getMyStruct() const
    {
        return myStruct;
    }

    void setMyStruct(MyStruct val)
    {
        myStruct = val;
        emit myStructChanged();
    }

    void changeEvent(QEvent* event)
    {
        if (event->type() == QEvent::StyleChange) 
        {   
            qDebug() << "style changed"; 
        }
    }

signals:
    void myStructChanged();

private:
    Ui::MainWindow* ui;
};
Cesar
  • 41
  • 2
  • 5
  • 16
  • You seem to be very confused about something. What the link you shared is about is how to use C++ data in **QML**. Supposedly, instead of a `QMainWindow` (= `QWidgets` realm), you are expected to make that work with a QML file run by e.g. a `QQmlApplicationEngine` (= `QML` realm). It has nothing whatsoever to do with style sheets (that belong to the QWidgets module and is only used to customize how widgets look like). – Atmo Jul 15 '23 at 16:09
  • @Atmoi understand, about the question, do you know, if it's possible to update a struct from a stylesheet? I have found that there are even classes declared as Q_PROPERTY, and also some qproperties- that you can pass multiple values using a stylesheet. – Cesar Jul 17 '23 at 02:41
  • 1
    Your question in its current form is a [XY problem](https://en.wikipedia.org/wiki/XY_problem). Please explain what you are trying to do instead of asking help for your attempted implementation of it (which IMO is doomed from the start). And to answer your question: Like I said, stylesheets are **only** used to customized how widgets look like. – Atmo Jul 17 '23 at 15:14

2 Answers2

0

But none of the functions is being called setA, getA, getMyStruct or setMyStruct when the stylesheet is applied.

The closest way I have found from changing values with the stylesheet is "Dynamic Properties and Stylesheets", mentioned in this thread "Set dynamic property by stylesheet?"

Dynamic properties

For dynamic changes in the user interface look, the property value selector can be used in combination with dynamic properties.

Dynamic properties were introduced in Qt 4.2 and allow you to assign property values to QObjects for properties that do not exist at compile time.
I.e. if you choose to set the a property called urgent to true for a QObject, that property will stick even tough the class does not contain a Q_PROPERTY macro for the property urgent.

Creating a stylesheet selector relying on a dynamic property, e.g. urgent, makes it possible to highlight parts of the user interface in a very dynamic manner.

For instance, adding the following rule to the stylesheet above will given any QLineEdit with the urgent property set to true red text on a yellow background.

QLineEdit[urgent=true] {
  color: red;
}

But the documentation adds:

Limitations

  • Any stylesheet aware widget could be turned red using this generic selector
    (meaning any non-stylesheet aware element is not impacted)
  • the style will not update itself automatically when the value of a property referenced from the style sheet changes. Instead, you must manually trigger an update of the visual appearance of a widget when a styled property changes.

In short: the dynamic properties and stylesheet approach is for changing styles of widgets, not for storing or manipulating arbitrary data structures.


If you need to update a struct's properties from the user input, you might need to use a different approach, such as parsing the text yourself or using a form UI with input fields.

For instance, to parse a text, when pressing a button as in "Qt C++ connect QPushButton click":

connect(button, &QPushButton::clicked, [=] 
{ 
    QString text = textEdit->toPlainText();

    QRegularExpression re(R"(myStruct\.a: (\d+); myStruct\.b: "(.*)";)");
    QRegularExpressionMatch match = re.match(text);

    if (match.hasMatch()) 
    {
        int a = match.captured(1).toInt();
        QString b = match.captured(2);

        MyStruct ms = getMyStruct();
        ms.setA(a);
        ms.m_b = b;
        setMyStruct(ms);
    }
});

Here, when you press the button, the text is parsed using a regular expression. The values for a and b are extracted and used to update the properties in the MyStruct instance.
In other words, you are coding yourself the calls to setA, getA, getMyStruct or setMyStruct, in response to a UI event.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Hi, if i would go with a parser option I would prefer to not use a stylesheet/Q_PROPERTY, I was searching if it was possible to update a struct from the stylesheet. Some qproperties like minimumSize, i have been able to update from the stylesheet even it expecting two values instead of usually just one. – Cesar Jul 17 '23 at 02:49
  • @William I understand. "I was searching if it was possible to update a struct from the stylesheet": the short answer is "no, it does not seem possible". – VonC Jul 17 '23 at 05:36
0

No, you would not use a stylesheet to update a structure.