qt2-无边框窗口创建、拖拽、阴影

时间:2024-03-26 18:39:35

创建 widget 工程

注意这里选择 QWidget 基类即可。
qt2-无边框窗口创建、拖拽、阴影
qt2-无边框窗口创建、拖拽、阴影

  1. 类名:Widget
  2. 基类:QWidget
  3. 头文件:widget.h
  4. 源文件:widget.h
  5. 创建界面
  6. 界面文件:widget.ui
  7. pro文件:firstLessonReview
  8. 主函数:main.cpp

main.cpp

qt2-无边框窗口创建、拖拽、阴影

  1. 第 6 行创建一个 QApplication 的对象,用于管理应用程序,接收两个命令行参数。
  2. 第 7 行创建一个 Widget 的对象,该对象实际运行时弹出来的部件窗口
  3. 第 8 行让该 widget 对象显示,因为qt 默认新建的可视化部件都是不显示的
  4. 第 10 行,让 QApplication 对象跑起来,进入事件轮询,这样在发生事件的时候可以进行响应

设置无边框窗口

  1. 运行程序,观察运行结果如下

qt2-无边框窗口创建、拖拽、阴影
2. 进入widget.cpp文件,添加this->setWindowFlags(Qt::FramelessWindowHint);
qt2-无边框窗口创建、拖拽、阴影
2.1 在 setWindowFlags上右键选择 Follow symbol under cursor
qt2-无边框窗口创建、拖拽、阴影
2.2 观察到:该函数只有一个参数,在 Qt::WindowFlags 继续右键 follow
qt2-无边框窗口创建、拖拽、阴影
qt2-无边框窗口创建、拖拽、阴影
2.3 随后,继续follow WindowType
qt2-无边框窗口创建、拖拽、阴影
2.4 观察到, WindowType 是一个 enum 变量,从中选择FramelessWindowHint,写入 setWindowFlags()函数中
qt2-无边框窗口创建、拖拽、阴影
3. 运行程序,结果如下
qt2-无边框窗口创建、拖拽、阴影

窗口的拖拽

