C++
自定义QT程序标题栏
  • By刘立博
  • 2021-02-13 23:46:49
  • 1461人已阅读

制作标题栏样式

首先,根据设计实现具体的窗体样式,假定我们需要实现一个带LOGO、最小化、最大化、关闭按钮的标题栏。

 

层级关系

header中包含左侧和右侧两个QWidget容器,左侧容器包含logo和logo描述;右侧容器包含窗体最小化、窗体最大化、关闭窗体3个元素。

样式

为header设置背景色,为最小化、最大化、关闭元素设置背景图片

#header
{
background-color: rgb(60, 60, 60);
}

#header_min_btn
{
	background-image: url(:/camv1/img/min.png);
}
#header_max_btn
{
	background-image: url(:/camv1/img/max.png);
}
#header_close_btn
{
	background-image: url(:/camv1/img/close.png);
}

隐藏系统默认菜单栏

虽然我们实现了自定义标题栏,但windows默认的标题栏仍然存在,我们可以使用setWindowFlags函数将窗体标记为FramelessWindowHint,实现无边框以达到隐藏windows默认标题栏的目的。

camv1::camv1(QWidget *parent): QWidget(parent)
{
    ui.setupUi(this);
    setWindowFlags(Qt::FramelessWindowHint);
}

预览

标题栏样式已开发完毕,编译项目预览实际效果如下:

窗体最小化、最大化、恢复、关闭

 

窗体的样式设计已经完成,但窗体的最小化、最大化、恢复、关闭按钮并没有响应点击,所以我们需要将相关事件绑定至按钮,以便响应最小化、最大化、恢复、关闭事件。

 

绑定信号槽函数:

最小化按钮发送信号:showMinimized()

关闭按钮发送信号:close()

自定义槽函数:

最大化窗体:windows2Max();

恢复窗体:windows2Normal();

 

绑定信号槽函数

最大化按钮发送信号:windows2Max()

恢复按钮发送信号:windows2Normal()

槽函数流程设计

 

点击最大化按钮后,隐藏最大化按钮,显示恢复按钮,发送默认最大化信号

点击恢复按钮后,隐藏恢复按钮,显示最大化按钮,发送默认恢复信号

void camv1::windows2Max()
{
    ui.header_max_btn->setVisible(false);
    ui.header_normal_btn->setVisible(true);
    showMaximized();
}

void camv1::windows2Normal()
{
    ui.header_max_btn->setVisible(true);
    ui.header_normal_btn->setVisible(false);
    showNormal();
}

 

窗体拖动

窗体已经实现了最小化、最大化、关闭。可以并不能用鼠标拖动,所以我们需要重写3个事件实现窗体拖动:

 

程序流程

mousePressEvent:鼠标按下触发该事件,判断是否为左键点击,如果为左键点击,则将标志位修改为true,并记录点击的相对位置

mouseMoveEvent:鼠标移动触发该事件,判断标志位,如果为true,则修改窗体位置

mouseReleaseEvent:鼠标释放触发该事件,将标志位修改为false

程序代码

 

头文件

#pragma once

#include <QtWidgets/QWidget>
#include "ui_camv1.h"
#include <QMouseEvent>

class camv1 : public QWidget
{
    Q_OBJECT

public:
    camv1(QWidget *parent = Q_NULLPTR);

    //重写鼠标事件,用于拖动窗体
    void mouseMoveEvent(QMouseEvent* ev) override;
    void mousePressEvent(QMouseEvent* ev) override;
    void mouseReleaseEvent(QMouseEvent* ev) override;

private:
    Ui::camv1Class ui;
    //是否为左键
    bool mouseIsPress = false;
    //鼠标相对位置
    QPoint mousePosition;
};

源文件如下:

#include "camv1.h"

camv1::camv1(QWidget *parent): QWidget(parent)
{
    ui.setupUi(this);
    setWindowFlags(Qt::FramelessWindowHint);
}


void camv1::mouseMoveEvent(QMouseEvent* ev)
{
    if (!this->mouseIsPress)
    {
        QWidget::mouseMoveEvent(ev);
        return;
    }
    this->move(ev->globalPos() - mousePosition);
}
void camv1::mousePressEvent(QMouseEvent* ev)
{
    if (ev->button() == Qt::LeftButton)
    {
        this->mouseIsPress = true;
        this->mousePosition = ev->pos();
    }
    
}
void camv1::mouseReleaseEvent(QMouseEvent* ev)
{
    if (ev->button() == Qt::LeftButton)
    {
        this->mouseIsPress = false;
    }
   
}

测试

 

最小化、最大化、关闭按钮可以正常使用,点击窗体可以拖动。