Recent

Author Topic: Embedded qss stylesheets & fonts, a quick little guide  (Read 1078 times)

jns

  • Newbie
  • Posts: 6
Embedded qss stylesheets & fonts, a quick little guide
« on: January 14, 2026, 12:43:03 am »
Hello pascal friends :)

I just figured I'd share my experiences so far getting embedded cross-platorm font resources and qss stylesheets to work - for any one looking to dig deeper into qt with Lazarus.

I posted this on my gopher site here: gopher://gopher.linkerror.com:70/1/pascal

You can view it over regular http via a proxy here: https://gopher.floodgap.com/gopher/gw?=gopher.linkerror.com+70+312f70617363616c

I happened the notice that the wiki pages on qt usage are rather outdated, with one page about qt4, another about qt5, but no mention of qt6 just yet - and I didn't see much in terms of basic instructions like these, such as common conventions to access underlying qt components of lcl widgets. Unless I looked in the wrong place :)

That said, I'm not even sure if creating such pages is even appropriate, as it's all a bit hacky - it would be nicer to have a formalized interface to load stylesheets instead.

As noted on the stylesheets page, at this time you even have to manually set control names, as the LCL implementation doesn't do so automatically - so this kind of thing is probably outside of the scope of what was intended usage.

I tried to include a basic mapping list between LCL widgets and Qt widgets -- it might not be 100% accurate, so let me know if there's corrections to be made!


cdbc

  • Hero Member
  • *****
  • Posts: 2600
    • http://www.cdbc.dk
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #1 on: January 14, 2026, 07:40:56 am »
Hi
The gopher-link is saying "No reverse proxy....", i.e.: It doesn't work!
Please upload the material here on this forum as something we can read...  :D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12634
  • FPC developer.
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #2 on: January 14, 2026, 10:34:57 am »
I'm not really a QT expert, but aren't QT and QTquick (the latter with stylesheet) two different things?

big_M

  • Full Member
  • ***
  • Posts: 102
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #3 on: January 14, 2026, 01:01:30 pm »
Wow, lots of very useful information here. Thanks!  :) Maybe this could be integrated into the wiki, or linked to it?

So far I'm using only external qss files, but since they can be embedded into the code, do you know if you can change the stylesheet on the fly? I have an idea for some effects, but for that I think I would have to switch between stylesheets.

Ah, and would you by any chance have a solution for my problem on my topic below? I'm looking for an alternative to a stylized speedbutton (some kind of a stylized toggle button with support for icons)

jns

  • Newbie
  • Posts: 6
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #4 on: January 14, 2026, 05:19:04 pm »
I'm not really a QT expert, but aren't QT and QTquick (the latter with stylesheet) two different things?

You are almost correct:

Qt is the widget library.
The widgets can be styled with stylesheets (QSS)
QtQuick is a scripting language that can be used in addition to, or in replacement of, the normal code, and it is distinctly separate from stylesheets.

You can combine QtQuick and Stylesheets, but you don't have to use QtQuick to use stylesheets.


jns

  • Newbie
  • Posts: 6
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #5 on: January 14, 2026, 05:36:40 pm »
Wow, lots of very useful information here. Thanks!  :) Maybe this could be integrated into the wiki, or linked to it?

Feel free to copy paste it there - I wasn't sure if it would be appropriate or not, since in the end it's all a bit obscure and hacky and doesn't particularly feel like an intended use case, which is why amidst my notes I am lamenting the lack of a more formal optional interface when using the qt widget set. (It would also be nice to have a built-in cross platform mechanism for loading fonts from memory). - Since the Qt calling interface might change as soon as the Qt version changes, and because it's code only specific to people using the Qt widget set, it's not particularly 'general' information applicable to all lazarus use.

So far I'm using only external qss files, but since they can be embedded into the code, do you know if you can change the stylesheet on the fly? I have an idea for some effects, but for that I think I would have to switch between stylesheets.

Yep, you can use the same code i used to load the stylesheet to change it on the fly.

The workflow is:

* Cast the LCL control to it's Qt equivalent (beware, not all /have/ a Qt equivalent)
* Once you have your control as TQtWidget (or the appropriate child class thereof, in my example I cast to a TQtMainWindow, but TQtWidget will work too) you can now call the .StyleSheet property and change it on the fly.

In my example I'm setting it on the main window, because you can automatically style all children from there in a single stylesheet, but you don't /have/ to do it that way either. Each control can also have it's own distinctly separate stylesheet.

Ah, and would you by any chance have a solution for my problem on my topic below? I'm looking for an alternative to a stylized speedbutton (some kind of a stylized toggle button with support for icons)

Right, the speedbutton control draws itself, rather than being rendered by Qt, so styling won't work here.
But you can get creative, I guess. Maybe you could just style a checkbox to make it look like a button with a background image ;)

