QT界面优化

本文目录

前言:既然QT主要做客户端开发,那么一个程序的的界面好看是否重要呢,这就要取决你这个程序面对的用户是那些,如果是面向一些专业领域的人的程序,其实不是很重要,而是功能逻辑更加重要,如果面向的是普通用户,那么界面的美化是一个大大的加分项。"看脸世界"😭
我们对于QT界面的主要优化主要就是使用QSS,即样式,我们可以通过修改样式表,或者调用函数接口setstylesheet进行QSS的美化。QSS也是借鉴了CSS的美化,虽然没有CSS那么丰富,多样,但是足够支持我们使用了。

基本语法

QSS沿用了CSS的语法结构:

选择器

{

属性:属性值;

...

}

那么什么是选择器,选择器:*表示你选择某一个或者某一类控件,接下来进行对这些控件的各种属性设置,这里的属性包括有,北京属性,边框属性,字体属性,颜色属性,box属性,边距属性,位属性,文本属性,过滤选择器。

设置样式

例如:

cpp 复制代码
QPushButton
{
	color:red;
}
cpp 复制代码
    ui->setupUi(this);
    ui->pushButton->setStyleSheet("QPushButton{ color:red;}");
    ui->pushButton->setStyleSheet("QPushButton{ color:#ff0000;}");//使用rgb方式16进行之
    ui->pushButton->setStyleSheet("QPushButton{ color:rgb(255,0,255);}");//l另一种10进制方式

可以看到,使用代码的方式设置,我们是对某个组件调用它的setstylesheet进行设置,确定组件,设置样式,与其他组件互相"独立"。**那如果我们这里不是固定某个组件,而是一些组件,比如说主窗口呢?**😎

cpp 复制代码
this->setStyleSheet("QPushButton{ color:rgb(255,0,255);}");

此时我们运行就会返发现,凡是添加到主窗口的按钮组件,所有的样式都会是上述样式设置的结果。
除了以上这种方式,QSS还可以设置全局样式。

设置全局样式

相对于这里设置一下,哪里设置一下,全局样式的设置更为常用,更适合修改,增强代码内聚。全局样式的设置,是在主函数中的窗口对象设置的:

cpp 复制代码
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.setStyleSheet("QPushButton{ color:rgb(255,0,255);}");//全局设置按钮颜色
    w.show();
    return a.exec();
}

且对于全局样式,窗口样式,针对某一控件样式的设置,我的理解是这里就相当于函数重载--就近原则,全局函数调用优先级最低,下来是窗口的函数,在下来是特定的组件函数设置。全局设置是优先级最低的,接下来是对于一个窗口的全局设置,优先级最高的是指定的组件 .其次要分两种情况:
第一种情况是:有相同的属性被重复设置了不同的值,优先选取优先级高的属性设置。
第二种情况是:不同的属性分别在全局,一个窗口,指定组件上设置,属性是可以叠加。
简单举个例子:全局设置了按钮颜色,窗口也设置了按钮颜色,按钮最后也设置了颜色,最后选用按钮设置的颜色。
全局设置了按钮颜色,窗口也设置了按钮字体大小,按钮最后也设置了字体颜色,则最后的属性是三者叠加。
对于简单的QSS,我们直接就在代码里写了,但是对于复杂的QSS,我们为了更好的去排查,更好的修改,一般会放到一个文件中并添加到资源文件,程序启动时加载文件获取内容。

cpp 复制代码
QString loadQss()
{
    QFile file(":style.qss");
    file.open(QFile::ReadOnly);
    QString style=file.readAll();
    return s tyle;
}

除了该种方式还有更方便的办法,其实在Qt Designer中集成了这样的功能,当然这我们之前也用过,就是在designer中,右键有一个改变样式表 ,我们只需要以键值对的形式往里面添加属性+属性值;通过这种方式就内置的QSS美化组件。

所有的属性都可以在里面列出来,具体的某些属性我们可以参照CSS的属性以及属性值,当然上面也提供了一些,添加字体与颜色,添加资源的属性生成。

由于设置方式多种多样,开发中最好就选择一种方式进行样式设置,负责排查起来有点费劲。

选择器

什么是选择器

