1

What I want to do is that I have a QSS stylesheet in specific folder. And I want to edit selected elements from GUI, programmatically. Since QT doesn't support SaSS or LeSS, I need to do this "manually". What I have until now is read a qss file and with few if statments I can get the value of each element that placed on qss file.

QTextStream in(qssFile);
line = in.readLine();
if(line.startsWith("QDialog"))
{
     int start = line.indexOf("{") + 1;
     int end = line.indexOf("}", start);
     qDebug() << "QDialog" << line.mid(start, end - start); //"background-color: #404040;"
}

I read the line and if user changes the values on the gui, I save the new ones. of course this one isn't the best/right solution but how I can make a better solution to this issue I have?

Update 1: the sample code I have added it may work, but seems like a "junk" code with 7-8 if statements for each line. What I need is if I can set variables to each elements in stylesheet such as:

QDialog{ 
   background-color: @dialogBackgroundColor; 
   min-width: @dialogMinWidth;
}

by that I can set the values into the temp stylesheet and apply it.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Tirolel
  • 928
  • 3
  • 17
  • 43
  • You may write your own QSS parser/generator. There are a lot of ways, how to do it. Vote for close, because it is not clear, what you mean by "better solution". If your solution works - use it. If not - provide additional information that will clarify your question. – Dmitry Sazonov Aug 08 '16 at 09:24
  • @Dmitry thank you for reply, my solution may work but I see it like a junk code. I will update the thread with better question – Tirolel Aug 08 '16 at 09:28
  • Qt has a built-in QSS parser that you can re-use. You can [iterate the parse tree](http://stackoverflow.com/a/31593423/1329652) and modify it to your heart's desire. You could also use a proxy tree model to let the user graphically and safely modify the QSS. – Kuba hasn't forgotten Monica Aug 08 '16 at 19:07
  • I had a similar problem, but instead of editing it directly, I simply use a `std::map` to make stuff like `QWidget#some_id` map to another `std::map`, which combines key-value pairs. I then rebuild the entire stylesheet when a property changes and then apply it. Horrible in every way, but at least it works and doesn't depend on some undocumented, possibly not available in future release, feature.:-( – Clearer Aug 21 '17 at 07:31

1 Answers1

2

There is a terrible asymmetry between the dynamic C++ setters and getters for several (but far from all) properties that can be set via QSS.

To make the problem worse, as you noticed, there is no decent way to edit the active stylesheet other than refreshing the whole thing, which means reloading everything. To top it all off, there is no easy programmatic way to actually edit the stylesheet once loaded. It's a structured string, and for parsing and modifying it, you need to resort to boilerplate code, written by you.

Not using stylesheets isn't an option either, as various properties cannot be set without them.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • The stylesheet can be iterated and modified in the form of a parse tree. The data structure you should look for is `QCss::StyleSheet`. You can get access to the stylesheet and its parse via the proxy stylesheet of the widget. You can modify the stylesheet in the stylesheet cache, or regenerate the CSS from the parse tree. – Kuba hasn't forgotten Monica Aug 08 '16 at 19:16
  • @KubaOber Is that a public function/struct/class? I can't seem to find any documentation on it. Using private internals is rather... hacky, don't you think? – rubenvb Aug 08 '16 at 21:05
  • It's less hacky than writing a CSS parser yourself. Qt's source code is available for you to use. Really. – Kuba hasn't forgotten Monica Aug 09 '16 at 14:19
  • @Kuba It's more hacky because implementation details can change in new releases. This is not a future-proof solution. – rubenvb Aug 09 '16 at 14:39
  • Nobody forces you to do anything, including taking changed implementations. You want the CSS parser from Qt, you copy it over to your project and you use it. Ideally, you should be keeping your own git repository of Qt and having your projects reference it and build the whole shebang on a clean system, pretty much. Only then you're truly in control over what goes into your product. – Kuba hasn't forgotten Monica Aug 09 '16 at 15:39
  • @kuba You're partially right, but copying over private code won't guarantee it will keep functioning in future versions. The only way to be future-proof is to write something that limits itself to the public interface, which in this case would mean reloading the qss each time you modify it, and parsing it yourself or through a library. – rubenvb Aug 09 '16 at 16:00
  • `QCss` namespace is very much self-contained. It is almost as if it was meant to be reused, but someone ran out of time documenting it and massaging the API for public consumption. It depends on public Qt API itself, and using it after you add it to your own sources is no different than using any other 3rd party library that uses Qt. – Kuba hasn't forgotten Monica Aug 09 '16 at 16:02