qtcanpool 知 04:主题之争

本文详细介绍了在Qt开发中通过图标调色、绘画样式表和自定义控件来美化界面的过程,展示了如何使用QPalette、QPainter和QSS实现个性化主题设置。

前言

作者在设定这个主题(标题)之后,就有点后悔了,因为作者也没有很丰富的主题经验之谈,唯恐介绍的流于表面,让读者读后收获甚微……

既然没有经验,那就现学现卖吧,多少之前还是有一些些使用经历的,不能做到高质量,至少可以做到归纳总结吧……

何谓主题?此主题非中心思想的意思,在Windows操作系统,“主题”一词特指Windows的视觉外观,别称有“皮肤、壁纸、样式”等。一个界面软件的主题,主要包括:窗口的外观、字体、颜色、图标等等。

那么Qt开发的界面软件,有哪些手段可以用来设置主题呢?这些不同的手段又有哪些利弊呢?这就是本章要讲的:主题之争。

争鸣

为什么我们要改变主题呢,原生的为什么满足不了我们?一个字:丑……
如何解决丑的问题,人类是怎么做的呢?穿衣搭配、健身塑型、梳妆化妆、照片PS、整容……

从人类美化自己的过程,粗略的得出美化界面的手段如下:
在这里插入图片描述
下面作者就通过一个简单的例子,来详细讲解这几种手段是如何美化界面的。

原生

功能描述:实现一个窗口类,其包含一个QToolButton,显示文本为“主题之争”。

由于功能简单,这里作者就采用Designer来设计:
在这里插入图片描述
效果如下:
在这里插入图片描述
备注:关于Designer和手写代码的区别,可以查看“设计器pk手码”章节。

这么一看,颜值确实有点普通,下面开始上美化手段。

图标

功能描述:给QToolButton添加按钮图标,给MainWindow换Logo。

新建资源文件resource.qrc,添加两个图标如下:
在这里插入图片描述
修改mainwindow.cpp如下:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
   
   
    ui->setupUi(this);

    ui->toolButton->setIcon(QIcon(":/main/button"));
    ui->toolButton->setIconSize(QSize(32, 32));
    ui->toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);

    setWindowIcon(QIcon(":/main/logo"));
}

效果图如下:
在这里插入图片描述
看破

  • 看:logo图标的路径明明是/main/resource/logo.png,为什么代码里面写:/main/logo就可以了。
    破:资源编辑界面最下面有Alias,即别名,这里采用别名,可以屏蔽路径的差异,随着图标越来越多,可能需要分目录存放,当你改变图标路径时,只要保证Prefix和Alias不变,就不需要改代码了。

添加图标,立马效果不一样了。最简单的美化就是加图标,图标的表意也可以更好的表达控件的功能。

图标只是点缀,控件本身的背景和文字颜色还是有点单调,如何调色呢?这就要说起QPalette了。

调色

QPalette是Qt的调色板,官方介绍如下:
在这里插入图片描述

  • 调色板由三个颜色组组成:活动,禁能和不活动。
    在这里插入图片描述

  • Qt中的所有widget都包含一个调色板,并使用其调色板进行绘制。这使用户界面易于配置并且更易于保持一致。

  • 如果创建新的widget,我们强烈建议您使用调色板中的颜色,而不是对特定颜色进行硬编码

  • 可以使用setColor()和setBrush()为调色板的任何颜色组中的特定角色设置颜色和画笔。
    在这里插入图片描述

  • 强烈建议您使用当前样式的默认调色板(由QGuiApplication :: palette()返回),并根据需要进行修改。这是由Qt的widget在绘制时完成的。

  • 要修改颜色组,请调用函数setColor()和setBrush(),具体取决于您要纯色还是像素图图案

ColorRole(颜色角色)示意图如下:
在这里插入图片描述
下面采用QPalette对主窗口和按钮进行配色。

功能描述:主窗口设置背景图片,按钮设置红底白字。

  1. 资源文件中增加背景图片
    在这里插入图片描述
  2. 修改mainwindow.cpp如下:
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
   
   
    ui->setupUi(this);

    ui->toolButton->setIcon(QIcon(":/main/button"));
    ui->toolButton->setIconSize(QSize(32, 32));
    ui->toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);

    QPalette palette = ui->toolButton->palette();
    palette.setColor(QPalette::Button, Qt::red);
    palette.setColor(QPalette::ButtonText, Qt::white);
    ui->toolButton->setPalette(palette);

    setWindowIcon(QIcon(":/main/logo"));

    palette = this->palette();
    palette.setBrush(QPalette::Window, QBrush(QPixmap(":/main/backgroud").scaled(this->width(), this->height())));
    this->setPalette(palette);
}

效果图如下:
在这里插入图片描述
看破

  • 看:为什么按钮背景色不是红色,而主窗口背景被改为图片了?
    破:点击QWidget::setPalette()看看官方如何介绍的:
    在这里插入图片描述
    背景色被用来填充控件的背景,请看QWidget::autoFillBackground
    在这里插入图片描述
    1)这个属性用来控制背景是否自动填充,默认是false
    2)对于Windows如果未设置后面两个属性,将永远填充。
    思考:莫非QMainWindow是Window,按钮不是Window?
    调试:查看二者的windowFlags(),如下所示,看来按钮确实不是Window。
    在这里插入图片描述

使能按钮的自动填充背景色属性,增加如下代码:

ui->toolButton->setAutoFillBackground(true);

效果如下:
在这里插入图片描述
看破

  • 看:按钮的背景为什么只有四周是红色,好像上面被什么遮挡了?
    破:具体原因作者也不是很明朗,在看到QPushButton的时候,QPushButton的isFlat()属性会影响其border的raise,于是寻找QToolButton有没有类似的属性,发现autoRaise属性如下:
    在这里插入图片描述
    使能这个属性,增加代码ui->toolButton->setAutoRaise(true);,测试效果如下:
    在这里插入图片描述
    从效果来看,基本是满足了要求,作者暂未发现别的解决方案……

小结

  1. 上面例子中使用的是QWidget::setPalette()设置widget的配色,实际上可以先通过QApplication::setPalette设置全局的配色,然后再局部调整widget的配色。
  2. 非Window的控件,设置背景色时,需要显示使能属性autoFillBackgroud。
  3. 按钮在设置背景色时,需要额外配置一些属性。

思考一下:调色板明明由三个颜色组组成,刚刚的例子似乎没感受到。

这是因为刚刚调用的palette接口,将三个颜色组设置成一样了,现在改造一下button的背景色为:活动时红色,不活动时绿色,禁能时蓝色,修改代码如下:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
   
   
    ui->setupUi(this);

    ui->toolButton->setIcon(QIcon(":/main/button"));
    ui->toolButton->setIconSize(QSize(32, 32));
    ui->toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    ui->toolButton->setAutoFillBackground(true);
    ui->toolButton->setAutoRaise(true);

    QPalette palette = ui->toolButton->palette();
    palette.setColor(QPalette::Active, QPalette::Button, Qt::red);
    palette.setColor(QPalette::Inactive, QPalette::Button, Qt::green);
    palette.setColor(QPalette::Disabled, QPalette::Button, Qt::blue);
    palette.setColor(QPalette::ButtonText, Qt::white);
    ui->toolButton->setPalette(palette);

    setWindowIcon(QIcon(":/main/logo"));

    palette = this->palette();
    palette.setBrush(QPalette::Window, QBrush(QPixmap(":/main/backgroud").scaled(this-</
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

canpool

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值