QProgressBar : Change color while keeping OS style - c++

I know that Qt uses by default the OS style for decorating a QProgressBar.
I am wondering if there is a way to change the color of a QProgressBar while keeping the OS style.
I tried several methods as showned below.
Changing the palette:
QPalette palette = myProgressBar->palette();
palette.setBrush(QPalette::Highlight, someColor); // setColor() did the same
myProgressBar->setPalette(palette);
Changing directly the style:
QPalette palette = myProgressBar->palette();
palette.setBrush(QPalette::Highlight, someColor); // setColor() did the same
myProgressBar->style()->polish(palette);
But both methods was completely ignored and nothing has changed.
The only way I found to change the color of the QProgressBar is by setting a style sheet via setStyleSheet(). The problem is that it ignores the OS style at the same time.
I think it is possible to approximately replicate the OS style in a style sheet but I don't know if it is possible to directly apply the OS style and only change the color palette.
I would be very grateful for any helpful answer.
EDIT: The OS is not fixed. I am trying to make it work under Windows but the application may/will run under another OS (some Linux distribution).

It depends on which style you are using. In general Qt specific themes (like fusion) can be easily customized simply by changing the palette (Note that different styles may use different palette roles).
However, for OS specific styles (like QWindowsVistaStyle), you simply cannot do it.
The reason is that the style implementation ignores the palette and use colors from the OS theme.
For instance if you look at the implementation at QWindowsXPStyle you will find calls to GetThemeColor() which returns the color from the OS.
These OS specific styles also cannot use stylesheets correctly, that's why if yo use a stylesheet, the widget will fallback to a default style.
I believe your only solution would be to use QProxyStyle, but you may have to rewrite the code to draw parts of widget you want to customize.

Related

C++ && QT Is there a way to create "warm screen" color using c++ and qt on Mac && Windows

Is there some way to change screen "saturation" ? Make screen in warm colors \ or make it in sepia using c++ && qt on win\mac ?
As a reference modern monitors have such a menu option on changing the screen color or you can also check the app for linux f.lux as a reference ...
The first thing that comes on my mind is to create some transparent " window on top " make a screenshot and play around with rgb ... but it will be not the best solution
There's no Qt API that will help you with that. On either platform you'll have to use native APIs to change the screen color reproduction curves and shift the color temperature to warmer tones. The situation on OS X would be more uniform in that the API to do that either exists on all hardware or on none. On Windows, things might be more complicated. Some undocumented vendor APIs probably exist, used by respective vendor control panels to alter the color temperature. There are also all ways you could hook yourself into the screen compositing pipeline, but this may require writing a driver. Unfortunately, I'm not too familiar with how easy it might be. It'll be probably either very simple or very complicated. There are some simple workarounds, like adding a translucent tinted window on top of everything, but those don't look good.
Neither C++ nor Qt facilitate such functionality. It seems for windows it is possible to modify brightness and contrast for the display, but that's about it, no saturation, no colorization.
The "make a screenshot and play around with rgb" will have abysmal performance and a number of other possible complications, such as event handling.
Now, if you want to apply a color filter to your Qt application, Qt has the QGraphicsEffect class, which automatically hooks up with the rendering system, caches the target to an image and applies to desired effect. I am not sure how well will that work for the "transparent window on top" idea.
It only has a few stock effects, but you can easily roll out your own. Then you can use QWidget::setGraphicsEffect(QGraphicsEffect * effect) to apply it to the desired widget or derived.

How to recognize that an application is running in dark theme on Linux?

