Recent

Author Topic: QButton: A Fully customizable Button  (Read 634 times)

Ed78z

  • Jr. Member
  • **
  • Posts: 65
QButton: A Fully customizable Button
« on: August 02, 2026, 06:14:54 pm »
I'd just like to share my QButton component! It's very powerful and flexible.

It can act as a normal button, a toggle button, a counter button, or a modal button. You can fully control its shape, colors, multiline text, and icon (TBitmap or TImageList).
 
Feel free to use it and share your feedback!

Demo:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, QButton;
  9.  
  10. type
  11.   { TForm1 }
  12.   TForm1 = class(TForm)
  13.     procedure FormCreate(Sender: TObject);
  14.   private
  15.     BtnPrimary: TQButton;
  16.     BtnOutline: TQButton;
  17.     BtnDisabled: TQButton;
  18.     BtnToggleA: TQButton;
  19.     BtnToggleB: TQButton;
  20.     BtnToggleC: TQButton;
  21.     BtnToggleD: TQButton;
  22.     BtnRepeat: TQButton;
  23.     BtnModal: TQButton;
  24.  
  25.     FCounter: Integer; //  Clicks counter
  26.  
  27.     procedure BtnPrimaryClick(Sender: TObject);
  28.     procedure BtnRepeatClick(Sender: TObject);
  29.   public
  30.  
  31.   end;
  32.  
  33. var
  34.   Form1: TForm1;
  35.  
  36. implementation
  37.  
  38. {$R *.lfm}
  39.  
  40. { TForm1 }
  41.  
  42. procedure TForm1.FormCreate(Sender: TObject);
  43. begin
  44.   Self.Width := 450;
  45.   Self.Height := 250;
  46.  
  47.   BtnPrimary := TQButton.Create(Self);
  48.   BtnPrimary.Parent := Self;
  49.   BtnPrimary.SetBounds(20, 20, 120, 50);
  50.   BtnPrimary.Caption := 'Save File'#13#10'💾';
  51.   BtnPrimary.Color := $00FCFCFC;
  52.   BtnPrimary.BorderColor := $00CCCCCC;
  53.   BtnPrimary.BorderWidth := 1;
  54.   BtnPrimary.RoundCorners := True;
  55.   BtnPrimary.CornerRadius := 15;
  56.   BtnPrimary.Font.Color := clBlack;
  57.   BtnPrimary.Font.Style := [];
  58.   BtnPrimary.UseHoverColor := True;
  59.   BtnPrimary.HoverColor := $00FEE0BD;
  60.   BtnPrimary.PressedColor := clHighlight;
  61.   BtnPrimary.OnClick := @BtnPrimaryClick;
  62.  
  63.  
  64.   BtnOutline := TQButton.Create(Self);
  65.   BtnOutline.Parent := Self;
  66.   BtnOutline.SetBounds(160, 20, 120, 50);
  67.   BtnOutline.Caption := 'Delete'#13#10'🗑️';
  68.   BtnOutline.Color := clWhite;
  69.   BtnOutline.Font.Color := clMaroon;
  70.   BtnOutline.Font.Style := [fsBold];
  71.   BtnOutline.RoundCorners := False; // Square corners
  72.   BtnOutline.BorderColor := clBlue;
  73.   BtnOutline.BorderWidth := 5;
  74.   BtnOutline.HoverColor := clRed;
  75.  
  76.   BtnDisabled := TQButton.Create(Self);
  77.   BtnDisabled.Parent := Self;
  78.   BtnDisabled.SetBounds(300, 20, 120, 50);
  79.   BtnDisabled.Caption := 'No Access'#13#10'🚫';
  80.   BtnDisabled.CornerRadius := Width;//Ellipse
  81.   BtnDisabled.Enabled := False;
  82.  
  83.   //Groupped Toggle Button A
  84.   BtnToggleA := TQButton.Create(Self);
  85.   BtnToggleA.Parent := Self;
  86.   BtnToggleA.SetBounds(20, 90, 120, 50);
  87.   BtnToggleA.Caption := 'Mode A'#13#10'🔘';
  88.   BtnToggleA.Color := clAqua;
  89.   BtnToggleA.DownColor := clTeal;
  90.   BtnToggleA.Font.Color := clBlack;
  91.   BtnToggleA.Toggleable := True;
  92.   BtnToggleA.GroupIndex := 1;
  93.   BtnToggleA.Down := True;
  94.  
  95.   //Groupped Toggle Button B
  96.   BtnToggleB := TQButton.Create(Self);
  97.   BtnToggleB.Parent := Self;
  98.   BtnToggleB.SetBounds(160, 90, 120, 50);
  99.   BtnToggleB.Caption := 'Mode B'#13#10'⭕';
  100.   BtnToggleB.Color := clAqua;
  101.   BtnToggleB.DownColor := clTeal;
  102.   BtnToggleB.Font.Color := clBlack;
  103.   BtnToggleB.Toggleable := True;
  104.   BtnToggleB.GroupIndex := 1;
  105.  
  106.   //Groupped Toggle Button C
  107.   BtnToggleC := TQButton.Create(Self);
  108.   BtnToggleC.Parent := Self;
  109.   BtnToggleC.SetBounds(45, 150, 70, 70);
  110.   BtnToggleC.Caption := 'Mode C'#13#10'✔️';
  111.   BtnToggleC.Color := clAqua;
  112.   BtnToggleC.CornerRadius:=BtnToggleC.Width;
  113.   BtnToggleC.DownColor := clTeal;
  114.   BtnToggleC.Font.Color := clBlack;
  115.   BtnToggleC.Toggleable := True;
  116.   BtnToggleC.GroupIndex := 1;
  117.  
  118.   //Groupped Toggle Button D
  119.   BtnToggleD := TQButton.Create(Self);
  120.   BtnToggleD.Parent := Self;
  121.   BtnToggleD.SetBounds(160, 160, 120, 50);
  122.   BtnToggleD.Caption := 'Mode D'#13#10'✖️';
  123.   BtnToggleD.Color := clAqua;
  124.   BtnToggleD.DownColor := clTeal;
  125.   BtnToggleD.Font.Color := clBlack;
  126.   BtnToggleD.Toggleable := True;
  127.   BtnToggleD.GroupIndex := 1;
  128.  
  129.   //Continuous Repeat Button
  130.   BtnRepeat := TQButton.Create(Self);
  131.   BtnRepeat.Parent := Self;
  132.   BtnRepeat.SetBounds(300, 90, 120, 50);
  133.   FCounter := 0;
  134.   BtnRepeat.Caption := 'Hold Me!'#13#10'Count: 0';
  135.   BtnRepeat.Color := clFuchsia;
  136.   BtnRepeat.Font.Color := clWhite;
  137.   BtnRepeat.RepeatClick := True;
  138.   BtnRepeat.RepeatInterval := 150;
  139.   BtnRepeat.OnClick := @BtnRepeatClick;
  140.  
  141.   //Modal Feature Button (Auto-closes the form)
  142.   BtnModal := TQButton.Create(Self);
  143.   BtnModal.Parent := Self;
  144.   BtnModal.SetBounds(300, 160, 120, 50);
  145.   BtnModal.Caption := 'Close Form'#13#10'(mrCancel)';
  146.   BtnModal.Color := clRed;
  147.   BtnModal.Font.Color := clWhite;
  148.   BtnModal.Font.Style := [fsBold];
  149.   BtnModal.CornerRadius := 10;
  150.   // Automatically acts as a cancel button and closes the form! No OnClick needed.
  151.   BtnModal.ModalResult := mrCancel;
  152.  
  153. end;
  154.  
  155. procedure TForm1.BtnPrimaryClick(Sender: TObject);
  156. begin
  157.   ShowMessage('Primary Action Executed!');
  158. end;
  159.  
  160. procedure TForm1.BtnRepeatClick(Sender: TObject);
  161. begin
  162.   Inc(FCounter);
  163.   BtnRepeat.Caption := 'Hold Me!'#13#10'Count: ' + IntToStr(FCounter);
  164. end;
  165.  
  166. end.

