Qt|制作简单的不规则窗体

通常我们用到的对话框基本上都是规则的,在有些特殊情况下,也会使用到不规则窗口,那么该如何实现不规则窗体呢?

在MFC框架下很难实现,应该说是难的都想放弃,但是,Qt框架下提供了一个叫做setMask()函数,用来实现不规则窗体,为窗体设置遮罩。

在今天的功能介绍中,主要是围绕如何setMask()函数进行讲解的。首先,我们看一下实现出来的效果吧!

功能:点击鼠标左键拖动窗口进行移动,鼠标右键销毁当前窗口。

用到的事件:鼠标按下事件、鼠标拖动事件、绘图事件

具体的功能操作如下:

功能层创建

新建一个Qt Widgets Application工程,基类为:QWidget,工程名字随意就行。

事件处理

为了让不规则窗口能够通过鼠标进行随意拖动,此时需要重写鼠标事件以及绘图事件。

按下事件:mousePressEvent

cpp 复制代码
void QtIrregularWidget::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton)
	{
		m_ptDragPosition = event->globalPos() - this->frameGeometry().topLeft();
		event->accept();
	}
	if (event->button() == Qt::RightButton)
	{
		close();
	}
}

代码解析:

在鼠标按下事件中根据左键和右键不同响应分为了两个功能。

就拿简单的右键响应来说,触发了鼠标右键事件后,直接退出程序。

鼠标左键触发,此时,需要保存当前鼠标点所在的位置相对于窗体左上角的偏移值。使用成员变量m_ptDragPostion。

event->globalPos():获取的鼠标位置是鼠标偏离电脑屏幕左上角(x=0, y=0)的位置。

frameGeometry()->topLeft():获取包括了标题栏客户区的左上角的点位置

在这里,就有一个小疑点,geometry()与frameGeometry()究竟有什么区别呢?

geometry()获取的区域不包括标题栏和边框区域的,而frameGeometry()是包括标题栏和边框的,也就是窗口真正的区域

移动事件:mouseMoveEvent

cpp 复制代码
void QtIrregularWidget::mouseMoveEvent(QMouseEvent *event)
{
	if (event->buttons() & Qt::LeftButton)
	{
		move(event->globalPos() - m_ptDragPosition);
	}
}

代码解析:

当鼠标左键处于按下状态,且触发了mouseMoveEvent事件后,此时才会产生窗口移动效果。

移动的位置也就是由实时获取的电脑屏幕区域,减去鼠标按下时获取的最初位置。

绘图事件:paintEvent

因为添加的是不规则图片,所以,在paintEvent中需要将图片绘制到窗口中,这个没有难度。

cpp 复制代码
void QtIrregularWidget::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	painter.drawPixmap(0, 0, QPixmap(":/QtIrregularWidget/image/kcfl_n.png"));
}

不规则处理

在文章开篇就说道,设置Qt框架中不规则窗体需要用到:QWidget::setMask()函数。

所谓的不规则就是为窗口设置遮罩,遮住所选区域以外的部分使其看起来是透明的,如果选择一个png图片,该图片的透明部分就是一个遮罩。

QWidget::setMask参数可以是一个QBitmap对象或者是QRegion对象,此时,只有QPixmap::mask()可以获取图片的遮罩信息,所以,在这里,参数传入的是一个QBitmap对象。

那么,实际的处理如下代码所示:

cpp 复制代码
QString qsPicturePath = ":/QtIrregularWidget/image/kcfl_n.png";

QPixmap pix;
pix.load(qsPicturePath, 0, Qt::AvoidDither | Qt::ThresholdAlphaDither | Qt::ThresholdDither);
resize(pix.size());

setMask(QBitmap(pix.mask()));

代码解析:

使用QPixmap的方式加载需要展示不规则背景图,重点是load后面的第三个参数。

参数1:图片的路径

参数2:读取图片文件的格式,一般采取默认值0

参数3:读取图片的方式。

Qt::AvoidDither:(当打算保存为文件而转化时的默认项) -- 只有在图像超过256色并且它将被转化为8位时,抖动32位图像。

Qt::ThresholdAlphaDither:(默认)- 没有抖动。因为有可能填入的图片带有透明通道,所以该属性有必要存在。

Qt::ThresholdDither:没有抖动;最靠近的颜色将被使用。

根据当前加载的背景图的大小,设置窗口的整体区域,最后设置不规则方法。

到这里,一个简单的,可拖动的不规则窗口就已经实现了。

我是糯诺诺米团,一名C++开发程序媛~

相关推荐
czq_26867194871 天前
Python打卡第46天
开发语言·python
宛 禾1 天前
Qt 事件系统完全指南:从事件循环到实战避坑
qt
Evand J1 天前
【MATLAB例程介绍】(17)永磁同步电机(PMSM)基于自适应无迹卡尔曼滤波(AUKF)的电流噪声在线估计。测量噪声协方差自适应与转速估计对比仿真
开发语言·matlab·卡尔曼滤波·无迹卡尔曼滤波·pmsm·电机滤波
BaiPeter1 天前
ZPL文件预览
开发语言·c++
噢,我明白了1 天前
JAVA中的一些基础应用知识点
java·开发语言
时间的拾荒人1 天前
Redis 入门详解:核心特性、重要文件与全局命令实战
开发语言·redis·面试
敲上瘾1 天前
Qt Widgets入门:项目模板解析与Hello World
开发语言·数据库·c++·qt·ui·qt6.3
码途行者1 天前
网站的SQL 注入:从攻击原理到防御措施
开发语言·sql·php
旖旎夜光2 天前
【C++ 基础入门】C++ 多态(中):虚函数表、多态原理与动静绑定
开发语言·c++·笔记·学习
你看我名字2 天前
产品参数昨天还对,今天已过期:数眼智能与大模型应用如何做资料版本校验
开发语言·架构