在QT中,选择器(或称为QSS选择器)是Qt Style Sheets(QSS)的一个重要组成部分,用于选择Qt应用程序中的UI元素并为其应用样式。这些选择器类似于CSS中的选择器,允许开发者根据特定的条件选择UI元素,并为其设置样式,以定制应用程序的外观和风格。
以下是QT中常见的一些选择器类型:
通配符选择器
匹配所有的控件,用星号()表示。例如: { background-color: yellow; }
也可以指明子类,注意和子类名之间有空格。例如: QPushButton { background-color: yellow; }
可以指明多个子类。例如:* QPushButton, QLabel { background-color: yellow; }
类型选择器
通过控件类型来匹配控件(包括子类)。例如:QWidget { background-color: yellow; }如果想防止子类(如窗口)被修改样式,可以设置相关属性,如setAttribute(Qt::WA_StyledBackground);类选择器也通过控件类型来匹配控件,但不同的是不包含子类。语法是在类前面加了个点(.)。如:.QWidget { background-color: yellow; }这些选择器使得开发者能够精确地定位到需要修改样式的UI元素,并为其设置相应的样式规则。通过QSS选择器,开发者可以轻松地修改Qt应用程序的外观,使其更符合用户需求或应用程序的设计风格。
总结来说,QT中的选择器是用于选择和定制Qt应用程序中UI元素样式的工具,它们提供了多种选择机制,如通配符选择器和类型选择器,以便开发者能够精确地应用样式规则。
ID 选择器 #pushButton_2 选择 objectName 为 pushButton_2 的控件.
了解这三种常用的即可。

子控件选择器

对于一些组件,他是有一些子控件组合而成的,比如说下拉框,微调框,旋钮,进度条等等,这些组件都会有自己的字控件,我们也可以通过搜索QT style sheet reference查阅官方文档,最上方的章节中最后一个章节就代表了哪些是哪些的子控件。

cpp 复制代码
    ui->comboBox->addItem("早上好");
    ui->comboBox->addItem("下午好");
    ui->comboBox->addItem("晚上好");
    //改变下拉图形
    ui->comboBox->setStyleSheet("QComboBox::down-arrow{ image:url(:/down.png);}");

伪类选择器

上述的选择器都是选择指定控件,而伪类是根据控件的状态进行选择。常用的伪类选择器如下:

伪类选择器 说明
:hove ⿏标放到控件上
:pressed ⿏标左键按下时
:focus 获取输⼊焦点时
:enabled 元素处于可⽤状态时
:checked 被勾选时
:read-only 元素为只读状态时

这些状态也可以通过!进行取反,伪类选择器的使用也可以根据官方文档Qt style sheet
refere 中的倒数第二个目录进行详细的查看。通过这种方式,我们都不需要使用事件或者信号槽实现。

cpp 复制代码
    QString style="QPushButton{background-color:red}";//默认情况背景下为红色
    style+="QPushButton:hover{background-color:green}";//鼠标放上去就是绿色
    style+="QPushButton:pressed{background-color:yellow}";//按钮按下就是黄色
    ui->pushButton->setStyleSheet(style);

盒子模型

当我们在翻阅手册时,去查看样式都有哪些组件,哪些属性时,我们常常会看到有些组件会说,support modle,这时什么意思呢:


盒子模型的关键就在这张图上,从上到下依次是外边距(margin),边框(Border),内边距(pandning),内容(content),

对于以上的属性,也可以通过QSS来进行设置。

QSS 属性说明
margin 设置四个⽅向的外边距复合属性.
padding 设置四个⽅向的内边距复合属性
border-style 设置边框样式
border-width 边框的粗细
border-colo 颜⾊
border 复合 相当于 border-style + border-width + border-color

magin的写法有多种,因为它有四个方向,如果是margin:10px,上下左右都是10px,如果是margin 10px 20px;代表上下10px,左右20px.如果是margin 10 px 10px 20px 30px代表上10px,右10 px,下20px,左30px。(顺时针方向)。padding同理,以标签为例:

cpp 复制代码
  QString style="QLabel{border:5px dashed red;}"; //修改边框为5px的宏实线
    //特可以设置为虚线dashed
    style+="QLabel { padding:5px 42px;}";//四个方向的内边距  使得文本在中间
    a.setStyleSheet(style);

基本属性

按钮

对于一个按钮,基本的属性设置如下:

cpp 复制代码
QPushButton
{
font-size:10px;
border-radius:10px;//圆角边框
background-color:red;
color:green;
}
QPushButton:pressed
{
   background-color:grb(100,0,255);
}

复选框

对于一个复选框,基本的属性设置如下:
indicator表示里面的按钮,unchecked表示复选框未选中状态,hover表示鼠标在上面的状态
其他相反。

cpp 复制代码
QCheckBox
{
  font-size:20px;
  color:"red";
  font-family:"仿宋";
}
QCheckBox::indicator
{
  width:20px;
  height:20px;
}
QCheckBox::indicator:unchecked
{
  image:url(:/checkbox.png);
}
QCheckBox::indicator:unchecked:hover
{
  image:url(:/checkbox (1).png);
}
QCheckBox::indicator:checked
{
  image:url(:/checkbox-checked (1).png);
}
QCheckBox::indicator:checked:hover
{
  image:url(:/checkbox-checked.png);
}

单选按钮

对于一个单选按钮,基本的属性设置如下:

