精华内容
下载资源
问答
  • qt自定义标题栏
    2021-12-09 16:30:04

    Qt自定义标题栏,实现拖动功能

    提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
    例如:第一章 Python 机器学习入门之pandas的使用


    提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


    前言

    Qt自定义标题栏,实现拖动功能


    一、MyTitle继承于QWidget的实现

    class Mytitile : public QWidget

    二、关键代码

    1.重载

    重载以下三个方法:

    protected:
    	void mousePressEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
    	void mouseReleaseEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
    	void mouseMoveEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
    private:
    	QPoint mouse_press_, mouse_move_;
    	bool mouse_left_pressed_;
    

    2.实现

    代码如下:

    void Mytitile ::mousePressEvent(QMouseEvent* event)
    {
    	if (event->button() == Qt::LeftButton) {
    		mouse_press_= event->globalPos();
    		mouse_left_pressed_= true;
    	}
    
    	event->ignore();//表示继续向下传递事件,其他的控件还可以去获取
    }
    
    void Mytitile ::mouseReleaseEvent(QMouseEvent* event)
    {
    
    	if (event->button() == Qt::LeftButton) {
    		mouse_left_pressed_= false;
    	}
    	event->ignore();
    }
    
    void Mytitile ::mouseMoveEvent(QMouseEvent* event)
    {
    	if (leftBtnClk) {
    		mouse_move_= event->globalPos();
    		this->window()->move(this->window()->pos() + mouse_move_ - mouse_press_); //移动window,这样就不需要在页面的类中去重载这三个函数了,所有添加了这个title的页面都可拖动。
    		mouse_press_= mouse_move_;  //每次拖动都设置好press的位置,这样下一次触发拖动才能正确
    	}
    	event->ignore();
    }
    

    3.使用

    一般在Qt的Designer模式里给页面加一个Mytitle,添加方法:拖入一个Widget,设置合理的大小以及位置,并提升成Mytitle。
    提升控件的方法,右击该控件->提升为…->输入刚刚的类名->点击添加按钮->选中刚刚的类型->点击提升按钮。
    这是提升的页面


    总结

    完事儿。

    更多相关内容
  • QT自定义标题栏最大最小化关闭按钮源码,专给入门者参考源码 QT5,VS2017,窗口背景贴图按钮贴图
  • 初学者项目需要,自己封装的一个qt自定义标题栏,可以直接调用。环境是vs2013+qt5.6.2,其他环境我也不知道能否使用,谨慎下载。 大部分标题栏的显示效果都放在paintEvent函数中,可以动态更改。大部分效果都写了...
  • Qt自定义标题栏

    千次阅读 2021-09-19 13:52:17
    Qt自定义标题栏效果图源码使用方法实现思路及部分代码参考 效果图 1.设置为无边框窗口后拉伸、移动、放大缩小等事件需要自己重新实现,我只实现标题栏拖动、双击放大/还原、窗体边缘可拉伸等基本功能,有其他需求的...

    效果图

    在这里插入图片描述

    1.设置为无边框窗口后拉伸、移动、放大缩小等事件需要自己重新实现,我只实现标题栏拖动、双击放大/还原、窗体边缘可拉伸等基本功能,有其他需求的小伙伴可参考和修改源码


    2.拉伸右、下、右下这三个方向不会抖动,拉伸其他方向均会抖动,貌似很多自定义窗口的软件都是这样,包括微软的Edge浏览器、QQ、网易云音乐等


    3.事件实现看过很多别人的方法,思路都是差不多的,但仅实现放大、缩小、移动、拉伸的话,很多人的代码都写得过于复杂,不便于我这种菜鸡阅读和理解。我的代码中拉伸实现主要参考了qt 无边框窗口,可拖动,可拉伸 这篇文章


    4.试过刘典武大佬的无抖动方案源码,一样是会抖动的,相对来说没那么抖
    Qt开源作品38-无边框窗体方案(无抖动,支持win、linux、mac等系统,侧边半屏顶部全屏)

    在这里插入图片描述

    源码

    链接: https://pan.baidu.com/s/1HtN-ciYU_-HaVTId6gjMKw
    提取码: 5dmy

    使用方法

    1. titlebar.h,titlebar.cpp,titlebar.ui 文件加入到自己的项目中
    2. 包含头文件 #include "titlebar.h"
    3. 创建标题栏对象 TitleBar title;
    4. 创建主窗口对象 QWidget w;
    5. 调用函数将主窗口添加入标题栏窗口 title.setMainWidget(&w);
    6. 调用显示函数 title.show();
    7. 2021.10.21注:如果实例化的是普通对象,则3和4顺序不可倒换,因为title.setMainWidget(&w)是title把w作为子对象,构造时应先构造title再构造w,析构时先析构w再析构title。如果顺序倒换,则先析构了title,这时再析构w就会报错。如果创建的是对象指针则实例化顺序不影响

    实现思路及部分代码

    声明

    #ifndef TITLEBAR_H
    #define TITLEBAR_H
    
    #include <QWidget>
    #include <QMouseEvent>
    #include <QPoint>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class TitleBar; }
    QT_END_NAMESPACE
    
    class TitleBar : public QWidget
    {
        Q_OBJECT
    
    public:
        TitleBar(QWidget *parent = nullptr);
        ~TitleBar();
    
        /**
         * @brief msetStyleSheet 通过文件设置全局样式
         * @param styleSheet css/qss等样式文件
         */
        static void msetStyleSheet(const QString &styleSheet);
    
        /**
         * @brief setMainWidget 设置主窗口
         * @param widget 窗口指针
         */
        void setMainWidget(QWidget *widget);
    
        /**
         * @brief setTitleBarText 设置标题
         * @param text 文本
         */
        void setTitleBarText(const QString &text);
    
        /**
         * @brief setTitleBarIcon 设置标题栏图标
         * @param icon 图标
         */
        void setTitleBarIcon(const QString &icon);
    
        /**
         * @brief setTitleBarStyleSheet 设置标题栏样式
         * @param sheet 样式
         */
        void setTitleBarStyleSheet(const QString &sheet);
    
        /**
         * @brief setTitleBarBackGround 设置标题栏背景颜色
         * @param r 红色值
         * @param g 绿色值
         * @param b 蓝色值
         */
        void setTitleBarBackGround(const int &r, const int &g, const int &b);
    
        /**
         * @brief setTitleTextFont 设置标题栏字体
         * @param font 字体样式
         */
        void setTitleTextFont(const QFont &font);
    
        /**
         * @brief setMarginSize 设置拉伸边距
         * @param size 边距值
         */
        void setMarginSize(const int &size);
    
        /**
         * @brief The MousePosition enum 鼠标区域枚举
         * 左上角(1,1)   上(1,2)   右上角(1,3)
         * 左(2,1)      中(2,2)   右(2,3)
         * 左下角(3,1)  下(3,2)   右下角(3,3)
         */
        enum MousePosition
        {
            PosLeftTop = 11,
            PosTop = 12,
            PosRightTop = 13,
            PosLeft = 21,
            PosMid = 22,
            PosRight = 23,
            PosLeftBottom = 31,
            PosBottom = 32,
            PosRightBottom = 33,
        };
    
    protected:
        bool eventFilter(QObject *watched, QEvent *event) override;
        void mousePressEvent(QMouseEvent *event) override;
        void mouseMoveEvent(QMouseEvent *event) override;
        void mouseReleaseEvent(QMouseEvent *event) override;
    
        /**
         * @brief getMouseArea 获取鼠标所在区域
         * @param pos 全局坐标
         * @return
         */
        int getMouseArea(const QPoint &pos);
    
        /**
         * @brief setMouseCursor 设置鼠标样式
         * @param pos 全局坐标
         */
        void setMouseCursor(const QPoint &pos);
    
    private:
        Ui::TitleBar *ui;
    
        QWidget *mainWidget;//主窗口指针
        QPoint dragPos;//窗口拖动位置
        bool isMoveEvent;//标题栏移动事件标志
    
        QPoint lastPos;//左键按下时停留的坐标
        bool leftBtnPress;//左键按下标志
        int mousePressArea; //鼠标点击的区域
        int marginSize;//边缘边距值
        bool isMidArea;//在非边缘区域标志
        int minWidth;//窗体(可缩小至)宽度
        int minHeight;//窗体(可缩小至)高度
    };
    #endif // TITLEBAR_H
    
    

    1. 窗体布局
    在这里插入图片描述

    以一个Widget作为整体窗口,在此基础上添加一个Widget作为标题栏,然后提供一个添加主窗口的接口函数 setMainWidget,布局属性边距、垂直策略那些啥的在ui文件里设置了

    void TitleBar::setMainWidget(QWidget *widget)
    {
        if (widget != nullptr) {
            mainWidget = widget;
            mainWidget->setParent(this);
            mainWidget->show();
            mainWidget->installEventFilter(this);
            //重新布局标题栏和窗口
            QLayout *mainLayout = this->layout();
            mainLayout->removeWidget(ui->titleWidget);
            mainLayout->addWidget(ui->titleWidget);
            mainLayout->addWidget(mainWidget);
        }
    }
    


    2. 标题栏拖动窗口及双击最大化


    用事件过滤器限定窗口整体拖动只在标题栏事件中

    窗口拖动应该不难,偏移量就是左键按下时鼠标的位置相对于整体窗口的左上角的位置

    双击放大就没啥好说了,但是会和拖动冲突,现象就是双击放大后窗口移动到了鼠标的位置,所以用isMoveEvent这个标志来解决冲突

    bool TitleBar::eventFilter(QObject *watched, QEvent *event)
    {
        //标题栏区域事件
        if (isMidArea && watched == ui->titleWidget) {
            setCursor(Qt::ArrowCursor);
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
            switch (event->type()) {
                case QEvent::MouseButtonPress:
                    dragPos = mouseEvent->globalPos() - frameGeometry().topLeft();//计算偏移量
                    isMoveEvent = true;
                    break;
                case QEvent::MouseButtonDblClick:
                    isMoveEvent = false;
                    emit ui->btnMax->clicked();
                    break;
                case QEvent::MouseMove:
                    if (isMoveEvent && !isMaximized())
                        move(mouseEvent->globalPos() - dragPos);//移动窗口
                    break;
                case QEvent::MouseButtonRelease:
                    isMoveEvent = false;
                    break;
                default:
                    break;
            }
        }
        //主窗口区域事件
        if (isMidArea && watched == mainWidget)
            setCursor(Qt::ArrowCursor);
    
        return QWidget::eventFilter(watched, event);
    }
    

    3. 光标样式及拉伸动作

    3.1. 光标样式
    在这里插入图片描述
    在这里插入图片描述

    上图把整体窗口分为了9个区域,光标在哪个区域就根据图上的划分计算(函数getMouseArea),得出区域值后便根据区域值对应的区域设置光标(函数setMouseCursor),在mouseMoveEvent中调用setMouseCursor

    区域枚举值

    /**
     * @brief The MousePosition enum 鼠标区域枚举
     * 左上角(1,1)   上(1,2)   右上角(1,3)
     * 左(2,1)      中(2,2)   右(2,3)
     * 左下角(3,1)  下(3,2)   右下角(3,3)
     */
    enum MousePosition
    {
        PosLeftTop = 11,
        PosTop = 12,
        PosRightTop = 13,
        PosLeft = 21,
        PosMid = 22,
        PosRight = 23,
        PosLeftBottom = 31,
        PosBottom = 32,
        PosRightBottom = 33,
    };
    
    int TitleBar::getMouseArea(const QPoint &pos)
    {
        int posX = pos.x();//全局x坐标
        int posY = pos.y();//全局y坐标
        int mainWidth = width();//全局宽度
        int mainHeight = height();//全局高度
        int areaX = 0;//x所在区域
        int areaY = 0;//y所在区域
    
        //判断x所在区域
        if (posX > (mainWidth - marginSize))
            areaX = 3;
        else if (posX < marginSize)
            areaX = 1;
        else
            areaX = 2;
    
        //判断y所在区域
        if (posY > (mainHeight - marginSize))
            areaY = 3;
        else if (posY < marginSize)
            areaY = 1;
        else
            areaY = 2;
    
        //返回区域值,如区域1:1 + 1*10 = 11
        return areaX + areaY*10;
    }
    
    void TitleBar::setMouseCursor(const QPoint &pos)
    {
        Qt::CursorShape cursor;
        //获取区域值
        int area = getMouseArea(pos);
        switch (area) {
            case PosLeftTop:
            case PosRightBottom:
                cursor = Qt::SizeFDiagCursor;
                break;
            case PosRightTop:
            case PosLeftBottom:
                cursor = Qt::SizeBDiagCursor;
                break;
            case PosLeft:
            case PosRight:
                cursor = Qt::SizeHorCursor;
                break;
            case PosTop:
            case PosBottom:
                cursor = Qt::SizeVerCursor;
                break;
            case PosMid:
                cursor = Qt::ArrowCursor;
                break;
            default:
                break;
        }
        setCursor(cursor);
    }
    


    3.2. 拉伸动作

    重点在重写mouseMoveEvent函数,核心在switch语句中,根据光标所在区域以及偏移量进行运算,条件判断用于防止过度拉伸,理解代码时可不看

    void TitleBar::mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::LeftButton) {
            leftBtnPress = true;//左键按下标志
            lastPos = event->globalPos();//按下时鼠标坐标
            mousePressArea = getMouseArea(event->pos());//按下时鼠标所在区域
        }
        return QWidget::mousePressEvent(event);
    }
    
    void TitleBar::mouseMoveEvent(QMouseEvent *event)
    {
        //最大化状态时不能拉伸
        if (isMaximized())
            return;
        //根据位置设置鼠标样式
        if (!leftBtnPress)
            setMouseCursor(event->pos());
    
        if (leftBtnPress && (event->buttons() & Qt::LeftButton)) {
            if (mousePressArea != PosMid)
                isMidArea = false;
            QPoint offset = event->globalPos() - lastPos;//偏移量=当前鼠标坐标-按下时鼠标坐标
            int offsetX = offset.x();
            int offsetY = offset.y();
            QRect globalGeometry = frameGeometry();//获取窗口矩形
            int globalWidth = globalGeometry.width();
            int globalHeight = globalGeometry.height();
            //拉伸后位置=当前位置+偏移量
            //加入条件判断防止过度拉伸
            switch (mousePressArea) {
                case PosLeftTop:
                    if (minWidth <= (globalWidth - offsetX))
                        globalGeometry.setLeft(globalGeometry.left() + offsetX);
                    if (minHeight <= (globalHeight - offsetY))
                        globalGeometry.setTop(globalGeometry.top() + offsetY);
                    //globalGeometry.setTopLeft(globalGeometry.topLeft() + offset);
                    break;
                case PosTop:
                    if (minHeight <= (globalHeight - offsetY))
                        globalGeometry.setTop(globalGeometry.top() + offsetY);
                    break;
                case PosRightTop:
                    if (minWidth <= (globalWidth + offsetX))
                        globalGeometry.setRight(globalGeometry.right() + offsetX);
                    if (minHeight <= (globalHeight - offsetY))
                        globalGeometry.setTop(globalGeometry.top() + offsetY);
                    //globalGeometry.setTopRight(globalGeometry.topRight() + offset);
                    break;
                case PosRight:
                    if (minWidth <= (globalWidth + offsetX))
                        globalGeometry.setRight(globalGeometry.right() + offsetX);
                    break;
                case PosRightBottom:
                    if (minWidth <= (globalWidth + offsetX))
                        globalGeometry.setRight(globalGeometry.right() + offsetX);
                    if (minHeight <= globalHeight + offsetY)
                        globalGeometry.setBottom(globalGeometry.bottom() + offsetY);
                    //globalGeometry.setBottomRight(globalGeometry.bottomRight() + offset);
                    break;
                case PosBottom:
                    if (minHeight <= (globalHeight + offsetY))
                        globalGeometry.setBottom(globalGeometry.bottom() + offsetY);
                    break;
                case PosLeftBottom:
                    if (minWidth <= (globalWidth - offsetX))
                        globalGeometry.setLeft(globalGeometry.left() + offsetX);
                    if (minHeight <= (globalHeight + offsetY))
                        globalGeometry.setBottom(globalGeometry.bottom() + offsetY);
                    //globalGeometry.setBottomLeft(globalGeometry.bottomLeft() + offset);
                    break;
                case PosLeft:
                    if (minWidth <= (globalWidth - offsetX))
                        globalGeometry.setLeft(globalGeometry.left() + offsetX);
                    break;
                default:
                    break;
            }
            //设置拉伸后坐标并记录
            setGeometry(globalGeometry);
            lastPos = event->globalPos();
        }
    
        return QWidget::mouseMoveEvent(event);
    }
    
    void TitleBar::mouseReleaseEvent(QMouseEvent *event)
    {
        leftBtnPress = false;//左键释放
        isMidArea = true;
        setCursor(Qt::ArrowCursor);
        return QWidget::mouseReleaseEvent(event);
    }
    


    4. 其他接口函数声明

    /**
     * @brief msetStyleSheet 通过文件设置全局样式
     * @param styleSheet css/qss等样式文件
     */
    static void msetStyleSheet(const QString &styleSheet);
    
    /**
     * @brief setMainWidget 设置主窗口
     * @param widget 窗口指针
     */
    void setMainWidget(QWidget *widget);
    
    /**
     * @brief setTitleBarText 设置标题
     * @param text 文本
     */
    void setTitleBarText(const QString &text);
    
    /**
     * @brief setTitleBarIcon 设置标题栏图标
     * @param icon 图标
     */
    void setTitleBarIcon(const QString &icon);
    
    /**
     * @brief setTitleBarStyleSheet 设置标题栏样式
     * @param sheet 样式
     */
    void setTitleBarStyleSheet(const QString &sheet);
    
    /**
     * @brief setTitleBarBackGround 设置标题栏背景颜色
     * @param r 红色值
     * @param g 绿色值
     * @param b 蓝色值
     */
    void setTitleBarBackGround(const int &r, const int &g, const int &b);
    
    /**
     * @brief setTitleTextFont 设置标题栏字体
     * @param font 字体样式
     */
    void setTitleTextFont(const QFont &font);
    
    /**
     * @brief setMarginSize 设置拉伸边距
     * @param size 边距值
     */
    void setMarginSize(const int &size);
    

    参考

    [1]: qt 无边框窗口,可拖动,可拉伸
    [2]: qt 无边框窗体拖动、拉伸

    展开全文
  • QT快速开发自定义标题栏示例,非常简单,使用方法如下: 1、目标窗口添加标题栏、最大化最小化关闭按钮(该步最好每次使用时,从模板程序中直接复制) 2、窗口基类从QDialog改为QFramelessDialog 3、窗口构造函数中...
  • Hello Qt——Qt自定义标题栏

    千次阅读 2022-03-01 22:42:10
    一、Qt自定义标题栏简介 QWidget及其子类窗体组件的标题栏受操作系统的控制,即标题栏的界面风格与操作系统的主题风格相同,工程实践中需要开发者自行定义,达到美化应用程序界面的目的。 二、Qt自定义标题栏实现 ...

    一、Qt自定义标题栏简介

    QWidget及其子类窗体组件的标题栏受操作系统的控制,即标题栏的界面风格与操作系统的主题风格相同,工程实践中需要开发者自行定义,达到美化应用程序界面的目的。

    二、Qt自定义标题栏实现

    1、自定义标题栏的功能

    自定义标题栏需要完成功能如下:

    (1)自定义标题栏需要包含最小化按钮、最大化按钮、关闭按钮、标题标签、图标标签等图形元素。

    (2)标题栏的拖拽。

    (3)鼠标双击标题栏实现窗体的最大化、最小化。

    2、自定义标题栏的界面布局

    自定义标题栏的界面布局如下:

     3、标题栏拖拽功能的实现

    窗体的拖拽平移过程如下图:

     当鼠标在窗体的标题栏按下并移动时,窗体会按照鼠标移动的轨迹进行平移。因此,窗体每次移动都是在当前位置按照鼠标移动的矢量进行移动。标题栏拖拽功能的实现需要实现mousePressEvent、mouseMoveEvent、mouseReleaseEvent三个事件处理函数。

    MouseEvent中的globalPos()函数返回的是相对屏幕的位置坐标,而pos()则是返回鼠标在当前控件(即捕获该鼠标事件的控件)中的位置。
    QWidget窗体的geometry().topLeft()则返回的是当前窗体的左上角在屏幕中的位置。

    startPos = event->globalPos();// 鼠标的全局初始位置,按下时记住 
    curWindowPos = geometry().topleft();// 窗体的全局位置,移动时 
    endPos = event->globalPos();// 鼠标按下发生移动之后的位置,移动时 
    move(curWindowPos+(startPos-endPos));// 根据矢量移动方向是初始位置减去末位置,移动时 
    startPos = endPos;// 将初始位置记为上次末位置,然后执行直到释放拖拽,移动时

    实现代码如下:

    void TitleBar::mousePressEvent(QMouseEvent *event)
    {
        // 鼠标左键按下事件
        if (event->button() == Qt::LeftButton)
        {
            // 记录鼠标左键状态
            m_leftButtonPressed = true;
            //记录鼠标在屏幕中的位置
            m_start = event->globalPos();
        }
    }
    
    void TitleBar::mouseMoveEvent(QMouseEvent *event)
    {
        // 持续按住才做对应事件
        if(m_leftButtonPressed)
        {
            //将父窗体移动到父窗体原来的位置加上鼠标移动的位置:event->globalPos()-m_start
            parentWidget()->move(parentWidget()->geometry().topLeft() +
                                 event->globalPos() - m_start);
    
            //将鼠标在屏幕中的位置替换为新的位置
            m_start = event->globalPos();
        }
    }
    
    void TitleBar::mouseReleaseEvent(QMouseEvent *event)
    {
        // 鼠标左键释放
        if (event->button() == Qt::LeftButton)
        {
            // 记录鼠标状态
            m_leftButtonPressed = false;
        }
    }

    4、标题栏双击实现最大化、最小化

    鼠标双击事件处理函数mouseDoubleClickEvent实现如下:

    void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
    {
        m_maximizeButton->click();
    }

    最大化、最小化、关闭按钮的槽函数如下:

    void TitleBar::onClicked()
    {
        QPushButton *pButton = qobject_cast<QPushButton *>(sender());
        QWidget *pWindow = this->window();
        if (pWindow->isTopLevel())
        {
            if (pButton == m_minimizeButton)
            {
                pWindow->showMinimized();
            }
            else if (pButton == m_maximizeButton)
            {
                pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized();
            }
            else if (pButton == m_closeButton)
            {
                pWindow->close();
            }
        }
    }

    三、Qt自定义窗体基类示例

    1、自定义窗体基类的功能

    自定义窗体基类的功能如下:

    (1)自定义标题栏。

    (2)增加内容组件,内容组件内部的界面布局完全由具体的用户决定。

    2、自定义窗体基类的实现

    TitleBar.h文件:

    #ifndef TITLEBAR_H
    #define TITLEBAR_H
    
    #include <QWidget>
    #include <QPushButton>
    #include <QLabel>
    #include <QHBoxLayout>
    #include <QEvent>
    #include <QMouseEvent>
    #include <QApplication>
    #include <QPoint>
    #include <QPixmap>
    #include <QString>
    /**
     * @brief 标题栏界面组件
     * @author 
     */
    
    class TitleBar : public QWidget
    {
        Q_OBJECT
    public:
        explicit TitleBar(QWidget *parent = NULL);
        /**
         * @brief 设置标题栏标题
         * @param title,参数,设置的标题
         */
        void setWindowTitle(const QString& title);
        /**
         * @brief 设置标题栏的图标
         * @param iconPath,参数,图标的路径
         */
        void SetTitleBarIcon(const QString& iconPath);
    
    protected:
        /**
         * @brief 鼠标双击事件处理函数
         * @param event,参数,事件
         * @note 双击标题栏进行界面的最大化/还原
         */
        virtual void mouseDoubleClickEvent(QMouseEvent *event);
    
        /**
         * @brief 鼠标按下事件处理函数
         * @param event,参数,事件
         * @note 按下鼠标左键
         */
        virtual void mousePressEvent(QMouseEvent *event);
    
        /**
         * @brief 鼠标移动事件处理函数
         * @param event,参数,事件
         * @note 移动鼠标
         */
        virtual void mouseMoveEvent(QMouseEvent *event);
    
        /**
         * @brief 鼠标释放事件处理函数
         * @param event,参数,事件
         * @note 释放鼠标
         */
        virtual void mouseReleaseEvent(QMouseEvent *event);
    
        /**
         * @brief 事件过滤处理器
         * @param obj,参数
         * @param event,参数,事件
         * @return 成功返回true,失败返回false
         * @note 设置标题、图标
         */
        virtual bool eventFilter(QObject *obj, QEvent *event);
    
        /**
         * @brief 最大化/还原
         */
        void updateMaximize();
    protected slots:
        /**
         * @brief 最小化、最大化/还原、关闭按钮点击时响应的槽函数
         */
        void onClicked();
    
    private:
        QLabel* m_iconLabel;
        QLabel* m_titleLabel;
        QPushButton* m_minimizeButton;
        QPushButton* m_maximizeButton;
        QPushButton* m_closeButton;
        QPoint m_start;//起始点
        QPoint m_end;//结束点
        bool m_leftButtonPressed;//鼠标左键按下标记
    };
    
    #endif // TITLEBAR_H

    TitleBar.cpp文件:

    #include "TitleBar.h"
    
    
    TitleBar::TitleBar(QWidget *parent) : QWidget(parent)
    {
        setFixedHeight(30);
        setWindowFlags(Qt::FramelessWindowHint);
        m_iconLabel = new QLabel(this);
        m_iconLabel->setFixedSize(20, 20);
        m_iconLabel->setScaledContents(true);
    
        m_titleLabel = new QLabel(this);
        m_titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    
        m_minimizeButton = new QPushButton(this);
        m_minimizeButton->setFixedSize(27, 22);
        m_minimizeButton->setObjectName("minimizeButton");
    
        m_maximizeButton = new QPushButton(this);
        m_maximizeButton->setFixedSize(27, 22);
        m_maximizeButton->setObjectName("maximizeButton");
    
        m_closeButton = new QPushButton(this);
        m_closeButton->setFixedSize(27, 22);
        m_closeButton->setObjectName("closeButton");
    
        QHBoxLayout* layout = new QHBoxLayout;
        layout->addWidget(m_iconLabel);
        layout->addStretch(1);
        layout->addWidget(m_titleLabel);
        layout->addStretch(1);
        layout->addWidget(m_minimizeButton);
        layout->addWidget(m_maximizeButton);
        layout->addWidget(m_closeButton);
        setLayout(layout);
    
        setProperty("titleBar", true);
        setObjectName("titleBar");
        connect(m_minimizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));
        connect(m_maximizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));
        connect(m_closeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));
    }
    
    void TitleBar::setWindowTitle(const QString &title)
    {
        m_titleLabel->setAlignment(Qt::AlignCenter);
        m_titleLabel->setText(title);
    }
    
    void TitleBar::SetTitleBarIcon(const QString &iconPath)
    {
        QPixmap map(iconPath);
        m_iconLabel->setPixmap(map);
    }
    
    void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
    {
        m_maximizeButton->click();
    }
    
    void TitleBar::mousePressEvent(QMouseEvent *event)
    {
        // 鼠标左键按下事件
        if (event->button() == Qt::LeftButton)
        {
            // 记录鼠标左键状态
            m_leftButtonPressed = true;
            //记录鼠标在屏幕中的位置
            m_start = event->globalPos();
        }
    }
    
    void TitleBar::mouseMoveEvent(QMouseEvent *event)
    {
        // 持续按住才做对应事件
        if(m_leftButtonPressed)
        {
            //将父窗体移动到父窗体原来的位置加上鼠标移动的位置:event->globalPos()-m_start
            parentWidget()->move(parentWidget()->geometry().topLeft() +
                                 event->globalPos() - m_start);
            //将鼠标在屏幕中的位置替换为新的位置
            m_start = event->globalPos();
        }
    }
    
    void TitleBar::mouseReleaseEvent(QMouseEvent *event)
    {
        // 鼠标左键释放
        if (event->button() == Qt::LeftButton)
        {
            // 记录鼠标状态
            m_leftButtonPressed = false;
        }
    }
    
    bool TitleBar::eventFilter(QObject *obj, QEvent *event)
    {
        switch(event->type())
        {
        //设置标题
        case QEvent::WindowTitleChange:
        {
            QWidget *pWidget = qobject_cast<QWidget *>(obj);
            if (pWidget)
            {
                m_titleLabel->setText(pWidget->windowTitle());
                return true;
            }
        }
    
        //设置图标
        case QEvent::WindowIconChange:
        {
            QWidget *pWidget = qobject_cast<QWidget *>(obj);
            if (pWidget)
            {
                QIcon icon = pWidget->windowIcon();
                m_iconLabel->setPixmap(icon.pixmap(m_iconLabel->size()));
                return true;
            }
        }
    
        // 窗口状态变化、窗口大小变化
        case QEvent::WindowStateChange:
        case QEvent::Resize:
            updateMaximize();
            return true;
        }
    
        return QWidget::eventFilter(obj, event);
    }
    
    void TitleBar::updateMaximize()
    {
        QWidget *pWindow = this->window();
        if (pWindow->isTopLevel())
        {
            bool bMaximize = pWindow->isMaximized();
            if (bMaximize)
            {
                m_maximizeButton->setToolTip(tr("Restore"));
                m_maximizeButton->setProperty("maximizeProperty", "restore");
            }
            else
            {
                m_maximizeButton->setProperty("maximizeProperty", "maximize");
                m_maximizeButton->setToolTip(tr("Maximize"));
            }
            m_maximizeButton->setStyle(QApplication::style());
        }
    }
    
    void TitleBar::onClicked()
    {
        QPushButton *pButton = qobject_cast<QPushButton *>(sender());
        QWidget *pWindow = this->window();
        if (pWindow->isTopLevel())
        {
            if (pButton == m_minimizeButton)
            {
                pWindow->showMinimized();
            }
            else if (pButton == m_maximizeButton)
            {
                pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized();
            }
            else if (pButton == m_closeButton)
            {
                pWindow->close();
            }
        }
    }

    QWindowBase.h文件:

    #ifndef QWINDOWBASE_H
    #define QWINDOWBASE_H
    
    #include <QFrame>
    #include <QWidget>
    #include <QVBoxLayout>
    #include "TitleBar.h"
    
    /**
     * @brief 界面组件基类
     * @note QWindowBase界面组件主要用作顶层窗口,对于非顶层窗口的界面组件使用QWidget。
     */
    class QWindowBase : public QFrame
    {
        Q_OBJECT
    public:
        QWindowBase(QFrame* parent = NULL);
        /**
         * @brief 设置标题
         * @param title,输入参数,标题内容
         */
        void setWindowTitle(const QString& title);
        /**
         * @brief 设置标题栏的图标
         * @param iconPath,输入参数,图标资源路径
         */
        void SetTitleBarIcon(const QString& iconPath);
        /**
         * @brief 获取内容组件对象指针
         * @return 返回QWidget*
         */
        QWidget* contentWidget();
        /**
         * @brief 设置标题栏高度
         * @param h,输入参数,标题栏高度
         */
        void setWindowTitleHeight(int h);
    private:
        QWidget* m_contentWidget;//内容组件
        TitleBar* m_titleBar;//标题栏
        QVBoxLayout* m_layout;//布局管理器
    };
    
    #endif // QWINDOWBASE_H

    QWindowBase.cpp文件:

    #include "QWindowBase.h"
    
    
    QWindowBase::QWindowBase(QFrame *parent): QFrame(parent)
    {
        setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
        m_titleBar = new TitleBar(this);
        m_contentWidget = new QWidget(this);
        m_contentWidget->setObjectName("Contents");
        m_layout = new QVBoxLayout;
        m_layout->addWidget(m_titleBar);
        m_layout->addWidget(m_contentWidget);
        m_layout->setSpacing(0);
        m_layout->setContentsMargins(0, 0, 0, 0);
    
        setLayout(m_layout);
    }
    
    void QWindowBase::setWindowTitle(const QString &title)
    {
        m_titleBar->setWindowTitle(title);
    }
    
    void QWindowBase::SetTitleBarIcon(const QString &iconPath)
    {
        m_titleBar->SetTitleBarIcon(iconPath);
    }
    
    QWidget *QWindowBase::contentWidget()
    {
        return m_contentWidget;
    }
    
    void QWindowBase::setWindowTitleHeight(int h)
    {
        m_titleBar->setFixedHeight(h);
    }

    CommonHelper.h文件:

    #ifndef COMMONHELPER_H
    #define COMMONHELPER_H
    
    #include <QString>
    #include <QFile>
    #include <QApplication>
    #include <QDebug>
    #include <QColor>
    #include <QPalette>
    
    /**
     * @brief 通用功能辅助类
     */
    class CommonHelper
    {
    public:
        /**
         * @brief 为应用程序设置QSS样式表
         * @param filepath,输入参数,QSS文件路径
         */
        static void setStyleSheet(const QString& filepath)
        {
            //加载样式文件
            QFile qss(filepath);
            if(qss.open(QFile::ReadOnly))
            {
                QString stylesheet = QLatin1String(qss.readAll());
                QString paletteColor = stylesheet.mid(20, 7);
                qApp->setPalette(QPalette(QColor(paletteColor)));
                qApp->setStyleSheet(stylesheet);
            }
        }
    };
    
    #endif // COMMONHELPER_H

    main.cpp文件:

    #include <QApplication>
    #include "CommonHelper.h"
    #include "QWindowBase.h"
    #include <QPushButton>
    #include <QVBoxLayout>
    #include <QHBoxLayout>
    #include <QTreeView>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QWindowBase w;
        w.setWindowTitle("WidgetBase");
        QPushButton* button1 = new QPushButton("OK");
        QHBoxLayout* hLayout1 = new QHBoxLayout;
        hLayout1->addStretch(1);
        hLayout1->addWidget(button1);
    
        QVBoxLayout* layout = new QVBoxLayout;
        QTreeView* treeView = new QTreeView;
        layout->addWidget(treeView);
        layout->addLayout(hLayout1);
        layout->addStretch(1);
        w.contentWidget()->setLayout(layout);
        w.setWindowTitleHeight(40);
        w.show();
        CommonHelper::setStyleSheet("://qss/lightblue.qss");
        return a.exec();
    }

    工程文件:

    QT       += core gui
    
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = TitleBarDemo
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which has been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    
    SOURCES += \
        main.cpp \
        TitleBar.cpp \
        QWindowBase.cpp
    
    HEADERS += \
        TitleBar.h \
        CommonHelper.h \
        QWindowBase.h
    
    RESOURCES += \
        TitileBarDemo.qrc

    工程目录结构:

     3、自定义窗体基类结果展示

    运行结果:

    展开全文
  • QT自定义标题栏

    2021-07-30 14:24:39
    1、自定义标题栏 2、QT自带标题栏 自定义标题栏类的代码 1、ui界面 2、.h #include <QWidget> #include <QEvent> #include <QDockWidget> #include <QMouseEvent> namespace Ui { class...

    效果

    1、自定义标题栏
    在这里插入图片描述
    2、QT自带标题栏
    在这里插入图片描述

    自定义标题栏类的代码

    1、ui界面
    在这里插入图片描述
    2、.h

    #include <QWidget>
    #include <QEvent>
    #include <QDockWidget>
    #include <QMouseEvent>
    
    namespace Ui {
    class mTitleBar;
    }
    
    class mTitleBar : public QWidget
    {
        //Q_OBJECT
    public:
        explicit mTitleBar(QString title,QWidget *parent = nullptr);
        ~mTitleBar();
        void mousePressEvent(QMouseEvent *event);
        void mouseMoveEvent(QMouseEvent *event);
        void mouseReleaseEvent(QMouseEvent *event);
    
    private:
        Ui::mTitleBar *ui;
        bool            mPressBool;
        QPoint          mouseStartPoint;
        QPoint          mwindowTopLeftPoint;
        QDockWidget*    mpDockMouse;
    
    };
    

    3、.cpp

    #include "mtitlebar.h"
    #include "ui_mtitlebar.h"
    #include <QDockWidget>
    #include <QWidget>
    //构造函数
    mTitleBar::mTitleBar(QString title,QWidget *parent) :
        QWidget(parent),
        ui(new Ui::mTitleBar)
    {
     	ui->setupUi(this);
        mpDockMouse = new QDockWidget(this);
        mpDockMouse->hide();
        ui->label->setText(title);
        //囗:最大化/恢复
        connect(ui->pushButton, &QPushButton::clicked, [=]
        {
            mpDockMouse = qobject_cast<QDockWidget*>(parentWidget());
            if (mpDockMouse != nullptr)
            {
                if(mpDockMouse->isMaximized())  //显示原来的大小
                {
                    mpDockMouse->showNormal();
                }
                else //最大化
                {
                    mpDockMouse->showMaximized();
                }
    
            }
        });
        //× 关闭
        connect(ui->pushButton2, &QPushButton::clicked, [=]
        {
            mpDockMouse = qobject_cast<QDockWidget*>(parentWidget());
            if (mpDockMouse != nullptr)
            {
                mpDockMouse->close();
            }
        });
        //- 最小化
        connect(ui->pushButton3, &QPushButton::clicked, [=]
        {
            mpDockMouse = qobject_cast<QDockWidget*>(parentWidget());
    //        mpDockMouse->showMinimized();
            mpDockMouse->hide();
    
    
        });
    }
    
    //鼠标事件
    void mTitleBar::mousePressEvent(QMouseEvent *event)
    {
    
        if(event->button() == Qt::LeftButton)
        {
            mPressBool = true;
            //获得鼠标的初始位置
            mouseStartPoint = event->globalPos();
            //获得窗口的初始位置
            mpDockMouse = qobject_cast<QDockWidget*>(parentWidget());
            mwindowTopLeftPoint = mpDockMouse->frameGeometry().topLeft();
    
        }
    }
    
    void mTitleBar::mouseMoveEvent(QMouseEvent *event)
    {
        if(mPressBool)
        {
            //获得鼠标移动的距离
            QPoint distance = event->globalPos() - mouseStartPoint;
            //改变窗口的位置
            mpDockMouse = qobject_cast<QDockWidget*>(parentWidget());
            mpDockMouse->move(mwindowTopLeftPoint + distance);
        }
    }
    
    void mTitleBar::mouseReleaseEvent(QMouseEvent *event)
    {
        if(event->button() == Qt::LeftButton)
        {
            mPressBool = false;
        }
    }
    

    类设置自定义标题栏

    this->setTitleBarWidget(new mTitleBar("Cap",this));
    

    百度网盘链接

    提取码:wzds
    自定义标题栏

    展开全文
  • qt自定义标题栏,可任意改变标题栏的各种颜色大小字体位置等样式
  • Qt 自定义标题栏

    2019-01-23 15:52:17
    QWidget及其子类窗体组件的标题栏受操作系统的控制,即标题栏的界面风格与操作系统的主题风格相同,工程实践中需要开发者自行定义,达到美化应用程序界面的目的。开发环境是Qt5.7,调试成功,可自行下载,如有问题请...
  • Qt自定义标题栏
  • 本源代码是用Qt5.9的Creator编译和构建,主要功能是实现自定义标题栏,而屏蔽系统自带的标题栏。具体的讲解和用法可以参考我的博客:https://blog.csdn.net/naibozhuan3744/article/details/81120544
  • Qt 实现 自定义窗口标题栏

    千次下载 热门讨论 2016-12-07 17:06:46
    以上代码用Qt实现了自定义窗口标题栏,非常实用,提供了窗口图标、窗口标题、最小化、最大化、关闭按钮等几个部分。可以应用到每一个窗口中去,保持每个窗口外观的一致性,同时自定义标题栏也比系统自带的漂亮很多...
  • 设置自定义标题栏需要修改鼠标移动事件,这样窗口才能移动。哪个窗口不能移动,就再这个窗口的类中添加下列代码。 有一点点的bug,窗口会突然移动,后续修改。 代码 .h文件 void mousePressEvent(QMouseEvent *...
  • Qt自定义标题栏用法

    2019-09-27 14:38:38
    其中,自定义标题栏主要原理是,屏蔽原来的标题栏,然后用QVBoxLayout垂直布局管理器,加载一个标题栏QWidget。其中,这个标题栏QWidget里面自定义标题栏的功能按钮,比如图标、图标内容、最大化按钮(QWidget::...
  • 自定义标题栏源码,实现了 1.鼠标左键点击移动 2.最小化 最大化/恢复 关闭程序功能 3.双击鼠标最大化/恢复功能 ************************************************************************************************...
  • 我之前写了自定义标题栏已经实现可移动,可伸缩窗口了,但是往窗口里面添加控件在窗口边缘时重叠时没有改变光标,导致不能伸缩窗口,现在我终于解决了这个问题! gitee地址:...
  • 众所周知,一个最简单的窗口也是有标题栏的 Widnows默认提供的标题栏上有: ​ 图标-窗口标题-Min-Max-Close按钮 但是,这未免太过局限 高自由度的自定义是极客(Geek)精神不可或缺的一部分 如果你想在标题栏上增加/...
  • 关于Qt自定义标题栏

    2021-08-07 00:15:33
    这种就是需要自定义标题栏。 最近项目用到了自定义标题栏 自定义标题栏分为几个步骤: 1.隐藏QT自身的标题栏 2.用一个QWidget充当标题栏,在QWidget里面放置你想要的功能控件 3.在QWidget的基础上加入最基本的控件:...
  • 参考链接: 搬运官方参考例子 ...Qt 使用windows api实现自定义标题栏无边框窗口,给出了去边框导致的最大化后像素偏移的解决方案 VC++实现阴影窗口,通过创建子窗口来实现阴影,设置跟随父窗口,有参考价值 ...
  • .h protected: //标题栏的拖拽 void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event);...//标题栏的拖拽,鼠标不在标题栏范围内无效 void mousePressEvent(QMouseEvent *event) {
  • qt自定义窗口标题栏,能移动和缩放,简易文本编辑器,可以把文本信息存储在图片中 。
  • Qt高级——Qt自定义标题栏

    千次阅读 2020-11-20 16:27:21
    一、Qt自定义标题栏简介 QWidget及其子类窗体组件的标题栏受操作系统的控制,即标题栏的界面风格与操作系统的主题风格相同,工程实践中需要开发者自行定义,达到美化应用程序界面的目的。 二、Qt自定义标题栏实现 ...
  • // 隐藏标题栏 setWindowFlags(Qt::FramelessWindowHint); 头文件 void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); //头...
  • Qt自定义标题栏并实现拖拽

    千次阅读 2017-09-25 22:54:54
    Qt自定义标题栏并实现拖拽  很多时候,Qt自带的窗体边框不能满足我们的需求,或者我们觉得由于系统的主题影响导致界面太丑了,我们需要自行定义一个好看并和普通标题栏功能相同的控件去替代,以达到美化我们的程序...
  • QT自定义窗口 自由拖动 自定义标题

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,056
精华内容 1,622
关键字:

qt自定义标题栏

友情链接: input__einimum.rar