Lazarus

Programming => Widgetset => QT => Topic started by: dbannon on March 12, 2023, 05:53:21 am

Title: Qt colors
Post by: dbannon on March 12, 2023, 05:53:21 am
As I understand it Lazarus Apps use Lazarus default colours unless the user has somehow set something else. Doing so makes the app really flexible, especially for people who like dark themes, they can get a great result. A Qt app does not pickup system colours by default (sadly).

But if the user does "set something", see below, Qt LCL follows the set theme really well but some other, external, components do not. It would be easy to work around that or fix the component if we could just read what the colors in the chosen theme really are. I assume there is some qt library that reads the (eg) qt5ct theme and Qt widgets get their colours from there.

Does anyone know how to read colours from the selected theme ? 

More details ?
Starting a Qt app with either an env var set or a switch will instruct it what colour theme to use -
Code: Pascal  [Select][+][-]
  1. $> QT_QPA_PLATFORMTHEME=qt5ct ./my_qt5_app <enter>
  2.  
  3. $> ./my_qt5_app  -platformtheme  gtk2 <enter>

If you use qt5ct then it makes sense to set that var in either /etc/environment (requires root or, simpler in a .xsessionrc file in your home dir). Or use the switch for a one off test. In either case the value can be, eg qt5ct (if installed and configed) or gtk2.

qt5ct is really good but does require an extra package and a bit of configuring. Just setting gtk2 might be enough for most people but it does not always work. I just noticed that it does not work on Debian Bookwork at the moment. Sigh....

So, installing qt5ct seems safer ! It adds about 180k to your install. Make it a "recommended" attribute of a deb and it will be installed along with the other Qt libraries.  .

Davo

EDIT : added warning about value=gtk2 not always working.


Title: Re: Qt colors
Post by: zeljko on March 12, 2023, 09:58:20 am
You can read theme colors from QApplication_palette(), read docs about QPalette.
Also, you can create your own QPalette, set your colors and set it as application palette.
Title: Re: Qt colors
Post by: dbannon on March 12, 2023, 12:45:39 pm
Thanks Zelko, I did read the docs about QPalette and decided it would be easier to directly read qt5ct's config !  I am guessing thats how QPalette does it so its doubling up. But only a 100 lines of code and I am feeling lazy !

Thanks !

Davo

Edit - in the unlikely case of someone wanting to do what I needed to -
 https://github.com/tomboy-notes/tomboy-ng/blob/master/source/uqt_colors.pas

Title: Re: Qt colors
Post by: rca on March 12, 2023, 06:45:56 pm
... Just setting gtk2 might be enough for most people but it does not always work. I just noticed that it does not work on Debian Bookwork at the moment. Sigh....


@dbannon

I just tried a qt5 app on Debian 12 and it didn't work -platformtheme gtk2

I fixed it with:

First I checked that I have gtk2 platformtheme installed for qt5:
Code: Pascal  [Select][+][-]
  1. find /usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes -type f

Code: Pascal  [Select][+][-]
  1. /usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/libqgtk3.so


Only gtk3 appears, so I have to install the qt5-gtk2-platformtheme package.

Code: Pascal  [Select][+][-]
  1. sudo apt install qt5-gtk2-platformtheme

Code: Pascal  [Select][+][-]
  1. /usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/libqgtk2.so
  2. /usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/libqgtk3.so

And now it works
Code: Pascal  [Select][+][-]
  1. ./my_qt5_app  -platformtheme  gtk2 <enter>

But a Warning appears:
Code: Pascal  [Select][+][-]
  1. Failed to load module "canberra-gtk-module"

I solved it with:
Code: Pascal  [Select][+][-]
  1. sudo apt install libcanberra-gtk-module
Title: Re: Qt colors
Post by: dbannon on March 12, 2023, 11:34:49 pm
Thanks RCA, but thats not a good solution in packaging terms. If you put in that the package is dependent on qt5-gtk2-platformtheme then it will install all of gtk2 into a, say, pure Qt system. All 220Meg of it.

Debian is now treating dependency on GTK2 as a bug, not a critical one but  report-able one. My plan for my app now is to add a dependency on qt5ct, its only 180K. Only on the Qt version of course. Thats the one in Debian now....

As for Canberra, yes, that been the case for a long time, I have no idea why, my app at least does not use any of the canberra api, I guess another dependency is incorrectly dependent on it.

Davo
Title: Re: Qt colors
Post by: dbannon on February 16, 2024, 03:52:56 am
You can read theme colors from QApplication_palette(), read docs about QPalette.
Also, you can create your own QPalette, set your colors and set it as application palette.

Yep, that was good advice and I should have taken it way back then.

zeljko, I have something working fine with QPalette but don't understand whats happening with memory management. Simplified version of my code -

Code: Pascal  [Select][+][-]
  1. function GetWindowQTColor() : TColor;
  2. var
  3.   PaletteH : QPaletteH;
  4.   ABrush : QBrushH;
  5.   APQColor : PQColor;
  6. begin
  7.   PaletteH := QPalette_Create;          // https://doc.qt.io/qt-5/qpalette.html
  8.   QGuiApplication_palette(PaletteH);    // https://doc.qt.io/qt-5/qguiapplication.html
  9.   ABrush := QPalette_Window(PaletteH);
  10.   APQColor := QBrush_color(ABrush);
  11.   Result := RGBtoColor(APQColor^.r div 256, APQColor^.g div 256, APQColor^.b div 256);
  12. //  PaletteH.free;                      // NO, don't do this.
  13.   QPalette_destroy(PaletteH);  // zeljko says (below) do this and it works !
  14. end;          
 

I found  QGuiApplication_palette(PaletteH) must have PaletteH created (or I get a segV).  OK, said I, if I call create(), I must call .free(), nope, SegV again. So, it works as expected. But no memory leaks, I call QPalette_Create;  and do not free it. And if I call it multiple times, the memory consumption does not increase.

Is Qt doing some memory management below my line of sight ?                     

The above works perfectly, no memory leaks and returns the stuff I want. But I feel I am breaking an important rule !

Thoughts ?

Davo

EDIT: added scale to r, g and b values.  Added zeljko's suggestion on how to free PaletteH, all good now !
Title: Re: Qt colors
Post by: zeljko on February 16, 2024, 08:01:48 am
No, it does not. You must free it. Check with valgrind and you'll see.
Edit: Forgot to write : You must use QPalette_destroy(PaletteH);
Title: Re: Qt colors
Post by: dbannon on February 16, 2024, 10:08:10 am
Ah, thank you zeljko, yep, that works perfectly !  Don't think I would have guessed that !

Now my code works as expected. Beautiful. Works fine in Qt6 too. I will edit the source above in case someone else is interested.

Davo
TinyPortal © 2005-2018