cpp 复制代码
QWidget QRadioButton {
 font-size: 20px;
}
QWidget QRadioButton::indicator {
 width: 20px;
 height: 20px;
}
//单旋按钮里按钮未被选中时的图片
QWidget QRadioButton::indicator:unchecked {

 image: url(:/radio-unchecked.png);
}
//单旋按钮里按钮未被选中时鼠标在上面时的图片
QWidget QRadioButton::indicator:unchecked:hover {
 image: url(:/radio-unchecked_hover.png);
}
//单旋按钮里按钮未被选中时鼠标按压时的图片
QWidget QRadioButton::indicator:unchecked:pressed {
 image: url(:/radio-unchecked_pressed.png);
}
//单旋按钮里按钮被选中时的图片
QWidget QRadioButton::indicator:checked {
 image: url(:/radio-checked.png);
}//单旋按钮里按钮被选中时鼠标在上面时的图片
QWidget QRadioButton::indicator:checked:hover {
 image: url(:/radio-checked_hover.png);
}//单旋按钮里按钮被选中时鼠标点击时的图片
QWidget QRadioButton::indicator:checked:pressed {
 image: url(:/radio-checked_pressed.png);
}

编辑栏

对于一个编辑栏,基本的属性设置如下:

cpp 复制代码
QLineEdit {
 border-width: 1px; //边距
 border-radius: 10px; //圆角
 border-color: rgb(58, 58, 58);
 border-style: inset;//设置为内嵌式
 padding: 0 8px;//内边距
 color: rgb(255, 255, 255);
 background:rgb(100, 100, 100);
 selection-background-color: rgb(187, 187, 187);//选中后的背景色
 selection-color: rgb(60, 63, 65);//选中的字的颜色
}

线条的属性:

列表框

列表框的属性:

cpp 复制代码
//item表示子部件,也就是每一行(项)
QListView::item:hover {
 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
 stop: 0 #FAFBFE, stop: 1 #DCDEF1);
}
QListView::item:selected {
 border: 1px solid #6a6ea9;//分别表示width  实线 颜色
 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #6a6ea9, stop: 1 #888dd9);//渐变色
}
渐变色

这里的qlineargradient为渐变色属性,具体设置介绍如下图:

除了自己设置,QT在"改变样式表"中有一些定义好的渐变色,我们可以直接使用。

cpp 复制代码
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 255), stop:0.166 rgba(255, 255, 0, 255), stop:0.333 rgba(0, 255, 0, 255), stop:0.5 rgba(0, 255, 255, 255), stop:0.666 rgba(0, 0, 255, 255), stop:0.833 rgba(255, 0, 255, 255), stop:1 rgba(255, 0, 0, 255));

菜单栏

font face="仿宋">菜单栏的样式:

cpp 复制代码
QMenuBar{//菜单栏
background-color:rgb(127,115,159);
spacing:5px;
}
QMenuBar::item:selected{
background-color:rgb(0,120,0);
}
QMenuBar::item{//菜单栏的菜单项
border-radius:5px;
padding:3px 5px;
color:rgb(255,255,255);
}
QMenu::item:selected {  //菜单项被选中时
    background-color: rgb(216, 224, 255);
    border: 2px solid  "blue";
}
QMenu::separator {  //分隔线
    height: 1px;  
    margin-left: 10px;  
    margin-right: 10px;  
}

QMenu::indicator {  //菜单的菜单项
    width: 13px;  
    height: 13px;  
}  

假设我们来实现一个登陆界面,首先使用ui界面简单的构造出登陆界面,由于QWidget不支持直接在主窗口内设置背景图,因为我们需要将这些组件添加到QFrame,这也是一个窗口,且能设置形状大小等。如果想添加背景图,我们推荐使用border-image,他会跟就窗口的大小自动来填充。

绘图API

咱们以上了解到的所有控件都是画出来,QT基本上将常用的都提供好了,如果想自己实现比较特殊的控件,可以自己绘画一个出来,如下时绘画的常用接口。核心API:

QPainter "绘画者" 或者 "画家".⽤来绘图的对象, 提供了⼀系列 drawXXX ⽅法, 可以允许我们绘制各种图形.
QPaintDevice "画板".描述了 QPainter 把图形画到哪个对象上. 像咱们之前⽤过的 QWidget 也是⼀种 QPaintDevice (QWidget 是 QPaintDevice 的⼦类) .
QPen "画笔"描述了 QPainter 画出来的线是什么样的...
QBrush "画刷".描述了 QPainter 填充⼀个区域是什么样的.

画手

首先我们来看看画手pinter,这个类是绘画最重要的类,通过该类,我们可以画各种图形,参数一般是2个坐标或者1个坐标或者我们h之前就认识的QRect,这样就可以进行大小以及位置处的图行绘制。