I've developed an application which uses qscintilla as a text editor. I also implemented custom lexer to highlight language specific keywords. So far styles for highlighted keywords are hardcoded in mine application and it looks quite ok in the default theme on Windows/Linux(Ubuntu)/Mac.
The problems appears when user chooses a dark theme (on Linux). Depending on QScintilla version some parts of editor do reflect current theme colors while other don't. Moreover mine custom styles render dark blue letters on dark grey background.
I'm looking for some Qt class, which will allow me access of the current system theme. I do not want to define styles for mine application widgets.
I want to know what is system default non-proportional font, what is it's size, color, ... If I knew that dark scheme is used I would choose complementary colors for keyword highlighting.
I checked docs for QStyle, QPlatformTheme and other qt classes and it seems to me that these serve more for defining of new styles, then for describing the current style.
For the system colours, you can use the group/role of the QPalette class.
For the system fonts, you can create a QFont using e.g. "Serif", "Sans Serif", "Monospace", etc with an appropriate style hint to discover the defaults.
NB:
From the Qt Docs:
Warning: Some styles do not use the palette for all drawing, for
instance, if they make use of native theme engines. This is the case
for both the Windows Vista and the macOS styles.
Here is some python code using QPalette that works for me on Linux:
label = QLabel("am I in the dark?")
text_hsv_value = label.palette().color(QPalette.WindowText).value()
bg_hsv_value = label.palette().color(QPalette.Background).value()
dark_theme_found = text_hsv_value > bg_hsv_value

How to change button color?

I am developing a GUI application using Embarcadero VCL c++ IDE for windows OS. As part of this project, I have to change color of button with respect to an external state.
I understood that windows32 API will not allow to change the color of button.
Could you please suggest me, how to change button color?
Do you wish to change the background-colour of the button, or the text-colour of it?
Since windows has used visual themes for some time now, if you have commctrl loaded and include a manifest file, the button will be drawn using the default (current) theme.
Options I can see include (a) custom-drawing the background (b) changing the text-colour in the normal draw process (c) drawing the button without a theme (i.e drawing a 'flat' button).
You could simply draw a bitmap-button, changing the bitmap depending on the state of the button. You could also use a single bitmap, tinting it using the HSL or HSV colour-space, depending on the state.
As for the flat type of button, I think you can probably change it's background-colour in much the same way as you can change the colour of the text - by intervening during the standard draw process and changing the colour from 3D_FACE (or whatever it is, I forget) to whatever you'd like.
If you look at the calculator included with windows XP, you can see an example of changing the text colour.
CodeProject.com likely has a stack of articles that would help in this endeavour. :)

Creating widgets with C++/Obj-C?

I want to create a widget in Mac OS X that exists on the desktop background rather than the dashboard. The widget will be interactive (the widget will be able talk through text boxes when the user clicks on it, similar to Clippy) and I need it to be floating (always been on top of all windows). The widget should also be able to be flexible- by this I mean it can change shapes (i.e. how Clippy always moves). It should almost be like a character from a game on the desktop.
I have absolutely not idea how to do this, nor do I could I find any resources that instructed me how to.
Does anyone know how I could create an interactive widget on the desktop background on all major versions of Mac OS X (i.e. Snow Leopard, Lion) that floats using either C++ or Obj-C? (C++ is much more preferable)
Borderless Windows, and HUDs can be used to simulate a widget by creating a transparent, floating window.
For more info, refer to: How to create transparent notification window?

Win32: How can i set the color of windows Title, Scrollbar etc.?

I am updating a GUI of a Win32 Application in white text on black background. Thats simple for my content. But how can i change also the color of my child windows (Titlebar, Scrollbar etc.). i Know there is WM_CTLCOLORDLG to set the color of Dialogs. I also know there is WM_NCPAINT, but that would leave all painting (i.e of Scrollbars) to me. All i want, is to set colors of my choice.
You can use SetSysColors() to change the colour for window captions, borders, etc. (see http://msdn.microsoft.com/en-us/library/ms724940(VS.85).aspx). However this will change the colour for all windows, not just yours, so it is at the least an unfriendly thing to do.
One option is to use SetSysColors() to change the active window caption colour when your application has focus and to reset it to the defaults when it loses focus. But I'd say that's klunky and not really in keeping with good practice (suppose your application crashes? and there might be some flickering).
WM_NCPAINT is there so that you can do things like this. It is a bit of a pain, but maybe that's to discourage you from creating non-standard windows... ;-)
Hook GetSysColor() (Using something like Microsoft Detours)