How to save style before changing it?



  • I want to make some changes to the application's global style, but want to save the default style, for use in certain widgets.

    I don't see anything in QStyle or QCommonStyle that would help me achieve it.

    How to do it?



  • Not sure, but saving a pointer to the style before applying it does not suffice?



  • How will saving a pointer help me when I change the style? A pointer is just a pointer. I need a copy or clone functionality, or a way to do what QApplication does when starting up, that is, constructing the correct style for the current environment.



  • Perhaps you should try to rephrase what your real goal is. It is not very clear what you want to achieve in the end.



  • If what you want is to be able to switch back to your original style, maybe thru a menu item, something like this should suffice:

    @QStyle* myOldStyle = style();
    // change your style here

    @

    but as Andre stated, you should express better what is your aim, so we can help.



  • What I want is

    • to be able to switch back to the old style
    • to be able to explicitly set the old style on certain widgets


  • Actually, that is in interesting question. A quick documentation scan does not reveal an easy way to do this.

    The main problem is, that the suggestion to just take the pointer and keep it around, and set it for the widgets you mention, will not work. QApplication will delete the curent QStyle object as soon as you set another one. That makes that you cannot really use the pointer anymore after that.

    On the other hand, I do not see a way to query the name of the current QStyle. I might have overlooked it, but I would have expected QStyle to provide a name for the style. If you can find it, you can instantiate a new style object based on the name.



  • [quote author="Andre" date="1323080251"]
    The main problem is, that the suggestion to just take the pointer and keep it around, and set it for the widgets you mention, will not work. QApplication will delete the curent QStyle object as soon as you set another one. That makes that you cannot really use the pointer anymore after that.
    [/quote]

    Confirm, in fact within QApplication::setStyle we have

    @ if (old && old->parent() == qApp) {
    delete old;
    } @

    being old the previous QStyle*. Being setStyle a static method there is no way with subclassing of change the behavior.

    I guess the only solution is to create a data structure to store properties about the old style. Or to make a subclass that reveals the d-pointer, with of course a lot of portability issues.....



  • A style is a global object, you cannot set a different style for a selected set of widgets.



  • Of course style is shared among the whole application. The problem here was also about how to swtich back to an already used style.



  • [quote author="fluca1978" date="1323090473"]Of course style is shared among the whole application. The problem here was also about how to swtich back to an already used style.[/quote]

    That was one part. The other question was

    [quote author="Asperamanca" date="1323078786"]What I want is

    • to be able to explicitly set the old style on certain widgets[/quote]


  • You can set a style on a widget too. That is not the issue:
    @
    QWidget::setStyle(theOtherStyle);
    @
    Setting a style on a widget will override the application style.

    However, I guess you should heed the warning from the documentation:
    [quote]Warning: This function is particularly useful for demonstration purposes, where you want to show Qt's styling capabilities. Real applications should avoid it and use one consistent GUI style instead.[/quote]



  • Well, I could do an ugly hack like this:

    @
    if (qobject_cast<QWindowsVistaStyle*>(QApplication::style()))
    {
    sm_pLocalStyle = new QWindowsVistaStyle();
    }
    else if (qobject_cast<QWindowsXPStyle*>(QApplication::style()))
    {
    sm_pLocalStyle = new QWindowsXPStyle();
    }
    else
    {
    sm_pLocalStyle = new QWindowsStyle();
    }
    @



  • [quote author="Andre" date="1323093315"]
    Setting a style on a widget will override the application style.
    [/quote]

    The widget style is usually the same for all widgets in an application (QApplication::style()), but it can be overridden on a per-widget basis using QWidget::setStyle().



  • Well, QStyle is an QObject, so retrieving the name of the current style is as simple as ...
    @
    QString currentStyle = qApp->style()->metaObject()->className(); // eg. 'QWindowsVistaStyle'
    @



  • But the class name is not the same as the style name, that you need to instantiate it. Although, I think you might be able to instantiate the object using the class name.



  • You can deep copy the style and just restore it later, can't you?



  • [quote author="veeeee_d" date="1323105034"]You can deep copy the style and just restore it later, can't you?[/quote]

    You can't clone a QObject.

    [quote author="Andre" date="1323104776"]But the class name is not the same as the style name, that you need to instantiate it. Although, I think you might be able to instantiate the object using the class name. [/quote]

    What's the difference between the style name and the class name? What's the advantage of one over the other?

    As far as I've seen QStyle unfortunately does not provide any invokable constructors so you'll need a simple factory which creates a QStyle out of a given (class) name.

    (I wonder why QObject subclasses do not have at least one invokable (default) constructor.)



  • Indeed, that would solve the issue. I also wonder why the QStyle classes don't have a method like styleName() that returns the name of the style that you can pass to QApplication::setStyle(QString name). The difference between the class and the style name is at least the "Q", but perhaps more.

    By the way: I noticed the same types of missing features for the Qt SQL drivers: all you can get is a list of plugin names for the drivers, but nothing that you might want to present to the end user.

    One final issue that comes to mind is this: are you (topic starter) certain that it actualy works to change the style during the application run? Because I think that that is not really supported. The docs for QApplication::setStyle() even suggest you set it before you actually construct the QApplication object. That makes me wonder how dynamic style changes are going to be. I never tried it myself, but it would not supprise me that dynamic style changes are not supported at all, and you run into all kinds of layout and rendering issues if you try.



  • Or maybe they could be exported as a Style Sheet, but I believe that would be a little complicated to develop.



  • Quite a thread, for such a simple question!

    My main issue is that my application is a little schizophrenic:

    Within the main window's client area, it is a simulation of how it would run on the embedded device, with a corresponding style.

    Outside that (the menu bar, dialogs that are only used on the PC), it should look and behave like a good desktop application.

    I need the style that is used on the embedded device to properly test the configuration on the PC. On the other hand, I need the dialogs and menus to at least work in the PC. Setting the style manually on the widgets that should have the "PC style" sounded like the best approach.

    However, I have found out that my main troubles did not come from the style at all...it came from the palette. Somehow, I implicitly assumed that the palette would be part of the style. It is not.

    So I could solve most of my troubles by copying the palette before changing it, and setting that palette on the "PC widgets". Fortunately, a palette can be copied easily.

    Thanks all for discussing and making suggestions!


Log in to reply
 

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