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++开发程序媛~

相关推荐
_.Switch几秒前
Python 自动化运维持续优化与性能调优
运维·开发语言·python·缓存·自动化·运维开发
徐*红几秒前
java 线程池
java·开发语言
尚学教辅学习资料1 分钟前
基于SSM的养老院管理系统+LW示例参考
java·开发语言·java毕设·养老院
小丑西瓜6662 分钟前
qt ui设计案例--登录界面
qt·ui·c/c++·qss
1 9 J3 分钟前
Java 上机实践4(类与对象)
java·开发语言·算法
Code apprenticeship4 分钟前
Java面试题(2)
java·开发语言
J不A秃V头A6 分钟前
Python爬虫:获取国家货币编码、货币名称
开发语言·爬虫·python
SRY122404193 小时前
javaSE面试题
java·开发语言·面试
无尽的大道3 小时前
Java 泛型详解:参数化类型的强大之处
java·开发语言
ZIM学编程3 小时前
Java基础Day-Sixteen
java·开发语言·windows