Xenno

  • Full Member
  • ***
  • Posts: 163
    • BS Programs
Re: QButton: A Fully customizable Button
« Reply #1 on: August 03, 2026, 05:25:30 am »
Keep going!
Lazarus 4.6, Windows 10, https://www.youtube.com/@bsprograms
If I want to share, I give. If I want money, I sell. I don't set traps.

dbannon

  • Hero Member
  • *****
  • Posts: 3882
    • tomboy-ng, a rewrite of the classic Tomboy
Re: QButton: A Fully customizable Button
« Reply #2 on: August 03, 2026, 02:33:12 pm »
Hmm, no license ?   Lots of people will not be able to use it unless you stamp a license. I suggest the MIT License ...

Can you make the button follow the theme that all the other buttons in a project use ?

Anyway, great idea !  Thanks
Lazarus 4, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

Ed78z

  • Jr. Member
  • **
  • Posts: 65
Re: QButton: A Fully customizable Button
« Reply #3 on: August 03, 2026, 03:32:50 pm »
Keep going!

Thank you Xenno, here is my QToggleSwitch component, please check it too! :)

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Buttons, QToggleSwitch;
  9.  
  10. type
  11.   { TForm1 }
  12.  
  13.   TForm1 = class(TForm)
  14.     procedure FormCreate(Sender: TObject);
  15.   private
  16.     FToggle1: TQToggleSwitch;
  17.     FToggle2: TQToggleSwitch;
  18.     FToggle3: TQToggleSwitch;
  19.     FToggle4: TQToggleSwitch;
  20.     FToggle5: TQToggleSwitch;
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. { TForm1 }
  33.  
  34. procedure TForm1.FormCreate(Sender: TObject);
  35. begin
  36.   // 1. On / Off Switch
  37.   FToggle1 := TQToggleSwitch.Create(Self);
  38.   FToggle1.Parent := Self;
  39.   FToggle1.SetBounds(40, 20, 80, 26);
  40.   FToggle1.State := True;
  41.   FToggle1.TextOn := 'On';
  42.   FToggle1.TextOff := 'Off';
  43.   FToggle1.BodyColorOn := $00D77800;
  44.   FToggle1.BodyColorOff := $00EAEAEA;
  45.   FToggle1.Font.Style := [fsBold];
  46.  
  47.   // 2. Yes / No Switch
  48.   FToggle2 := TQToggleSwitch.Create(Self);
  49.   FToggle2.Parent := Self;
  50.   FToggle2.SetBounds(40, 60, 80, 26);
  51.   FToggle2.State := False;
  52.   FToggle2.TextOn := 'Yes';
  53.   FToggle2.TextOff := 'No';
  54.   FToggle2.BodyColorOn := $0047A532;
  55.   FToggle2.BodyColorOff := $004A4A9C;
  56.   FToggle2.KnobColorOff := clWhite;
  57.   FToggle2.Font.Style := [fsBold];
  58.  
  59.   // 3. True / False Switch
  60.   FToggle3 := TQToggleSwitch.Create(Self);
  61.   FToggle3.Parent := Self;
  62.   FToggle3.SetBounds(40, 100, 100, 26);
  63.   FToggle3.State := True;
  64.   FToggle3.TextOn := 'True';
  65.   FToggle3.TextOff := 'False';
  66.   FToggle3.BodyColorOn := $00B300B3;
  67.   FToggle3.BodyColorOff := $00EAEAEA;
  68.   FToggle3.Font.Style := [fsBold];
  69.  
  70.   // 4. Wifi / Lan Switch
  71.   FToggle4 := TQToggleSwitch.Create(Self);
  72.   FToggle4.Parent := Self;
  73.   FToggle4.SetBounds(40, 140, 90, 26);
  74.   FToggle4.State := False;
  75.   FToggle4.TextOn := 'Wifi';
  76.   FToggle4.TextOff := 'Lan';
  77.   FToggle4.BodyColorOn := $0000A5FF;
  78.   FToggle4.BodyColorOff := $00808000;
  79.   FToggle4.KnobColorOff := clWhite;
  80.   FToggle4.Font.Style := [fsBold];
  81.  
  82.   // 5. Like / Dislike Switch
  83.   FToggle5 := TQToggleSwitch.Create(Self);
  84.   FToggle5.Parent := Self;
  85.   FToggle5.SetBounds(40, 180, 70, 15);
  86.   FToggle5.State := True;
  87.   FToggle5.TextOn := 'Like';
  88.   FToggle5.TextOff := 'Dislike';
  89.   FToggle5.BodyColorOn := $005C5CFF;
  90.   FToggle5.BodyColorOff := $00EAEAEA;
  91.   FToggle5.KnobColorOn:=clGreen;
  92.   FToggle5.KnobColorOff:=clBlack;
  93.   FToggle5.Font.Style := [fsBold];
  94.   //FToggle5.Enabled:=False;
  95. end;
  96.  
  97. end.
  98.  