Alternatively, use a regular button, give it a background image, and set it to 'checkable' using QAbstractButton_setCheckable https://doc.qt.io/qt-6/qabstractbutton.html#checkable-prop (I'm not sure if the pascal bindings exist by default, haven't checked, but if not, you can create them yourself like i did in the font loading example for QByteArray_Create/QByteArray_Destroy)


big_M

  • Full Member
  • ***
  • Posts: 102
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #6 on: January 14, 2026, 08:34:56 pm »
Yep, you can use the same code i used to load the stylesheet to change it on the fly.

The workflow is:

* Cast the LCL control to it's Qt equivalent (beware, not all /have/ a Qt equivalent)
* Once you have your control as TQtWidget (or the appropriate child class thereof, in my example I cast to a TQtMainWindow, but TQtWidget will work too) you can now call the .StyleSheet property and change it on the fly.

In my example I'm setting it on the main window, because you can automatically style all children from there in a single stylesheet, but you don't /have/ to do it that way either. Each control can also have it's own distinctly separate stylesheet.

Ah, very cool, I'm really excited to try this out! For some this might not be news, but unfortunately this stuff is very little documented.

Right, the speedbutton control draws itself, rather than being rendered by Qt, so styling won't work here.
But you can get creative, I guess. Maybe you could just style a checkbox to make it look like a button with a background image ;)

Alternatively, use a regular button, give it a background image, and set it to 'checkable' using QAbstractButton_setCheckable https://doc.qt.io/qt-6/qabstractbutton.html#checkable-prop (I'm not sure if the pascal bindings exist by default, haven't checked, but if not, you can create them yourself like i did in the font loading example for QByteArray_Create/QByteArray_Destroy)

Very good idea with the checkbox. Now that I know that I can use different stylesheets for specific controls, that opens up a lot of possibilities of course. :)

As you say, it's probably a bit hacky, but tbh, I feel the entire premise of the LCL to map different widget sets to it a bit hacky anyways. You always run into situations where something is either not supported by the WS or the LCL. One of the reasons I'm really looking forward to fresnel.

jns

  • Newbie
  • Posts: 6
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #7 on: January 14, 2026, 10:29:28 pm »
Now that I know that I can use different stylesheets for specific controls, that opens up a lot of possibilities of course. :)

Right, but as I also pointed out in my documentation, you don't even have to do that, as you can address specific controls by name from a single stylesheet, for example; say I want a standard style for all TEdit controls, but I want to override it for a specific TEdit control named 'FirstName', you could do:

Code: CSS  [Select][+][-]
  1. /* The default style for all TEdit controls */
  2. QTextEdit {
  3.   background: #333;
  4.   color: #639d74;
  5.   border-radius: 16;
  6. }
  7.  
  8. /* The overridden style for the FirstName control */
  9. QTextEdit#FirstName {
  10.   background: #fff;
  11.   color: #000;
  12. }
  13.  
  14.  

This will work, so long as QObject_setObjectName is called for the control - and as i mentioned in my documentation, you can name them all at once with a single function call in your main form. (SyncQtNames in the doc i wrote up).

Just be careful with the qss syntax, as 'QTextEdit#FirstName' (no space) means something completely different than 'QTextEdit #FirstName' (space in between):

* QTextEdit#FirstName = A QTextEdit control named 'FirstName'
* QTextEdit #FirstName = A control named 'FirstName' which is a child of any QTextEdit control


zeljko

  • Hero Member
  • *****
  • Posts: 1828
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #8 on: January 14, 2026, 10:48:03 pm »
Hello pascal friends :)

I just figured I'd share my experiences so far getting embedded cross-platorm font resources and qss stylesheets to work - for any one looking to dig deeper into qt with Lazarus.

I posted this on my gopher site here: gopher://gopher.linkerror.com:70/1/pascal

You can view it over regular http via a proxy here: https://gopher.floodgap.com/gopher/gw?=gopher.linkerror.com+70+312f70617363616c

I happened the notice that the wiki pages on qt usage are rather outdated, with one page about qt4, another about qt5, but no mention of qt6 just yet - and I didn't see much in terms of basic instructions like these, such as common conventions to access underlying qt components of lcl widgets. Unless I looked in the wrong place :)

That said, I'm not even sure if creating such pages is even appropriate, as it's all a bit hacky - it would be nicer to have a formalized interface to load stylesheets instead.

As noted on the stylesheets page, at this time you even have to manually set control names, as the LCL implementation doesn't do so automatically - so this kind of thing is probably outside of the scope of what was intended usage.

I tried to include a basic mapping list between LCL widgets and Qt widgets -- it might not be 100% accurate, so let me know if there's corrections to be made!

Note that: | TTreeView      | QTreeWidget     | Hierarchical tree structure.   | isn't quiet correct. TTreeView is TCustomControl (so QAbstractScrollArea basically). QTreeWidget is used only for TListView with ViewStyle = vsReport, other styles are QListWidget :) Thanks for sharing that info about qt and it's usage :)