通常情况下,对于一个程序的拖拽,我们都是左键按住窗口的上边栏进行拖拽,在这里,我们实现在窗口任意位置按住左键拖拽的功能。

  1. 数学关系 y = x+z
    qt2-无边框窗口创建、拖拽、阴影
    白色背景作为桌面,黑色方框作为程序窗口,箭头是鼠标左键按下的位置,y 是桌面左上角对于鼠标左键的位置,x是窗口左上角对于桌面左上角的位置,z 是鼠标左键对于窗口左上角的位置,存在向量关系 y = x + z或者是直角坐标系中,y的坐标也是x的坐标与z的坐标之和。
  2. 鼠标的动作为 按下(press)、移动(即拖拽 move)释放(release),对于qt而言,这些都是事件(event),且是在widget下的事件,在帮助菜单的索引中搜索 mousepress
    qt2-无边框窗口创建、拖拽、阴影
    2.1 双击mousePressEvent,在弹出的窗口中选择 QWidget Class | Qt Widgets 5.12
    qt2-无边框窗口创建、拖拽、阴影
    qt2-无边框窗口创建、拖拽、阴影
    2.2 上拉至顶部,观察到这是 QWidget Class,打开其中的Protected Functions,在其中找到我们需要的函数
    qt2-无边框窗口创建、拖拽、阴影
    qt2-无边框窗口创建、拖拽、阴影
    2.3 复制它们到 widget.h 中,进行函数声明,并在widget.cpp中具体实现
    qt2-无边框窗口创建、拖拽、阴影
    qt2-无边框窗口创建、拖拽、阴影
    2.4 由于要对点进行操作,故在widget.h中包含头文件 QPoint,同时又因为对鼠标进行事件操作(mouse event),故在 widget.h中包含QMouseEvent
    2.4.1 y 的位置获取
    y 是 鼠标按下事件发生时的点相对于桌面(global)的位置(pos)。故应该是 mouseEvent的位置
    QPoint y = event->globalPos();
    2.4.2 x 的位置获取
    x 是整个widget窗口(this)相对于桌面(global)的位置
    QPoint x = this->geometry().topLeft();
    2.4.3 z 的位置
    应用 y = x + z; QPoint z = y -x;
    qt2-无边框窗口创建、拖拽、阴影
    2.5 当获取到x,y,z 的位置后,进行移动窗口(move geometry)
    在移动窗口时候,y是个变值,x是个变直,z是个定值(在mousePressEvent中获取得到,需要在 mouseMoveEvent中使用,故改变 z 为类的私有变量
    2.5.1 在 widget.h z 中定义私有变量 z
    qt2-无边框窗口创建、拖拽、阴影
    2.5.2 在 widget.cpp 中使用私有z
    qt2-无边框窗口创建、拖拽、阴影
    2.5.3 在 mouseMoveEvent函数中实现 x,y,z
    y 的值时变值,需要时刻读取,z 是固定值,x是变值 ,x = y - z;
    qt2-无边框窗口创建、拖拽、阴影
    2.5.4 移动窗口
    移动(move)的是窗口(即部件widget),且移动的位置可以由x决定,即 窗口的移动跟随鼠标的移动(随动系统,x鼠标移动是输入,y窗口移动是输出,符合逻辑,反过来不成立)
    this->move(x);
    qt2-无边框窗口创建、拖拽、阴影
    2.6 鼠标释放
    直接将 z 的值清空即可,调用 QPoint 即可
    qt2-无边框窗口创建、拖拽、阴影
    2.7 运行程序,按下鼠标左键移动窗口

窗口移动总结反思

  1. 窗口的移动,应当是跟随着鼠标的移动而移动,逻辑顺序不能反。
  2. 对于 z,是一个固定值,只需要在最开始的时候确定下来,可以认为是一个const变量,故可作为私有成员;但是 y 不可以作为私有成员。该变量如果作为私有成员在press的时候固定下来,那么在move中,就无法改变该值,并且y应当是move中,每移动一次就需要改变的量。
  3. 最重要的是,y 是鼠标左键对于桌面左上角的位置值,它的变动,引起窗口的变动。

阴影效果

  1. 在 ui界面中拖入一个新的widget,命名为 shadowWidget(两个箭头处任意改变其中一个即可)
    qt2-无边框窗口创建、拖拽、阴影qt2-无边框窗口创建、拖拽、阴影
  2. 将shadowWidget 改变为其他颜色,便于区分
    qt2-无边框窗口创建、拖拽、阴影
    qt2-无边框窗口创建、拖拽、阴影
    qt2-无边框窗口创建、拖拽、阴影
    qt2-无边框窗口创建、拖拽、阴影
    qt2-无边框窗口创建、拖拽、阴影
  3. 对图片添加阴影效果(graphics drop shadow)
    在帮助文档搜索dropshadow,双击进入第一箭头处,发现不是我们要找的,进入第二个箭头处qt2-无边框窗口创建、拖拽、阴影
    qt2-无边框窗口创建、拖拽、阴影
    3.1 点击箭头指向的 more...
    qt2-无边框窗口创建、拖拽、阴影
    3.2 根据解释,我们找到需要的三个函数
    qt2-无边框窗口创建、拖拽、阴影
  4. 在 widget.cpp 中添加头文件 #include <QGraphicsDropShadowEffect>
  5. 创建指针对象,分配空间
    qt2-无边框窗口创建、拖拽、阴影
  6. 调用刚刚获得的三个函数
    qt2-无边框窗口创建、拖拽、阴影
  7. 设置shadowWidget的阴影效果
    7.1 在最开始创建界面的时候,在widget.h中,就同时生成了一个 Ui::Widget *ui;的指针,我们可以直接利用
    qt2-无边框窗口创建、拖拽、阴影
    7.2 在 widget.cpp中设置阴影
    qt2-无边框窗口创建、拖拽、阴影
  8. 运行,查看效果

qt2-无边框窗口创建、拖拽、阴影
9. 利用设置 widget 的属性,可以隐藏主 widget
qt2-无边框窗口创建、拖拽、阴影
qt2-无边框窗口创建、拖拽、阴影

关于ui的一点思考

  1. ui也是一个对象,只是这个对象是可视化的
  2. 在ui上进行可视化操作,利用纯程序代码应该也可以完成这个操作。
  3. 在ui上进行的可视化操作,本质上应该还是 对象的实例化,对象的函数调用等