« Last Edit: August 03, 2026, 03:48:12 pm by Ed78z »

Ed78z

  • Jr. Member
  • **
  • Posts: 65
Re: QButton: A Fully customizable Button
« Reply #4 on: August 03, 2026, 03:37:19 pm »
Hmm, no license ?   Lots of people will not be able to use it unless you stamp a license. I suggest the MIT License ...

Can you make the button follow the theme that all the other buttons in a project use ?

Anyway, great idea !  Thanks

Thank you dbannon,
My components are completely FREE to use. I'm just sharing them without any restriction and fully FREE.

Regarding to apply theme: It's easy, I've done it in my DWEdit component, just add QTheme unit to your project and wire the colors to the QTheme...
https://forum.lazarus.freepascal.org/index.php/topic,71946.15.html

cdbc

  • Hero Member
  • *****
  • Posts: 2931
    • http://www.cdbc.dk
Re: QButton: A Fully customizable Button
« Reply #5 on: August 03, 2026, 04:07:21 pm »
Hi
Quote
My components are completely FREE to use. I'm just sharing them without any restriction and fully FREE.
Then you Copyright them and stamp them with: "For Public Domain, Use at your own risk.", as a bare minimum...  ;D
(Just like SQLite3)
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

Ed78z

  • Jr. Member
  • **
  • Posts: 65
