【Delphi 】StyleControls组件 学习笔记

一.TscGPButton按钮

1.按钮外观基本上都在options里设置.

  Normal开头的属性: 按钮常态下的效果设置;

  HOT开头(或包含)的属性: 鼠标停在按钮上时的效果设置;

  Frame开头的属性: 边框设置;

  pressed开头(或包含)的属性: 与点击有关的效果设置;

  Font开头的属性: 字体效果设置;

  Disabled开头(或包含)的属性: 按钮失去焦点时的效果设置;

  Focused开头的属性:按钮获取焦点时的效果设置;

  带Alpha的属性: 与透明度有关,255为不透明,0为透明;

  shap开头的属性:设置按键的样式;

  

渐变设置:

 

 

如果按钮参与分组设置,需要设置ShapeStyle属性中的 scgpSegmentedLeft  /   scgpSegmentedRight   /  scgpSegmentedMiddle(可以有0个以上)

 

 

 

 

 

2.多个按钮设置了GroupIndex分组,则popupmenu属性无效.只能通过代码触发.另外,当按钮处于激活状态时,无法再次触发click指令.

3.如果设置了图标,spacing 可以设置图标与caption之间的距离.Layout可以设置图标展示的位置;

 4.badge属性可以做出角标效果

 

 

 

 

 

 

二.TscGPEdit文本输入框

1.设置好ButtonImages后,可同以时设置LeftButton和RightButton,可用对应的OnLeftClick和OnRightClick进行事件处理.

 

如果没有设置images,也可以设置LeftButton和RightButton属性下的Kind属性,使用系统自带的图标.

 

 2.如果嫌弃图标过大,可以设置以下几个属性.一般只设置 bottom 和 top 这两个属性.

 

 

 

3.同样的,大部分效果设置,都包含在了Options里.设置方法与按钮的设置方法大同小异

 

 

4.PrompTtext可以设置输入框的默认文本:

 

 5.自定义图标的方法如下:

1.设置TscGPEdit - ButtonImages关联图标集.

2.以RightButton为例,设置Kind属性为scgpebCustom

3.按需求,设置

 

 

 

三.TscPasswordEdit密码框

1.与TscGPEdit文本输入框差不多,但是它没有LeftButton和RightButton属性,有的只是PasswordBotton,它不能自定义图标.其效果是 : 临时把密文显示为明文,当鼠标左键弹起时,恢复密文状态

 

效果如图:


 2.其他设置请参考TscGPEdit文本框设置

四.TscStyledForm窗体UI类,不可见控件.作用是在标题栏上加一些按钮和tabs标签

重要声明:新项目默认是windows样式,这个样式是无法体现出TscStyledForm 效果的,要在选项里,更改为非windows样式才行(列表里随便勾几个你喜欢的)

 

 

 

1.ButtonImages设置图标集

ButtonFont设置字体

CaptionAlignment 设置标题栏 标题的对齐方式,如果使用默认的向左对齐,标题会紧随在按钮组或者标签组后面,很不美观.

 

2.show设置如图,这里说一下ShowStylesMenu,勾选后,当程序运行时,可以通过右键标题栏,展现 Style --> 皮肤列表 . 中给程序切换皮肤.如果你觉得不方便,请往下看第五点.

 

3.Buttons: 双击弹出按钮列表.所有的按钮增删与属性设置都在这里操作.如果要动态创建按钮,记得声明 var b1:TscNCButtonItem;

主要设置caption,position,imageIndex,spacing这几个属性.

如果你想设置按钮间的距离,可以设置

 

 效果如图:

一共设置了四个按钮,其中第一个设置了PopupMenu菜单,第四个设置了右对齐,无文本.


 

 

 4.Tabs: 和Buttoms一样,双击出现列表.所有的标签增删与属性设置都在这里操作.

tabsPosition : 标签的对齐方式.默认是靠左对齐.如果同时设置有按钮组,则按钮组在最左,标签组紧跟在按钮组后面出现

 

 

tab的属性设置非常简单:

如果有多个标签,可以设置统一的width性,不然会出现宽度不一致的情况

 

 

 

 

效果图:

 

 

动态创建标签:

 

 

var
  t1: TscNCTabItem;
begin
  t1 := scstyldfrm1.Tabs.Add;
  t1.Caption := 'Sheet' + IntToStr(scstyldfrm1.Tabs.Count);
  t1.Width := 60;
end;

5.接下来这个特效很酷:让父级窗体显示为毛玻璃透明模式(ShowModal模式下)

新建一个窗体form2,设置为可用窗体.

 

form1里加个按钮,加事件.

 

复制代码
uses unit2;
procedure
TForm1.btn4Click(Sender: TObject); begin form2 := TForm2.Create(self); scstyldfrm1.ShowClientInActiveEffect;    //这里是重点.要在窗体显示前,设置特效 Form2.ShowModal; scstyldfrm1.HideClientInActiveEffect;    //窗体显示后,隐藏特效
 Form2.free;
end;
复制代码

TscStyledForm中的 InActiveClienColor属性,用来设置特效颜色.

 

 

 效果如图:

 

 

 五.TscCombobox.做一个可以更改皮肤的下拉框.这个功能,用系统自带的控件就可以实现,不是非得要用第三方.

