写点什么

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

  • 2022 年 9 月 23 日
    河北
  • 本文字数:1621 字

    阅读完需:约 5 分钟

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

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

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

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

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

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

具体的功能操作如下:

功能层创建

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

事件处理

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

按下事件:mousePressEvent

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

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

代码解析:

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

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

绘图事件:paintEvent

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

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 对象。

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


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:没有抖动;最靠近的颜色将被使用。


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


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


我是中国好公民 st,一名 C++程序猿~

发布于: 刚刚阅读数: 6
用户头像

书山有路勤为径,学海无涯苦作舟 2022.07.01 加入

擅长语言:C++ 涉及语言:Python

评论

发布
暂无评论
Qt|制作简单的不规则窗体_qt_中国好公民st_InfoQ写作社区