Re: QButton: A Fully customizable Button
« Reply #6 on: August 03, 2026, 04:48:41 pm »
Hi
Quote
My components are completely FREE to use. I'm just sharing them without any restriction and fully FREE.
Then you Copyright them and stamp them with: "For Public Domain, Use at your own risk.", as a bare minimum...  ;D
(Just like SQLite3)
Regards Benny

Sure! I just added a license section to the QButton and QToggleSwitch components!

{
  This software is released into the public domain by Ed78z.

  It is completely free for anyone to use, modify, copy, or distribute for any purpose.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
  I ACCEPT NO RESPONSIBILITY OR LIABILITY FOR ANY DAMAGES ARISING FROM ITS USE.
}
« Last Edit: August 03, 2026, 04:59:12 pm by Ed78z »

dbannon

  • Hero Member
  • *****
  • Posts: 3882
    • tomboy-ng, a rewrite of the classic Tomboy
Re: QButton: A Fully customizable Button
« Reply #7 on: August 04, 2026, 03:10:10 am »
Thats great Ed, but, sadly, not acceptable to organizations like Debian for example. In fact many other 'big' organizations.

If you code is stamped (eg) MIT or LGPL then thats fine, everyone knows what that means. But if you write your own, no matter how simple, it has to be referred to a lawyer !  Crazy but true. In most cases, the cost of a lawyer looking at it and writing an opinion that its fine (as it almost certainty would be) is excessive. Sigh ...

First, we must hang all the lawyers ...

Davo
Lazarus 4, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

Ed78z

  • Jr. Member
  • **
  • Posts: 65
Re: QButton: A Fully customizable Button
« Reply #8 on: August 04, 2026, 06:54:37 am »
Thats great Ed, but, sadly, not acceptable to organizations like Debian for example. In fact many other 'big' organizations.

If you code is stamped (eg) MIT or LGPL then thats fine, everyone knows what that means. But if you write your own, no matter how simple, it has to be referred to a lawyer !  Crazy but true. In most cases, the cost of a lawyer looking at it and writing an opinion that its fine (as it almost certainty would be) is excessive. Sigh ...

First, we must hang all the lawyers ...

Davo


Is this ok?

{
  MIT License with Attribution Requirement

  Copyright (c) 2026 Ed78z

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  1. The above copyright notice (displaying "Ed78z") and this permission
     notice shall be included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
}

dbannon

  • Hero Member
  • *****
  • Posts: 3882
    • tomboy-ng, a rewrite of the classic Tomboy
Re: QButton: A Fully customizable Button
« Reply #9 on: August 04, 2026, 12:59:18 pm »
Brilliant !
So picky I know but sadly, true !
Davo
Lazarus 4, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

 

TinyPortal © 2005-2018