复制代码
uses Vcl.Themes;  //皮肤单元
procedure
TForm1.FormCreate(Sender: TObject); var i: Integer; begin for i := Low(TStyleManager.StyleNames) to High(TStyleManager.StyleNames) do    //TStyleManager样式管理器,不用声明.TStyleManager.StyleNames 返回一个皮肤数组. scGPComboBox1.ListBox.Add(TStyleManager.StyleNames[i]); end; procedure TForm1.scGPComboBox1Change(Sender: TObject); begin TStyleManager.TrySetStyle(scGPComboBox1.Items[scGPComboBox1.ItemIndex].Caption );    //TrySetStyle:设置皮肤 end;
复制代码

效果如图:

 

 

 六.TscGPPageControl

1.在TscGPPageControl 控件空白处右键,可新增和删除标签.也可以双击tabs属性,调出tab管理器进行设置.

2.切换页面 : scGPPageControl1.ActivePage := 直接写页面Name;

3.TscGPPageControl全局设置,大部分在TabOption里进行,还有很多个性化的设置,你可以慢慢去摸索.这里有个技巧:

先确定你需要的样式是全局的属性,还是标签里的属性,如果是全局,就找tabOption,标签就找tabs -> page

4.如何隐藏TscGPPageControl控件的标签头?分两步来:

  1.设置FrameWidth为0

 

 

  2.设置TabHeight为0.完成!

 

 

3.动态创建标签(基于Frame)

在此之前,请先了解一下Frame的Create原理  后半部分

先看运行图:

 

 主窗体设计图:

 

Frame设计图:

 

 

 下面是Frame的代码:

复制代码
unit Unit6;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, scControls, scGPControls;

type
  TFrame6 = class(TFrame)
    scGPPanel1: TscGPPanel;
    Button1: TButton;
  private
    { Private declarations }
  public
    constructor Create(AOwner: TComponent); override;    //上面链接有介绍Frame的Create原理  
  end;

implementation

{$R *.dfm}
uses
  Unit5;    //引用主窗体

constructor TFrame6.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);    //上面链接有介绍Frame的Create原理  
  Self.Align := alClient;     //如果没有这一句,frame嵌进去之后,会保持原有大小.
  Button1.Caption := 'Frame' + inttostr(Length(ArrayFrames) + 1);   //修改Btn属性
end;

end.
复制代码

主窗体的代码:

复制代码
unit Unit5;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, scControls, scGPPagers, Unit6, cxGraphics, cxControls,
  cxLookAndFeels, cxLookAndFeelPainters, cxStyles, cxEdit, cxInplaceContainer,
  cxVGrid, cxOI;
type TArrayFrames = array of TFrame; //设置动态数组的数据类型 TForm5 = class(TForm) scGPPageControl1: TscGPPageControl; sheet1: TscGPPageControlPage; Button1: TButton; Memo1: TMemo; Frame61: TFrame6; Label1: TLabel; procedure Button1Click(Sender: TObject); procedure scGPPageControl1Close(Sender: TObject; var CanClose: Boolean); procedure FormCreate(Sender: TObject); procedure DeleteArrItem(var arr: TArrayFrames; Index: Integer); private { Private declarations } public end; var Form5: TForm5; ArrayFrames: TArrayFrames; //全局数组 implementation {$R *.dfm} //创建新标签 procedure TForm5.Button1Click(Sender: TObject); var NewTap: TscGPPageControlTab; NewFrame: TFrame6; begin with scGPPageControl1 do begin NewTap := Tabs.Add; //新增标签 NewTap.Caption := 'sheet' + Tabs.Count.ToString; //设置标签名称 NewFrame := TFrame6.Create(scGPPageControl1); //设置Frame名称,这里一定要写,因为它每次新增都默认是Frame的Name, 会报错 NewFrame.Name := 'Frame' + IntToStr(NewFrame.Handle); NewFrame.Parent := NewTap.Page; //把frame嵌进标签里 //把 NewFrame记录进数组里,当关闭标签时,从数组里取出,并free .数组的Index值与标签的index值相同 SetLength(ArrayFrames, Length(ArrayFrames) + 1); ArrayFrames[Length(ArrayFrames) + 1] := NewFrame; //监测数组 Memo1.Lines.Add('ArrayFrames增加:' + Length(ArrayFrames).ToString); end; end; procedure TForm5.DeleteArrItem(var arr: TArrayFrames; Index: Integer); var len: Integer; tempFrame: TFrame; begin len := Length(arr); //不用考虑 Index =1 ,因为不能删除 if Index = len then begin SetLength(arr, len - 1); Exit; end; //其它情况 tempFrame := arr[Index - 1]; tempFrame.Free; //把将要删除的元素移到最后,然后重新设置它的长度,以实现删除的目的 //关于Move与sizeOf请看下面聊天记录 Move(arr[Index + 1], arr[Index], (len - Index) * SizeOf(arr[0])); SetLength(arr, len - 1); end; procedure TForm5.FormCreate(Sender: TObject); begin setLength(ArrayFrames, 1); //自带一个主页且不能删除 ArrayFrames[0] := Frame61; //把主页加进数组 end; //标签的关闭事件 procedure TForm5.scGPPageControl1Close(Sender: TObject; var CanClose: Boolean); var i, j: integer; begin CanClose := False; //设置成False才能删除 with scGPPageControl1 do begin i := GetPageIndex(ActivePage); //删除元素半释放free DeleteArrItem(ArrayFrames, i + 1); //监测数组 Memo1.Lines.Add('ArrayFrames删除:' + Length(ArrayFrames).ToString); tabs.Delete(i); //删除标签 FindPriorTab; //激活上一个标签 end; end; end.
复制代码

 

关于move函数与sizeOf函数,感谢群里大佬的指点:

 

 

posted @   一曲轻扬  阅读(2992)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示