jns

  • Newbie
  • Posts: 6
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #9 on: January 14, 2026, 11:27:39 pm »
Note that: | TTreeView      | QTreeWidget     | Hierarchical tree structure.   | isn't quiet correct. TTreeView is TCustomControl (so QAbstractScrollArea basically). QTreeWidget is used only for TListView with ViewStyle = vsReport, other styles are QListWidget :) Thanks for sharing that info about qt and it's usage :)

Thanks! Makes sense. I've updated the list. I figured I'd have a few mistakes like this as I haven't personally tested every single control type and made a few assumptions. :)

big_M

  • Full Member
  • ***
  • Posts: 102
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #10 on: January 15, 2026, 08:03:38 pm »
Right, but as I also pointed out in my documentation, you don't even have to do that, as you can address specific controls by name from a single stylesheet, for example; say I want a standard style for all TEdit controls, but I want to override it for a specific TEdit control named 'FirstName', you could do:

Code: CSS  [Select][+][-]
  1. /* The default style for all TEdit controls */
  2. QTextEdit {
  3.   background: #333;
  4.   color: #639d74;
  5.   border-radius: 16;
  6. }
  7.  
  8. /* The overridden style for the FirstName control */
  9. QTextEdit#FirstName {
  10.   background: #fff;
  11.   color: #000;
  12. }
  13.  


Hm, so I gave this a try. I placed a TCheckBox on a form, named "CheckBox1". On the FormCreate procedure I have put:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   ControlName: UnicodeString;
  4. begin
  5.   ControlName:= 'CheckBox1';
  6.   QObject_setObjectName(QObjectH(TQtWidget(CheckBox1.Handle).Widget), @ControlName);
  7. end;

Stylesheet:
Code: CSS  [Select][+][-]
  1. QCheckBox {
  2.     spacing: 5px;
  3.     outline: none;
  4.     color: #232627;
  5.     margin-bottom: 2px;
  6. }
  7.  
  8. QCheckBox#CheckBox1 {
  9.     border: 1px solid black;
  10. }

Stuff I put in QCheckBox works, but QCheckBox#CheckBox1 has no effect. Hm, did I forget something?

 

jns

  • Newbie
  • Posts: 6
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #11 on: January 15, 2026, 11:26:58 pm »
Hm, did I forget something?

It depends on when you're loading the stylesheet, as the order of operations is quite important.
Make sure controls are instantiated first, then you name the control, then you load the stylesheet.
If you load the stylesheet before naming the controls, it won't work.

I tried your example and it works for me (see attached image screenshot) - note how i set the names in the Loaded function, but the stylesheet is applied in the FormCreate event.

If you're unsure, set a break point when you start loading the stylesheet, and one when you set the name, and see which triggers the debugger first.

« Last Edit: January 15, 2026, 11:29:42 pm by jns »

big_M

  • Full Member
  • ***
  • Posts: 102
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #12 on: January 16, 2026, 12:52:34 am »
Oh, yes, that makes sense I guess. I did load the stylesheet first indeed. :)

zeljko

  • Hero Member
  • *****
  • Posts: 1828
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Embedded qss stylesheets & fonts, a quick little guide
« Reply #13 on: January 17, 2026, 09:05:42 am »
Right, but as I also pointed out in my documentation, you don't even have to do that, as you can address specific controls by name from a single stylesheet, for example; say I want a standard style for all TEdit controls, but I want to override it for a specific TEdit control named 'FirstName', you could do:

Code: CSS  [Select][+][-]
  1. /* The default style for all TEdit controls */
  2. QTextEdit {
  3.   background: #333;
  4.   color: #639d74;
  5.   border-radius: 16;
  6. }
  7.  
  8. /* The overridden style for the FirstName control */
  9. QTextEdit#FirstName {
  10.   background: #fff;
  11.   color: #000;
  12. }
  13.  


Hm, so I gave this a try. I placed a TCheckBox on a form, named "CheckBox1". On the FormCreate procedure I have put:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   ControlName: UnicodeString;
  4. begin
  5.   ControlName:= 'CheckBox1';
  6.   QObject_setObjectName(QObjectH(TQtWidget(CheckBox1.Handle).Widget), @ControlName);
  7. end;

Stylesheet:
Code: CSS  [Select][+][-]
  1. QCheckBox {
  2.     spacing: 5px;
  3.     outline: none;
  4.     color: #232627;
  5.     margin-bottom: 2px;
  6. }
  7.  
  8. QCheckBox#CheckBox1 {
  9.     border: 1px solid black;
  10. }

Stuff I put in QCheckBox works, but QCheckBox#CheckBox1 has no effect. Hm, did I forget something?

Qt don't know anything about LCL control name. I'm not sure that I've added QObject_setObjectName() when handle is created...maybe I did it, but check sources, or check any control eg QObject_objectName(QObjectH(TQtWidget(comboBox.Handle).Widget), @W) where W is WideString.

 

TinyPortal © 2005-2018