cpp 复制代码
   QFont font;
    font.setPointSize(50);
    font.setFamily("华文行楷");
    painter.setFont(font);
    painter.setPen(pen);
    painter.drawLine(20,20,200,20);//画一个线段,参数分别表示起点,终点坐标
    painter.drawLine(QPoint(20,30),QPoint(200,30));//两点之间的线
    painter.drawRect(40,40,100,100);//会一个矩形,参数为rect  x,y,width,heght
    painter.drawEllipse(150,150,100,100);//x,y,宽度,高度  ,宽高一样就是圆,负责时椭圆
    painter.drawEllipse(0,150,100,50);
    painter.drawText(QPoint(200,130),"你好,世界");//绘制文字

画笔

在绘画前,我们可以给画手设置一根画笔,它的线条粗细,线条颜色,以及线条类型等等。
设置画笔颜⾊:QPen::QPen(const QColor &color) 画笔的颜⾊主要是通过 QColor 类设置;
设置画笔宽度:void QPen::setWidth(int width)
设置画笔⻛格:void QPen::setStyle(Qt::PenStyle style)。

cpp 复制代码
    //创建画笔对象
    QPen pen;
    pen.setColor(QColor(0,255,0));//设置画笔颜色
    pen.setWidth(5);//设置画笔宽度
    pen.setStyle(Qt::DotLine);
    painter.setPen(pen);

画刷

在 Qt 中,画刷是使⽤ QBrush类 来描述,画刷⼤多⽤于填充。QBrush定义了QPainter的填充模式,具有样式、颜⾊、渐变以及纹理等属性。
画刷的格式中定义了填充的样式,使⽤ Qt::BrushStyle 枚举,默认值是 Qt::NoBrush,也就是不进⾏任何填充。可以通过 Qt 助⼿查找画刷的格式。如下图⽰

cpp 复制代码
//创建画刷
    QBrush brush;
    brush.setColor(QColor(0,0,100));
    brush.setStyle(Qt::SolidPattern);//必须设置风格才显示,默认是啥都不填充的。
    painter.setBrush(brush);

绘制图片

Qt 提供了四个类来处理图像数据:QImage、QPixmap、QBitmap 和 QPicture,它们都是常⽤的绘图设备。
其中QImage 主要⽤来进⾏ I/O 处理,它对 I/O 处理操作进⾏了优化,⽽且可以⽤来直接访问和操作像素;
QPixmap 主要⽤来在屏幕上显⽰图像,它对在屏幕上显⽰图像进⾏了优化;
QBitmap 是 QPixmap 的⼦类,⽤来处理颜⾊深度为1的图像,即只能显⽰⿊⽩两种颜⾊;
QPicture ⽤来记录并重演 QPainter 命令。
我们这里看看 QPixmap。

cpp 复制代码
void Widget::paintEvent(QPaintEvent * event){
    //进行图片绘制
    QPainter painter(this);
    QPixmap pixmap(":/leidian.jpg");
    //图片的缩放可以使用pixmap内置的scald进行缩放,除此之外,用painter也能缩放
    //pixmap=pixmap.scaled(pixmap.width()/2,pixmap.height()/2, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    painter.drawPixmap(0,0,pixmap);//在初始位置0,0,处绘制
    painter.drawPixmap(0,0,400,300,pixmap);//在0,0,处绘制且大小为200,200,
}

其次,我们还可以会之前,先旋转,然后在绘制可以实现图片旋转:

cpp 复制代码
    painter.rotate(180);//在点(0,0)处旋转180度
    //因此需要进行平移到们屏幕上
    painter.translate(-500,-400);//项右向下移动
    painter.drawPixmap(0,0,400,300,pixmap);

结束语

看到这里QT的一些最基本常用的就介绍完了,但是QT要学的东西还没有完,例如3d动画,第三方库,QT quick,甚至QT design Studio ,Qt动画,QT数据库,感兴趣的小伙伴可以往更深的方向去学习。

相关推荐
是小崔啊8 分钟前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama14 分钟前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全17 分钟前
Java的基础概念(一)
java·开发语言·python
liwulin050617 分钟前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr
jackiendsc22 分钟前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
Oneforlove_twoforjob26 分钟前
【Java基础面试题027】Java的StringBuilder是怎么实现的?
java·开发语言
羚羊角uou29 分钟前
【C++】优先级队列以及仿函数
开发语言·c++
FeboReigns34 分钟前
C++简明教程(文章要求学过一点C语言)(1)
c语言·开发语言·c++
FeboReigns37 分钟前
C++简明教程(文章要求学过一点C语言)(2)
c语言·开发语言·c++
数据小小爬虫1 小时前
利用Java爬虫获取苏宁易购商品详情
java·开发语言·爬虫