@[TOC]
一.前言
今天我们来实现自定义标题栏的实现,这里面用到了布局,鼠标事件重写等知识点,首先还是自定义标题栏的创作,像下面这样,可放大,可缩小,并且随着窗体大小的改变,控件做自适应调整。有没有感觉狗子的界面做的越来越好看,哈哈,其实只是想告诉大家,孰能生巧,第一次可能很丑,慢慢来嘛,我第一次也被人喷过。废话不多说,看实现。
二.实现
首先还是先把界面搭建出来,如上图,我知道有很多不会搭建这个布局,确实,我刚学习的时候,书中关于布局也是草草略过,我之前写过一个布局的介绍,大家可以看一下,qt 如何设计好布局和漂亮的界面,当然,你看了其中有关布局的知识,相信我,你依旧还是不能随心所欲的布成自己想要的局。你去百度,关于布局的知识,其实和我上面写的一样,其实这里面还隐藏一些配合,只不过可能这个知识点对于会布局的人来说太简单了,他们会选择性略过。
比如下面几个我能想到的问题:
- 对顶级窗口进行布局,布局和窗体有一定距离;
解决方法:选中顶级窗体,属性里面找到布局,将红括号内的值改为0,布局和窗体的距离就为0.
![]()
- 拖了一个布局,并且将相关控件加入布局,但是一旦将顶级窗口添加布局,控件大小就会不可控;
解决方法:之所以如此,是因为我们没有指定控件最大值和最小值,这也是为什么大家看到的软件,有一些控件最大化后跟随界面变大,而一些控件是不变化的,就比如最小化,最大化控件等等。大家只需要选中控件,右键选中选中大小限定,就会得到我们想要的大小。
![]()
- 界面放大或者缩小后,控件位置问题;
解决方法:要运用弹簧(horizontalSpacer)这个功能,并灵活运用sizetype这个属性,例如Minimum(最小大小),Maximum(最大大小),Expanding(自适应)等等,比如我们选择了Maximum,界面放大时,我们就不用这个弹簧放大。
![]()
然后布局就写到这里,涉及的有关控件背景图可加我qq2506897252获取,无偿的。
下面说一下功能的实现,有细心读者可能发现上面的动态图有两个标题栏,这不是骗人嘛,我想说不是骗人,到最后白色的标题栏我们是要隐藏的,为了文章的前后顺序,我们暂时先把他留下。
先将最小化,最大化以及关闭按钮的功能进行实现,这里可以选择代码实现,也可以在ui界面实现,只不过ui界面实现有一些局限性,由于我们目的是使用自定义标题栏,所以这里直接在ui界面进行实现。
进行信号和槽绑定后,我们现在就可以使用自定义的标题栏来实现最小化,最大化,关闭,接下来就是将系统的标签栏进行隐藏,如果在这之前,就将系统的标题栏隐藏,那么对于编译后生成的软件关闭将是不方便的。
在主窗体的构造函数加入this->setWindowFlags(Qt::FramelessWindowHint);
,编译运行即可隐藏系统标签栏。
隐藏后,会发现无法我们无法移动窗口了,想要移动窗口,我们需要进行鼠标事件重写,包括mousePressEvent(QMouseEvent *event)
,mouseMoveEvent(QMouseEvent *event)
,mouseReleaseEvent(QMouseEvent *event)
。
首先在mainwindow.h中声明这三个函数:
void mousePressEvent(QMouseEvent *event);//鼠标点击
void mouseMoveEvent(QMouseEvent *event);//鼠标移动
void mouseReleaseEvent(QMouseEvent *event);//鼠标释放
//添加类成员m_point(QPoint类型)
QPoint m_point;
mianwindow.cpp中进行定义:
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
m_point = event->globalPos()-frameGeometry().topLeft();
//鼠标位置减去左上角的左边
//可替换为m_point = event->pos();
}
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
move(event->globalPos() - m_point);
//鼠标位置减去按下点的坐标
//可替换为event->pos() - m_point + pos();
}
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
//Q_UNUSED() 没有实质性的作用,用来避免编译器警告
}
对应的m_point = event->globalPos()-frameGeometry().topLeft();可替换为m_point = event->pos();
别忘了加入头文件`#include
include`
完成上述代码,编译运行,窗口可通过鼠标移动。